fix(analytics): normalize dashboard entry years

This commit is contained in:
2026-06-15 17:26:57 +03:30
parent 38e7baef9c
commit a326d2e31d

View File

@@ -89,6 +89,43 @@ def _label(value) -> str:
return str(value or UNKNOWN_LABEL)
def _normalize_entry_year(value) -> str:
if value in (None, ""):
return UNKNOWN_LABEL
raw = str(value).strip()
normalized = (
raw.translate(str.maketrans("۰۱۲۳۴۵۶۷۸۹٠١٢٣٤٥٦٧٨٩", "01234567890123456789"))
.replace(",", "")
.replace("٬", "")
)
try:
year = int(normalized)
except (TypeError, ValueError):
return UNKNOWN_LABEL
if 1390 <= year <= 1499:
return str(year)
if 400 <= year <= 499:
return str(1000 + year)
if 90 <= year <= 99:
return str(1300 + year)
return UNKNOWN_LABEL
def _point_group_from_rows(rows: list[dict], *, limit: int = TOP_ITEMS_LIMIT):
sorted_rows = sorted(rows, key=lambda item: (-int(item["value"] or 0), str(item["label"])))
top_rows = sorted_rows[:limit]
other_rows = sorted_rows[limit:]
return {
"top_items": [
{"label": _label(item["label"]), "value": int(item["value"] or 0)}
for item in top_rows
],
"other_count": len(other_rows),
"total_count": len(sorted_rows),
}
def _point_queryset(queryset, label_field: str, *, limit: int = 12):
return [
{"label": _label(item.get(label_field)), "value": item["value"]}
@@ -122,6 +159,17 @@ def _point_group_queryset(queryset, label_field: str, *, limit: int = TOP_ITEMS_
}
def _entry_year_group_queryset(queryset, *, limit: int = TOP_ITEMS_LIMIT):
buckets: dict[str, int] = {}
for item in queryset.values("year_of_study").annotate(value=Count("id")):
label = _normalize_entry_year(item.get("year_of_study"))
buckets[label] = buckets.get(label, 0) + int(item["value"] or 0)
return _point_group_from_rows(
[{"label": label, "value": value} for label, value in buckets.items()],
limit=limit,
)
def _trend_queryset(queryset, field: str, granularity: str):
trunc = GRANULARITY_TRUNC[granularity]
rows = (
@@ -263,7 +311,7 @@ def admin_users_analytics(request, date_from: str | None = None, date_to: str |
"signup_trend": _trend_queryset(users_qs, "date_joined", granularity),
"by_major": _point_group_queryset(users_qs, "major__name"),
"by_university": _point_group_queryset(users_qs, "university__name"),
"by_year": _point_group_queryset(users_qs, "year_of_study"),
"by_year": _entry_year_group_queryset(users_qs),
}
@@ -742,7 +790,7 @@ def admin_dashboard(
"signup_trend": _trend_queryset(users_qs, "date_joined", selected_granularity),
"by_major": _point_queryset(users_qs, "major__name"),
"by_university": _point_queryset(users_qs, "university__name"),
"by_year": _point_queryset(users_qs, "year_of_study"),
"by_year": _entry_year_group_queryset(users_qs)["top_items"],
},
"events": {
"registration_status": registration_status,