167 lines
6.7 KiB
Python
167 lines
6.7 KiB
Python
|
|
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),
|
|||
|
|
"```",
|
|||
|
|
]
|
|||
|
|
)
|