feat: 新增预算后端服务与差旅风险规则库
后端新增预算模型、端点和服务模块,支持预算 CRUD 和余额 查询,清理旧生成规则文件并替换为按严重等级分类的差旅风 险规则库,优化认证权限和报销单访问策略,新增财务规则目 录和演示数据构建脚本,前端预算中心增加对话框交互,完善 审计页面运行时模型和元数据展示,补充单元测试。
This commit is contained in:
@@ -32,6 +32,7 @@ from app.schemas.agent_asset import (
|
||||
AgentAssetVersionCreate,
|
||||
)
|
||||
from app.schemas.reimbursement import TravelReimbursementCalculatorRequest
|
||||
from app.services import agent_foundation as agent_foundation_module
|
||||
from app.services.agent_asset_spreadsheet import (
|
||||
COMPANY_COMMUNICATION_EXPENSE_RULE_CODE,
|
||||
COMPANY_COMMUNICATION_EXPENSE_RULE_FILENAME,
|
||||
@@ -43,6 +44,9 @@ from app.services.agent_assets import AgentAssetService
|
||||
from app.services.agent_runs import AgentRunService
|
||||
from app.services.audit import AuditLogService
|
||||
from app.services.expense_rule_runtime import ExpenseRuleRuntimeService
|
||||
from app.services.finance_rule_catalog import (
|
||||
DEPRECATED_FINANCE_RULE_CODES,
|
||||
)
|
||||
from app.services.settings import OnlyOfficeRuntimeConfig
|
||||
from app.services.travel_reimbursement_calculator import TravelReimbursementCalculatorService
|
||||
|
||||
@@ -80,6 +84,7 @@ def isolate_rule_file_storage(tmp_path, monkeypatch) -> None:
|
||||
|
||||
|
||||
def build_session() -> Session:
|
||||
agent_foundation_module._foundation_ready_keys.clear()
|
||||
engine = create_engine(
|
||||
"sqlite+pysqlite:///:memory:",
|
||||
connect_args={"check_same_thread": False},
|
||||
@@ -163,12 +168,59 @@ def test_finance_rules_use_risk_rule_scenario_categories() -> None:
|
||||
travel_config = travel_rule.config_json or {}
|
||||
communication_config = communication_rule.config_json or {}
|
||||
|
||||
assert travel_rule.scenario_json == ["差旅"]
|
||||
assert travel_config["scenario_category"] == "差旅"
|
||||
assert travel_config["ai_review_category"] == "差旅"
|
||||
assert communication_rule.scenario_json == ["费用科目"]
|
||||
assert communication_config["scenario_category"] == "费用科目"
|
||||
assert communication_config["ai_review_category"] == "费用科目"
|
||||
assert travel_rule.scenario_json == ["差旅费"]
|
||||
assert travel_config["scenario_category"] == "差旅费"
|
||||
assert travel_config["ai_review_category"] == "差旅费"
|
||||
assert communication_rule.scenario_json == ["通信费"]
|
||||
assert communication_config["scenario_category"] == "通信费"
|
||||
assert communication_config["ai_review_category"] == "通信费"
|
||||
|
||||
|
||||
def test_non_standard_finance_rule_spreadsheets_are_not_seeded() -> None:
|
||||
with build_session() as db:
|
||||
service = AgentAssetService(db)
|
||||
service.list_assets(asset_type=AgentAssetType.RULE.value)
|
||||
|
||||
for code in DEPRECATED_FINANCE_RULE_CODES:
|
||||
asset = db.scalar(select(AgentAsset).where(AgentAsset.code == code))
|
||||
assert asset is None or asset.config_json["tag"] == "废弃规则"
|
||||
|
||||
|
||||
def test_demo_budget_risk_rules_sync_with_finance_rule_references() -> None:
|
||||
with build_session() as db:
|
||||
service = AgentAssetService(db)
|
||||
service.list_assets(asset_type=AgentAssetType.RULE.value)
|
||||
|
||||
budget_rule = db.scalar(
|
||||
select(AgentAsset).where(
|
||||
AgentAsset.code == "risk.budget.available_balance_insufficient"
|
||||
)
|
||||
)
|
||||
marketing_rule = db.scalar(
|
||||
select(AgentAsset).where(
|
||||
AgentAsset.code == "risk.application.marketing_without_campaign"
|
||||
)
|
||||
)
|
||||
|
||||
assert budget_rule is not None
|
||||
assert "差旅费" in budget_rule.scenario_json
|
||||
assert "市场推广费" in budget_rule.scenario_json
|
||||
assert "软件服务费" in budget_rule.scenario_json
|
||||
assert budget_rule.config_json["budget_required"] is True
|
||||
assert "marketing" in budget_rule.config_json["expense_types"]
|
||||
assert budget_rule.config_json["business_stage"] == [
|
||||
"expense_application",
|
||||
"reimbursement",
|
||||
"budget_execution",
|
||||
]
|
||||
assert budget_rule.config_json["finance_rule_code"] == "budget.execution.policy"
|
||||
|
||||
assert marketing_rule is not None
|
||||
assert marketing_rule.scenario_json == ["市场推广费"]
|
||||
assert marketing_rule.config_json["finance_rule_code"] == "expense.application.policy"
|
||||
assert marketing_rule.config_json["finance_rule_sheet"] == "费用申请前置规则"
|
||||
assert marketing_rule.config_json["expense_types"] == ["marketing"]
|
||||
assert marketing_rule.config_json["budget_required"] is True
|
||||
|
||||
|
||||
def test_agent_asset_service_can_activate_rule_after_review() -> None:
|
||||
|
||||
Reference in New Issue
Block a user