64 lines
2.2 KiB
Python
64 lines
2.2 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from typing import Any
|
||
|
|
|
||
|
|
from app.algorithem.employee_behavior_profile import build_review_suggestions
|
||
|
|
from app.models.employee_behavior_profile import EmployeeBehaviorProfileSnapshot
|
||
|
|
|
||
|
|
|
||
|
|
def build_profile_payloads(
|
||
|
|
rows: list[EmployeeBehaviorProfileSnapshot],
|
||
|
|
) -> list[dict[str, Any]]:
|
||
|
|
return [
|
||
|
|
{
|
||
|
|
"profile_type": row.profile_type,
|
||
|
|
"profile_label": row.profile_type,
|
||
|
|
"score": row.profile_score,
|
||
|
|
"level": row.profile_level,
|
||
|
|
"metrics": row.metrics_json or {},
|
||
|
|
"top_contributors": row.basis_codes_json or [],
|
||
|
|
}
|
||
|
|
for row in sorted(rows, key=lambda item: item.profile_type)
|
||
|
|
]
|
||
|
|
|
||
|
|
|
||
|
|
def build_latest_review_suggestions(
|
||
|
|
*,
|
||
|
|
rows: list[EmployeeBehaviorProfileSnapshot],
|
||
|
|
expense_score: int,
|
||
|
|
process_score: int,
|
||
|
|
) -> list[dict[str, Any]]:
|
||
|
|
expense_row = next((row for row in rows if row.profile_type == "expense"), None)
|
||
|
|
metrics = expense_row.metrics_json if expense_row is not None else {}
|
||
|
|
formula_suggestions = build_review_suggestions(
|
||
|
|
expense_profile_score=expense_score,
|
||
|
|
process_quality_score=process_score,
|
||
|
|
requested_days=metrics.get("requested_days"),
|
||
|
|
peer_days_p75=metrics.get("peer_days_p75"),
|
||
|
|
peer_unit_amount_p75=metrics.get("peer_unit_amount_p75"),
|
||
|
|
)
|
||
|
|
merged = [*formula_suggestions, *_merge_review_suggestions(rows)]
|
||
|
|
seen: set[str] = set()
|
||
|
|
unique: list[dict[str, Any]] = []
|
||
|
|
for item in merged:
|
||
|
|
key = str(item.get("type") or item.get("message") or "").strip()
|
||
|
|
if not key or key in seen:
|
||
|
|
continue
|
||
|
|
seen.add(key)
|
||
|
|
unique.append(item)
|
||
|
|
return unique[:5]
|
||
|
|
|
||
|
|
|
||
|
|
def _merge_review_suggestions(
|
||
|
|
rows: list[EmployeeBehaviorProfileSnapshot],
|
||
|
|
) -> list[dict[str, Any]]:
|
||
|
|
merged: list[dict[str, Any]] = []
|
||
|
|
seen: set[str] = set()
|
||
|
|
for row in rows:
|
||
|
|
for suggestion in (row.metrics_json or {}).get("review_suggestions") or []:
|
||
|
|
key = str(suggestion.get("type") or suggestion.get("message") or "")
|
||
|
|
if key and key not in seen:
|
||
|
|
seen.add(key)
|
||
|
|
merged.append(suggestion)
|
||
|
|
return merged[:5]
|