diff --git a/server/src/app/services/orchestrator.py b/server/src/app/services/orchestrator.py index f3a0205..54a6b94 100644 --- a/server/src/app/services/orchestrator.py +++ b/server/src/app/services/orchestrator.py @@ -657,8 +657,8 @@ class OrchestratorService: if ontology.scenario == "expense": tool_type = AgentToolType.DATABASE.value - tool_name = "database.expense_claims.upsert_draft" - executor = lambda: self.expense_claim_service.upsert_draft_from_ontology( + tool_name = "database.expense_claims.save_or_submit" + executor = lambda: self.expense_claim_service.save_or_submit_from_ontology( run_id=run_id, user_id=payload.user_id, message=payload.message or "", diff --git a/server/tests/test_orchestrator_service.py b/server/tests/test_orchestrator_service.py index b187a4a..39e8105 100644 --- a/server/tests/test_orchestrator_service.py +++ b/server/tests/test_orchestrator_service.py @@ -629,6 +629,65 @@ def test_orchestrator_user_agent_draft_returns_structured_payload() -> None: assert claim.items +def test_orchestrator_expense_next_step_submits_claim_to_approval() -> None: + client, session_factory = build_client() + user_id = "zhangsan@example.com" + + with session_factory() as db: + db.add( + Employee( + employee_no="E3001", + name="张三", + email=user_id, + ) + ) + db.commit() + + response = client.post( + "/api/v1/orchestrator/run", + json={ + "source": "user_message", + "user_id": user_id, + "message": "帮我报销昨天去上海出差的交通费680元", + "context_json": { + "role_codes": ["employee"], + "name": "张三", + "department_name": "销售部", + "attachment_names": ["didi-trip.png"], + "attachment_count": 1, + "review_action": "next_step", + "review_form_values": { + "reporter_name": "张三", + "expense_type": "交通费", + "amount": "680", + "occurred_date": "2026-05-13", + "location": "上海", + "reason": "上海客户拜访交通" + }, + }, + }, + ) + + assert response.status_code == 200 + payload = response.json() + assert payload["status"] == "succeeded" + assert payload["result"]["draft_payload"]["claim_no"].startswith("EXP-") + assert payload["result"]["draft_payload"]["status"] == "submitted" + assert payload["result"]["draft_payload"]["approval_stage"] == "AI验审" + assert "已提交审批" in payload["result"]["answer"] + + with session_factory() as db: + claim = db.scalar( + select(ExpenseClaim).where( + ExpenseClaim.id == payload["result"]["draft_payload"]["claim_id"] + ) + ) + assert claim is not None + assert claim.status == "submitted" + assert claim.approval_stage == "AI验审" + assert claim.submitted_at is not None + + def test_orchestrator_blocks_fourth_expense_draft_for_same_user() -> None: client, session_factory = build_client() user_id = "zhangsan@example.com"