fix(risk): restore upload-time rule center review
This commit is contained in:
@@ -941,6 +941,8 @@ class RiskRuleTemplateExecutor:
|
||||
time_keys = (
|
||||
"application_time",
|
||||
"applicationTime",
|
||||
"application_business_time",
|
||||
"applicationBusinessTime",
|
||||
"application_date",
|
||||
"applicationDate",
|
||||
"business_time",
|
||||
@@ -975,6 +977,15 @@ class RiskRuleTemplateExecutor:
|
||||
if isinstance(nested, dict):
|
||||
sources.append(nested)
|
||||
for source_dict in sources:
|
||||
business_time_context = source_dict.get("business_time_context")
|
||||
if isinstance(business_time_context, dict):
|
||||
start_date = str(business_time_context.get("start_date") or "").strip()
|
||||
end_date = str(business_time_context.get("end_date") or start_date).strip()
|
||||
display_value = str(business_time_context.get("display_value") or "").strip()
|
||||
if display_value:
|
||||
values.append(display_value)
|
||||
elif start_date:
|
||||
values.append(f"{start_date} 至 {end_date or start_date}")
|
||||
for key in time_keys:
|
||||
value = source_dict.get(key)
|
||||
if value not in (None, ""):
|
||||
|
||||
@@ -2216,6 +2216,154 @@ def test_upload_attachment_response_includes_refreshed_rule_center_risk_flags(
|
||||
assert payload["claim_risk_flags"] == claim.risk_flags_json
|
||||
|
||||
|
||||
def test_upload_attachment_runs_rule_center_city_risk_from_origin_destination_fields(
|
||||
monkeypatch,
|
||||
tmp_path,
|
||||
) -> None:
|
||||
current_user = CurrentUserContext(
|
||||
username="emp-1",
|
||||
name="张三",
|
||||
role_codes=[],
|
||||
is_admin=False,
|
||||
)
|
||||
|
||||
def fake_recognize(
|
||||
self,
|
||||
files: list[tuple[str, bytes, str | None]],
|
||||
) -> OcrRecognizeBatchRead:
|
||||
return OcrRecognizeBatchRead(
|
||||
total_file_count=1,
|
||||
success_count=1,
|
||||
documents=[
|
||||
OcrRecognizeDocumentRead(
|
||||
filename="train-ticket.png",
|
||||
media_type="image/png",
|
||||
text="铁路电子客票 出发城市 武汉 到达城市 北京 2026-02-20 票价354元",
|
||||
summary="铁路电子客票,武汉至北京,票价 354 元。",
|
||||
avg_score=0.98,
|
||||
line_count=1,
|
||||
page_count=1,
|
||||
document_type="train_ticket",
|
||||
document_type_label="火车/高铁票",
|
||||
scene_code="travel",
|
||||
scene_label="差旅票据",
|
||||
document_fields=[
|
||||
{"key": "origin", "label": "出发城市", "value": "武汉"},
|
||||
{"key": "destination", "label": "到达城市", "value": "北京"},
|
||||
{"key": "trip_date", "label": "列车出发时间", "value": "2026-02-20"},
|
||||
{"key": "fare", "label": "票价", "value": "354元"},
|
||||
],
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
monkeypatch.setattr(OcrService, "recognize_files", fake_recognize)
|
||||
monkeypatch.setattr(ExpenseClaimAttachmentStorage, "root", lambda self: tmp_path)
|
||||
|
||||
with build_session() as db:
|
||||
claim = build_claim(expense_type="travel", location="上海")
|
||||
claim.reason = "支撑国网仿生产环境部署"
|
||||
claim.items[0].item_location = "上海"
|
||||
claim.items[0].invoice_id = None
|
||||
db.add(claim)
|
||||
db.commit()
|
||||
|
||||
payload = ExpenseClaimService(db).upload_claim_item_attachment(
|
||||
claim_id=claim.id,
|
||||
item_id=claim.items[0].id,
|
||||
filename="train-ticket.png",
|
||||
content=b"fake-image-bytes",
|
||||
media_type="image/png",
|
||||
current_user=current_user,
|
||||
)
|
||||
|
||||
flags = payload["claim_risk_flags"]
|
||||
assert any(
|
||||
isinstance(flag, dict)
|
||||
and flag.get("rule_code") == "risk.travel.high.city_mismatch"
|
||||
for flag in flags
|
||||
)
|
||||
|
||||
|
||||
def test_upload_attachment_uses_linked_application_business_time_for_date_risk(
|
||||
monkeypatch,
|
||||
tmp_path,
|
||||
) -> None:
|
||||
current_user = CurrentUserContext(
|
||||
username="emp-1",
|
||||
name="张三",
|
||||
role_codes=[],
|
||||
is_admin=False,
|
||||
)
|
||||
|
||||
def fake_recognize(
|
||||
self,
|
||||
files: list[tuple[str, bytes, str | None]],
|
||||
) -> OcrRecognizeBatchRead:
|
||||
return OcrRecognizeBatchRead(
|
||||
total_file_count=1,
|
||||
success_count=1,
|
||||
documents=[
|
||||
OcrRecognizeDocumentRead(
|
||||
filename="late-train-ticket.png",
|
||||
media_type="image/png",
|
||||
text="铁路电子客票 武汉-上海 2026-03-01 票价354元",
|
||||
summary="铁路电子客票,武汉至上海,2026-03-01 出发。",
|
||||
avg_score=0.98,
|
||||
line_count=1,
|
||||
page_count=1,
|
||||
document_type="train_ticket",
|
||||
document_type_label="火车/高铁票",
|
||||
scene_code="travel",
|
||||
scene_label="差旅票据",
|
||||
document_fields=[
|
||||
{"key": "route", "label": "行程", "value": "武汉-上海"},
|
||||
{"key": "trip_date", "label": "列车出发时间", "value": "2026-03-01"},
|
||||
{"key": "fare", "label": "票价", "value": "354元"},
|
||||
],
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
monkeypatch.setattr(OcrService, "recognize_files", fake_recognize)
|
||||
monkeypatch.setattr(ExpenseClaimAttachmentStorage, "root", lambda self: tmp_path)
|
||||
|
||||
with build_session() as db:
|
||||
claim = build_claim(expense_type="travel", location="上海")
|
||||
claim.reason = "支撑国网仿生产环境部署"
|
||||
claim.items[0].item_location = "上海"
|
||||
claim.items[0].invoice_id = None
|
||||
claim.risk_flags_json = [
|
||||
{
|
||||
"source": "application_link",
|
||||
"application_claim_id": "application-date-risk",
|
||||
"application_claim_no": "AP-20260220-TEST",
|
||||
"application_detail": {
|
||||
"application_business_time": "2026-02-20 至 2026-02-23",
|
||||
"application_location": "上海",
|
||||
},
|
||||
}
|
||||
]
|
||||
db.add(claim)
|
||||
db.commit()
|
||||
|
||||
payload = ExpenseClaimService(db).upload_claim_item_attachment(
|
||||
claim_id=claim.id,
|
||||
item_id=claim.items[0].id,
|
||||
filename="late-train-ticket.png",
|
||||
content=b"fake-image-bytes",
|
||||
media_type="image/png",
|
||||
current_user=current_user,
|
||||
)
|
||||
|
||||
flags = payload["claim_risk_flags"]
|
||||
assert any(
|
||||
isinstance(flag, dict)
|
||||
and flag.get("rule_code") == "risk.travel.high.date_outside_trip"
|
||||
for flag in flags
|
||||
)
|
||||
|
||||
|
||||
def test_upload_hotel_attachment_audits_date_like_amount(monkeypatch, tmp_path) -> None:
|
||||
current_user = CurrentUserContext(
|
||||
username="emp-1",
|
||||
|
||||
Reference in New Issue
Block a user