60 lines
2.1 KiB
Python
60 lines
2.1 KiB
Python
from typing import List, Optional
|
|
from sqlalchemy.orm import Session
|
|
from datetime import datetime
|
|
|
|
from app.crud.base import CRUDBase
|
|
from app.models.exam_result import ExamResult
|
|
from app.schemas.exam_result import ExamResultCreate, ExamResultUpdate
|
|
|
|
|
|
class CRUDExamResult(CRUDBase[ExamResult, ExamResultCreate, ExamResultUpdate]):
|
|
def get_by_student(self, db: Session, *, student_id: int) -> List[ExamResult]:
|
|
"""Get all exam results for a specific student"""
|
|
return db.query(self.model).filter(ExamResult.student_id == student_id).all()
|
|
|
|
def get_by_exam(self, db: Session, *, exam_id: int) -> List[ExamResult]:
|
|
"""Get all exam results for a specific exam"""
|
|
return db.query(self.model).filter(ExamResult.exam_id == exam_id).all()
|
|
|
|
def get_by_student_and_exam(
|
|
self, db: Session, *, student_id: int, exam_id: int
|
|
) -> Optional[ExamResult]:
|
|
"""Get a student's result for a specific exam"""
|
|
return (
|
|
db.query(self.model)
|
|
.filter(
|
|
ExamResult.student_id == student_id,
|
|
ExamResult.exam_id == exam_id
|
|
)
|
|
.first()
|
|
)
|
|
|
|
def get_active_exam_attempt(
|
|
self, db: Session, *, student_id: int, exam_id: int
|
|
) -> Optional[ExamResult]:
|
|
"""Get a student's active (incomplete) attempt for an exam"""
|
|
return (
|
|
db.query(self.model)
|
|
.filter(
|
|
ExamResult.student_id == student_id,
|
|
ExamResult.exam_id == exam_id,
|
|
~ExamResult.is_completed
|
|
)
|
|
.first()
|
|
)
|
|
|
|
def complete_exam(
|
|
self, db: Session, *, db_obj: ExamResult, score: float, max_score: float
|
|
) -> ExamResult:
|
|
"""Mark an exam as completed with the final score"""
|
|
db_obj.score = score
|
|
db_obj.max_score = max_score
|
|
db_obj.completed_at = datetime.utcnow()
|
|
db_obj.is_completed = True
|
|
db.add(db_obj)
|
|
db.commit()
|
|
db.refresh(db_obj)
|
|
return db_obj
|
|
|
|
|
|
exam_result = CRUDExamResult(ExamResult) |