feat: add commentary in concil prep

This commit is contained in:
2025-08-15 07:59:23 +02:00
parent c3ef5287b3
commit f438082c4c
4 changed files with 656 additions and 5 deletions

View File

@@ -3,7 +3,7 @@ Services pour la préparation du conseil de classe.
Comprend CouncilPreparationService, StudentEvaluationService, AppreciationService.
"""
from dataclasses import dataclass
from typing import Dict, List, Optional, Tuple
from typing import Dict, List, Optional, Tuple, Any
from datetime import datetime
from repositories.appreciation_repository import AppreciationRepository
from repositories.grade_repository import GradeRepository
@@ -22,6 +22,7 @@ class StudentTrimesterSummary:
appreciation: Optional[CouncilAppreciation]
performance_status: str # 'excellent', 'good', 'average', 'struggling'
competence_domain_breakdown: Optional[Dict] = None # Données des compétences et domaines
special_values_summary: Optional[Dict] = None # Résumé des valeurs spéciales
@property
def has_appreciation(self) -> bool:
@@ -101,6 +102,13 @@ class StudentEvaluationService:
# Calculer les données de compétences et domaines
competence_domain_breakdown = self.get_student_competence_domain_breakdown(student_id, trimester)
# Calculer le résumé des valeurs spéciales
special_values_summary = self.get_student_special_values_summary(student_id, trimester)
# Ajouter tous les commentaires organisés par évaluations
all_comments_data = self.grade_repo.get_all_comments_by_student_trimester(student_id, trimester)
special_values_summary['comments_by_assessments'] = all_comments_data
return StudentTrimesterSummary(
student=student,
overall_average=overall_average,
@@ -108,7 +116,8 @@ class StudentEvaluationService:
grades_by_assessment=grades_by_assessment,
appreciation=appreciation,
performance_status=performance_status,
competence_domain_breakdown=competence_domain_breakdown
competence_domain_breakdown=competence_domain_breakdown,
special_values_summary=special_values_summary
)
def get_students_summaries(self, class_group_id: int, trimester: int) -> List[StudentTrimesterSummary]:
@@ -349,6 +358,80 @@ class StudentEvaluationService:
'domains': domains
}
def get_student_special_values_summary(self, student_id: int, trimester: int) -> Dict[str, Any]:
"""
Calcule le résumé des valeurs spéciales pour un élève sur un trimestre.
Returns:
Dict avec 'global' (total par trimestre) et 'by_assessment' (détail par évaluation)
"""
from app_config import config_manager
# Récupérer les valeurs spéciales configurées
special_values_config = config_manager.get_special_values()
# 1. Comptes globaux par trimestre
global_counts = self.grade_repo.get_special_values_counts_by_student_trimester(student_id, trimester)
global_details = self.grade_repo.get_special_values_details_by_student_trimester(student_id, trimester)
# 2. Comptes par évaluation
assessments = self.assessment_repo.find_by_class_trimester_with_details(
Student.query.get(student_id).class_group_id, trimester
)
by_assessment = {}
for assessment in assessments:
assessment_counts = self.grade_repo.get_special_values_counts_by_student_assessment(
student_id, assessment.id
)
assessment_details = self.grade_repo.get_special_values_details_by_student_assessment(
student_id, assessment.id
)
# Ajouter seulement si l'élève a des valeurs spéciales dans cette évaluation
if any(count > 0 for count in assessment_counts.values()):
by_assessment[assessment.id] = {
'title': assessment.title,
'date': assessment.date,
'counts': assessment_counts,
'details': assessment_details
}
# 3. Enrichir avec les métadonnées de configuration
enriched_global = {}
enriched_by_assessment = {}
for special_value, config in special_values_config.items():
enriched_global[special_value] = {
'count': global_counts.get(special_value, 0),
'label': config['label'],
'color': config['color'],
'counts_in_total': config['counts'],
'details': global_details.get(special_value, [])
}
for assessment_id, assessment_data in by_assessment.items():
enriched_by_assessment[assessment_id] = {
'title': assessment_data['title'],
'date': assessment_data['date'],
'special_values': {}
}
for special_value, config in special_values_config.items():
enriched_by_assessment[assessment_id]['special_values'][special_value] = {
'count': assessment_data['counts'].get(special_value, 0),
'label': config['label'],
'color': config['color'],
'details': assessment_data['details'].get(special_value, [])
}
return {
'global': enriched_global,
'by_assessment': enriched_by_assessment,
'total_special_values': sum(global_counts.values()),
'has_special_values': sum(global_counts.values()) > 0
}
def _calculate_assessment_score_for_student(self, assessment: Assessment, student_id: int) -> Optional[float]:
"""Calcule le score d'un élève pour une évaluation."""
grades = self.grade_repo.get_student_grades_by_assessment(student_id, assessment.id)