from __future__ import annotations import json from app.services.expense_rule_runtime_defaults import ( DEFAULT_SCENE_MATRIX_CONFIG, DEFAULT_TRAVEL_POLICY_CONFIG, SCENE_LABELS, ) from app.services.expense_rule_runtime_models import ( SceneMatrixRuleConfig, resolve_document_type_label, ) def build_scene_submission_standard_markdown() -> str: scene_matrix = SceneMatrixRuleConfig.model_validate(DEFAULT_SCENE_MATRIX_CONFIG) sections: list[str] = [ "# 报销场景提交与附件标准", "", "## 模板信息", "", "- 模板类型:系统内置场景矩阵规则", "- 运行时类型:`scene_matrix`", "- 适用对象:报销提交与附件校验", "", "## 目标", "", "统一约束各报销场景的必填字段、附件类型和金额预警口径,在上传附件和提交审核两个时点直接输出可执行风险判断。", "", "## 适用范围", "", "适用于差旅、住宿、交通、餐费、业务招待、办公、会务、培训、通讯、福利和其他费用场景。", "", "## 输入字段", "", "- expense_type", "- attachments", "- location", "- amount / item_amount", "- reason", "", "## 判断规则", "", ] for index, (expense_type, config) in enumerate(scene_matrix.scenes.items(), start=1): expected_document_labels = "、".join( resolve_document_type_label(item) for item in config.allowed_document_types ) expected_scene_labels = "、".join( SCENE_LABELS.get(item, item) for item in config.allowed_scene_codes ) sections.extend( [ f"### 规则 {index} {config.label}(`{expense_type}`)", "", f"- 业务地点:{'必填' if config.location_required else '非必填'}", f"- 最少附件数:{config.min_attachment_count}", f"- 允许识别场景:{expected_scene_labels or '不限制'}", f"- 允许附件类型:{expected_document_labels or '不限制'}", f"- 附件不匹配处理:{config.attachment_mismatch_severity.upper()}", ] ) if config.claim_amount_limit is not None: sections.append( f"- 合计金额阈值:预警 {config.claim_amount_limit.warn_amount or '-'} 元," f"拦截 {config.claim_amount_limit.block_amount or '-'} 元" ) if config.item_amount_limit is not None: sections.append( f"- 单笔金额阈值:预警 {config.item_amount_limit.warn_amount or '-'} 元," f"拦截 {config.item_amount_limit.block_amount or '-'} 元" ) if config.always_warn and config.always_warn_message: sections.append(f"- 特殊处理:{config.always_warn_message}") sections.append("") sections.extend( [ "## 输出", "", "- 命中高风险时退回待补充。", "- 命中中风险时继续流转,并提示审批人重点复核。", "- 命中 always_warn 场景时追加人工重点复核提示。", "", "## 来源依据", "", "- 公司报销制度中关于场景识别、附件要求、金额阈值和人工复核的统一口径。", "", "## 审核约束", "", "- 当前规则为系统内置真实运行规则,变更后需重新审核并评估回滚影响。", "- 规则 JSON 与 Markdown 说明必须保持一致。", "", "## 管理员备注", "", "如后续制度调整附件类型、金额阈值或人工复核口径,应优先修改运行时 JSON 并同步更新说明。", "", "```expense-rule", json.dumps(DEFAULT_SCENE_MATRIX_CONFIG, ensure_ascii=False, indent=2), "```", ] ) return "\n".join(sections) def build_travel_risk_control_standard_markdown() -> str: return "\n".join( [ "# 差旅报销风险管控制度", "", "## 模板信息", "", "- 模板键:`travel_standard_v1`", "- 运行时类型:`travel_policy`", "- 适用对象:差旅、住宿、交通相关报销审核", "", "## 目标", "", "校验差旅行程闭环、酒店地点一致性、住宿标准、飞机舱位和火车席别是否符合制度,并对例外情况保留人工复核入口。", "", "## 适用范围", "", "适用于差旅费、住宿费和交通费相关报销单,重点覆盖跨城市出差、改签、中转和超标说明场景。", "", "## 输入字段", "", "- expense_type", "- attachments / OCR routes", "- location", "- employee_grade", "- reason", "", "## 判断规则", "", "- 两段及以上长途交通票据必须首尾衔接。", "- 最终终点应与申报目的地一致,或返回首段出发城市。", "- 检测到多城市行程但无说明时,按高风险退回待补充。", "- 酒店城市必须落在目的地或交通链路停留城市中。", "- 住宿标准、飞机舱位和火车席别按职级与城市分级执行。", "- 超标但有说明时记为中风险;超标且无说明时记为高风险。", "", "## 输出", "", "- 行程异常时输出高风险退回。", "- 差标超限但有合理说明时输出中风险提醒。", "- 命中差旅制度规则时,保留 `rule_code` 和 `rule_version` 供审批链追踪。", "", "## 来源依据", "", "- 公司差旅制度关于行程闭环、酒店地点一致性、职级差标和例外说明的规定。", "", "## 审核约束", "", "- 当前规则为系统内置真实运行规则,修改前需确认差旅制度版本与灰度回滚方案。", "- 规则 JSON 与 Markdown 说明必须保持一致。", "", "## 管理员备注", "", "如制度调整职级带、城市分级或交通等级,应先更新运行时 JSON,再同步修改本说明。", "", "```expense-rule", json.dumps(DEFAULT_TRAVEL_POLICY_CONFIG, ensure_ascii=False, indent=2), "```", ] )