feat(expenses): add transactional expense case events

This commit is contained in:
caoxiaozhu
2026-07-13 11:58:48 +08:00
parent 9a84e125d0
commit 661990b27b
21 changed files with 1973 additions and 63 deletions

View File

@@ -115,6 +115,7 @@ from app.services.expense_claim_constants import (
TRAVEL_POLICY_HOTEL_NIGHT_PATTERN,
STANDARD_ADJUSTMENT_RISK_SOURCE,
)
from app.services.expense_cases import ExpenseCaseService
from app.services.expense_claim_risk_review import ExpenseClaimRiskReviewMixin
from app.services.expense_amounts import (
extract_amount_candidates,
@@ -645,6 +646,20 @@ class ExpenseClaimItemActionMixin:
claim.risk_flags_json = dedupe_claim_risk_flags(claim.risk_flags_json)
self._expense_cases.record_claim_event(
claim,
event_type=("application_submitted" if is_application_claim else "claim_submitted"),
actor_id=current_user.username,
tenant_id=getattr(current_user, "tenant_id", None),
idempotency_key=(
f"submit:{claim.id}:{claim.submitted_at.isoformat()}"
if claim.submitted_at is not None
else f"submit:{claim.id}:{before_json.get('status') or 'draft'}"
),
previous_status=str(before_json.get("status") or ""),
previous_approval_stage=str(before_json.get("approval_stage") or ""),
)
self.db.commit()
self.db.refresh(claim)
@@ -843,6 +858,20 @@ class ExpenseClaimItemActionMixin:
business_stage="expense_application" if is_application_claim else "reimbursement",
)
self._expense_cases.record_claim_event(
claim,
event_type=("application_returned" if is_application_claim else "claim_returned"),
actor_id=current_user.username,
tenant_id=getattr(current_user, "tenant_id", None),
idempotency_key=str(return_flag.get("return_event_id") or ""),
previous_status=previous_status,
previous_approval_stage=previous_stage,
extra_payload={
"reason": message,
"reason_codes": normalized_reason_codes,
},
)
self.db.commit()
self.db.refresh(claim)
@@ -862,6 +891,7 @@ class ExpenseClaimService(ExpenseClaimStandardAdjustmentMixin, ExpenseClaimItemA
def __init__(self, db: Session) -> None:
self.db = db
self.audit_service = AuditLogService(db)
self._expense_cases = ExpenseCaseService(db)
self._access_policy = ExpenseClaimAccessPolicy(db)
self._attachment_storage = ExpenseClaimAttachmentStorage()
self._attachment_presentation = ExpenseClaimAttachmentPresentation(self._attachment_storage)