187 lines
5.9 KiB
Python
187 lines
5.9 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, status, Query
|
|
from typing import List, Optional
|
|
from models import TeacherGradeCreate, TeacherGradeUpdate, TeacherGradeResponse, TeacherGradeInDB, UserInDB
|
|
from database import get_database
|
|
from routes.auth_routes import get_current_user
|
|
from bson import ObjectId
|
|
from datetime import datetime
|
|
|
|
router = APIRouter(prefix="/teacher-grades", tags=["teacher-grades"])
|
|
|
|
|
|
@router.post("", response_model=TeacherGradeResponse, status_code=status.HTTP_201_CREATED)
|
|
async def create_teacher_grade(
|
|
teacher_grade: TeacherGradeCreate,
|
|
current_user: UserInDB = Depends(get_current_user)
|
|
):
|
|
"""Create or update a teacher-provided grade override for a subject in a period"""
|
|
db = get_database()
|
|
|
|
# Verify subject exists and belongs to user
|
|
if not ObjectId.is_valid(teacher_grade.subject_id):
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail="Invalid subject ID"
|
|
)
|
|
|
|
subject = await db.subjects.find_one({
|
|
"_id": ObjectId(teacher_grade.subject_id),
|
|
"user_id": current_user.id
|
|
})
|
|
|
|
if not subject:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Subject not found"
|
|
)
|
|
|
|
# Verify period exists and belongs to user
|
|
if not ObjectId.is_valid(teacher_grade.period_id):
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail="Invalid period ID"
|
|
)
|
|
|
|
period = await db.periods.find_one({
|
|
"_id": ObjectId(teacher_grade.period_id),
|
|
"user_id": current_user.id
|
|
})
|
|
|
|
if not period:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Period not found"
|
|
)
|
|
|
|
# Check if teacher grade already exists for this subject and period
|
|
existing = await db.teacher_grades.find_one({
|
|
"subject_id": teacher_grade.subject_id,
|
|
"period_id": teacher_grade.period_id,
|
|
"user_id": current_user.id
|
|
})
|
|
|
|
if existing:
|
|
# Update existing teacher grade
|
|
update_data = teacher_grade.model_dump()
|
|
update_data["updated_at"] = datetime.utcnow()
|
|
|
|
await db.teacher_grades.update_one(
|
|
{"_id": existing["_id"]},
|
|
{"$set": update_data}
|
|
)
|
|
|
|
updated = await db.teacher_grades.find_one({"_id": existing["_id"]})
|
|
updated["_id"] = str(updated["_id"])
|
|
return TeacherGradeResponse(**updated)
|
|
else:
|
|
# Create new teacher grade
|
|
teacher_grade_in_db = TeacherGradeInDB(
|
|
**teacher_grade.model_dump(),
|
|
user_id=current_user.id
|
|
)
|
|
|
|
grade_dict = teacher_grade_in_db.model_dump(by_alias=True)
|
|
grade_dict["_id"] = ObjectId(grade_dict["_id"])
|
|
|
|
result = await db.teacher_grades.insert_one(grade_dict)
|
|
grade_dict["_id"] = str(result.inserted_id)
|
|
|
|
return TeacherGradeResponse(**grade_dict)
|
|
|
|
|
|
@router.get("", response_model=List[TeacherGradeResponse])
|
|
async def get_teacher_grades(
|
|
subject_id: Optional[str] = Query(None),
|
|
period_id: Optional[str] = Query(None),
|
|
current_user: UserInDB = Depends(get_current_user)
|
|
):
|
|
"""Get all teacher grades for the current user, optionally filtered by subject or period"""
|
|
db = get_database()
|
|
|
|
query = {"user_id": current_user.id}
|
|
|
|
if subject_id:
|
|
if not ObjectId.is_valid(subject_id):
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail="Invalid subject ID"
|
|
)
|
|
query["subject_id"] = subject_id
|
|
|
|
if period_id:
|
|
if not ObjectId.is_valid(period_id):
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail="Invalid period ID"
|
|
)
|
|
query["period_id"] = period_id
|
|
|
|
cursor = db.teacher_grades.find(query)
|
|
teacher_grades = await cursor.to_list(length=None)
|
|
|
|
for grade in teacher_grades:
|
|
grade["_id"] = str(grade["_id"])
|
|
|
|
return [TeacherGradeResponse(**grade) for grade in teacher_grades]
|
|
|
|
|
|
@router.get("/{teacher_grade_id}", response_model=TeacherGradeResponse)
|
|
async def get_teacher_grade(
|
|
teacher_grade_id: str,
|
|
current_user: UserInDB = Depends(get_current_user)
|
|
):
|
|
"""Get a specific teacher grade"""
|
|
db = get_database()
|
|
|
|
if not ObjectId.is_valid(teacher_grade_id):
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail="Invalid teacher grade ID"
|
|
)
|
|
|
|
teacher_grade = await db.teacher_grades.find_one({
|
|
"_id": ObjectId(teacher_grade_id),
|
|
"user_id": current_user.id
|
|
})
|
|
|
|
if not teacher_grade:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Teacher grade not found"
|
|
)
|
|
|
|
teacher_grade["_id"] = str(teacher_grade["_id"])
|
|
return TeacherGradeResponse(**teacher_grade)
|
|
|
|
|
|
@router.delete("/{teacher_grade_id}", status_code=status.HTTP_204_NO_CONTENT)
|
|
async def delete_teacher_grade(
|
|
teacher_grade_id: str,
|
|
current_user: UserInDB = Depends(get_current_user)
|
|
):
|
|
"""Delete a teacher grade override"""
|
|
db = get_database()
|
|
|
|
if not ObjectId.is_valid(teacher_grade_id):
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail="Invalid teacher grade ID"
|
|
)
|
|
|
|
# Check if teacher grade exists and belongs to user
|
|
teacher_grade = await db.teacher_grades.find_one({
|
|
"_id": ObjectId(teacher_grade_id),
|
|
"user_id": current_user.id
|
|
})
|
|
|
|
if not teacher_grade:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Teacher grade not found"
|
|
)
|
|
|
|
# Delete teacher grade
|
|
await db.teacher_grades.delete_one({"_id": ObjectId(teacher_grade_id)})
|
|
|
|
return None
|