cam / app /services /group_progress.py
cacode's picture
Upload 60 files
02a8414 verified
from __future__ import annotations
from datetime import datetime
from sqlalchemy.orm import Session, joinedload
from app.models import Activity, Submission, Task, User
def get_activity_with_group_context(db: Session, activity_id: int) -> Activity | None:
return (
db.query(Activity)
.options(
joinedload(Activity.tasks)
.joinedload(Task.submissions)
.joinedload(Submission.user)
.joinedload(User.group),
joinedload(Activity.tasks)
.joinedload(Task.submissions)
.joinedload(Submission.group),
joinedload(Activity.tasks)
.joinedload(Task.submissions)
.joinedload(Submission.reviewed_by),
joinedload(Activity.tasks)
.joinedload(Task.submissions)
.joinedload(Submission.assigned_admin),
)
.filter(Activity.id == activity_id)
.first()
)
def pick_primary_submission(submissions: list[Submission]) -> Submission | None:
if not submissions:
return None
approved = [submission for submission in submissions if submission.status == "approved"]
if approved:
return min(
approved,
key=lambda item: ((item.approved_at or item.created_at or datetime.min), item.id),
)
pending = [submission for submission in submissions if submission.status == "pending"]
if pending:
return max(
pending,
key=lambda item: ((item.created_at or datetime.min), item.id),
)
rejected = [submission for submission in submissions if submission.status == "rejected"]
if rejected:
return max(
rejected,
key=lambda item: ((item.created_at or datetime.min), item.id),
)
return max(
submissions,
key=lambda item: ((item.created_at or datetime.min), item.id),
)
def build_group_submission_map(activity: Activity, group_id: int | None) -> dict[int, Submission]:
if not activity or not group_id:
return {}
group_submissions: dict[int, Submission] = {}
for task in activity.tasks:
task_submissions = [submission for submission in task.submissions if submission.group_id == group_id]
primary_submission = pick_primary_submission(task_submissions)
if primary_submission:
group_submissions[task.id] = primary_submission
return group_submissions
def build_group_progress(activity: Activity, group_id: int | None) -> dict:
total_tasks = len(activity.tasks) if activity else 0
if not activity or not group_id:
return {
"total_tasks": total_tasks,
"approved_count": 0,
"pending_count": 0,
"rejected_count": 0,
"completion_ratio": 0,
}
submission_map = build_group_submission_map(activity, group_id)
approved_count = sum(1 for submission in submission_map.values() if submission.status == "approved")
pending_count = sum(1 for submission in submission_map.values() if submission.status == "pending")
rejected_count = sum(1 for submission in submission_map.values() if submission.status == "rejected")
return {
"total_tasks": total_tasks,
"approved_count": approved_count,
"pending_count": pending_count,
"rejected_count": rejected_count,
"completion_ratio": 0 if total_tasks == 0 else approved_count / total_tasks,
}