feat(mail): restauration de l'envoie de mail
This commit is contained in:
@@ -6,6 +6,7 @@ from typing import Optional, List
|
||||
from datetime import date
|
||||
|
||||
from fastapi import APIRouter, HTTPException, Query
|
||||
from fastapi.responses import HTMLResponse
|
||||
from sqlalchemy import select, func
|
||||
from sqlalchemy.orm import selectinload
|
||||
|
||||
@@ -392,6 +393,7 @@ async def get_assessment_results(
|
||||
student_scores[student_id] = StudentScore(
|
||||
student_id=student_id,
|
||||
student_name=f"{student.last_name} {student.first_name}",
|
||||
email=student.email, # Ajouter l'email de l'élève
|
||||
total_score=round(total_score, 2),
|
||||
total_max_points=counted_max,
|
||||
percentage=percentage,
|
||||
@@ -1215,3 +1217,127 @@ async def send_reports(
|
||||
results=results,
|
||||
message=message
|
||||
)
|
||||
|
||||
|
||||
@router.get("/{assessment_id}/preview-report/{student_id}", response_class=HTMLResponse)
|
||||
async def preview_report(
|
||||
assessment_id: int,
|
||||
student_id: int,
|
||||
session: AsyncSessionDep,
|
||||
):
|
||||
"""
|
||||
Génère un aperçu HTML du bilan d'un élève sans l'envoyer.
|
||||
|
||||
Utile pour vérifier le rendu du bilan avant l'envoi groupé.
|
||||
Retourne le HTML brut qui serait envoyé par email, directement affichable dans le navigateur.
|
||||
"""
|
||||
# Récupérer l'évaluation avec toutes les relations nécessaires
|
||||
assessment_query = (
|
||||
select(Assessment)
|
||||
.options(
|
||||
selectinload(Assessment.class_group),
|
||||
selectinload(Assessment.exercises).selectinload(Exercise.grading_elements).selectinload(GradingElement.grades),
|
||||
selectinload(Assessment.exercises).selectinload(Exercise.grading_elements).selectinload(GradingElement.domain)
|
||||
)
|
||||
.where(Assessment.id == assessment_id)
|
||||
)
|
||||
assessment_result = await session.execute(assessment_query)
|
||||
assessment = assessment_result.scalar_one_or_none()
|
||||
|
||||
if not assessment:
|
||||
raise HTTPException(status_code=404, detail="Évaluation non trouvée")
|
||||
|
||||
# Récupérer l'élève
|
||||
student_query = select(Student).where(Student.id == student_id)
|
||||
student_result = await session.execute(student_query)
|
||||
student = student_result.scalar_one_or_none()
|
||||
|
||||
if not student:
|
||||
raise HTTPException(status_code=404, detail="Élève non trouvé")
|
||||
|
||||
# Préparer les données pour le service de rapport (même logique que send_reports)
|
||||
assessment_data = {
|
||||
'title': assessment.title,
|
||||
'description': assessment.description,
|
||||
'date': assessment.date.isoformat() if assessment.date else '',
|
||||
'trimester': assessment.trimester,
|
||||
'class_name': assessment.class_group.name,
|
||||
'coefficient': assessment.coefficient
|
||||
}
|
||||
|
||||
# Préparer les données des exercices et éléments
|
||||
exercises_data = []
|
||||
all_students_grades = {} # {student_id: [grades]}
|
||||
|
||||
for exercise in sorted(assessment.exercises, key=lambda x: x.order):
|
||||
elements_data = []
|
||||
for element in exercise.grading_elements:
|
||||
element_data = {
|
||||
'id': element.id,
|
||||
'exercise_id': exercise.id,
|
||||
'label': element.label,
|
||||
'description': element.description,
|
||||
'skill': element.skill,
|
||||
'domain_name': element.domain.name if element.domain else None,
|
||||
'domain_color': element.domain.color if element.domain else None,
|
||||
'grading_type': element.grading_type,
|
||||
'max_points': element.max_points
|
||||
}
|
||||
elements_data.append(element_data)
|
||||
|
||||
# Collecter les notes
|
||||
for grade in element.grades:
|
||||
if grade.student_id not in all_students_grades:
|
||||
all_students_grades[grade.student_id] = []
|
||||
all_students_grades[grade.student_id].append({
|
||||
'element_id': element.id,
|
||||
'value': grade.value,
|
||||
'comment': grade.comment
|
||||
})
|
||||
|
||||
exercises_data.append({
|
||||
'id': exercise.id,
|
||||
'title': exercise.title,
|
||||
'description': exercise.description,
|
||||
'order': exercise.order,
|
||||
'elements': elements_data
|
||||
})
|
||||
|
||||
# Vérifier que l'élève a des notes pour cette évaluation
|
||||
if student_id not in all_students_grades:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"L'élève {student.first_name} {student.last_name} n'a pas de notes pour cette évaluation"
|
||||
)
|
||||
|
||||
# Créer le service de rapport
|
||||
report_service = StudentReportService()
|
||||
|
||||
# Préparer les données de l'élève
|
||||
student_data = {
|
||||
'id': student.id,
|
||||
'first_name': student.first_name,
|
||||
'last_name': student.last_name,
|
||||
'email': student.email
|
||||
}
|
||||
|
||||
try:
|
||||
# Générer le rapport
|
||||
report_data = report_service.generate_student_report(
|
||||
assessment_data,
|
||||
student_data,
|
||||
all_students_grades,
|
||||
exercises_data
|
||||
)
|
||||
|
||||
# Générer le HTML (sans message personnalisé pour la prévisualisation)
|
||||
html_body = generate_report_html(report_data, "")
|
||||
|
||||
# Retourner directement le HTML pour affichage dans le navigateur
|
||||
return HTMLResponse(content=html_body)
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail=f"Erreur lors de la génération du rapport: {str(e)}"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user