161 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			161 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from models import db, Assessment, Exercise, GradingElement
 | |
| from utils import safe_int_conversion, safe_decimal_conversion, validate_json_data, ValidationError, log_user_action
 | |
| from datetime import datetime
 | |
| 
 | |
| class AssessmentService:
 | |
|     """Service pour gérer les opérations sur les évaluations"""
 | |
|     
 | |
|     @staticmethod
 | |
|     def create_assessment(form_data):
 | |
|         """Crée une nouvelle évaluation"""
 | |
|         assessment = Assessment(
 | |
|             title=form_data['title'],
 | |
|             description=form_data.get('description', ''),
 | |
|             date=form_data['date'],
 | |
|             trimester=form_data['trimester'],
 | |
|             class_group_id=form_data['class_group_id'],
 | |
|             coefficient=form_data['coefficient']
 | |
|         )
 | |
|         db.session.add(assessment)
 | |
|         db.session.flush()  # Pour obtenir l'ID
 | |
|         log_user_action("Création évaluation", f"ID: {assessment.id}, Titre: {assessment.title}")
 | |
|         return assessment
 | |
|     
 | |
|     @staticmethod
 | |
|     def update_assessment_basic_info(assessment, form_data):
 | |
|         """Met à jour les informations de base d'une évaluation"""
 | |
|         assessment.title = form_data['title']
 | |
|         assessment.description = form_data.get('description', '')
 | |
|         assessment.date = form_data['date']
 | |
|         assessment.trimester = form_data['trimester']
 | |
|         assessment.class_group_id = form_data['class_group_id']
 | |
|         assessment.coefficient = form_data['coefficient']
 | |
|         log_user_action("Modification évaluation", f"ID: {assessment.id}")
 | |
|     
 | |
|     @staticmethod
 | |
|     def delete_assessment_exercises(assessment):
 | |
|         """Supprime tous les exercices d'une évaluation (pour remplacement)"""
 | |
|         for exercise in assessment.exercises:
 | |
|             db.session.delete(exercise)
 | |
|     
 | |
|     @staticmethod
 | |
|     def process_assessment_with_exercises(assessment_data, is_edit=False, existing_assessment=None):
 | |
|         """Traite une évaluation complète avec exercices et éléments"""
 | |
|         # Validation des données de base
 | |
|         required_fields = ['title', 'date', 'trimester', 'class_group_id', 'coefficient']
 | |
|         validate_json_data(assessment_data, required_fields)
 | |
|         
 | |
|         # Validation et conversion des types
 | |
|         try:
 | |
|             class_group_id = safe_int_conversion(assessment_data['class_group_id'], "ID de classe")
 | |
|             coefficient = safe_decimal_conversion(assessment_data['coefficient'], "coefficient")
 | |
|             trimester = safe_int_conversion(assessment_data['trimester'], "trimestre")
 | |
|             
 | |
|             # Validation du trimestre
 | |
|             if trimester not in [1, 2, 3]:
 | |
|                 raise ValidationError("Le trimestre doit être 1, 2 ou 3")
 | |
|             
 | |
|             # Validation de la date
 | |
|             date_str = assessment_data.get('date')
 | |
|             if date_str:
 | |
|                 date_obj = datetime.strptime(date_str, '%Y-%m-%d').date()
 | |
|             else:
 | |
|                 raise ValidationError("Date requise")
 | |
|                 
 | |
|         except ValueError as e:
 | |
|             raise ValidationError(str(e))
 | |
|         
 | |
|         # Préparation des données validées
 | |
|         validated_data = {
 | |
|             'title': assessment_data['title'].strip(),
 | |
|             'description': assessment_data.get('description', '').strip(),
 | |
|             'date': date_obj,
 | |
|             'trimester': trimester,
 | |
|             'class_group_id': class_group_id,
 | |
|             'coefficient': coefficient
 | |
|         }
 | |
|         
 | |
|         # Création ou mise à jour de l'évaluation
 | |
|         if is_edit and existing_assessment:
 | |
|             AssessmentService.update_assessment_basic_info(existing_assessment, validated_data)
 | |
|             AssessmentService.delete_assessment_exercises(existing_assessment)
 | |
|             assessment = existing_assessment
 | |
|         else:
 | |
|             assessment = AssessmentService.create_assessment(validated_data)
 | |
|         
 | |
|         # Traitement des exercices
 | |
|         exercises_data = assessment_data.get('exercises', [])
 | |
|         AssessmentService.process_exercises(assessment, exercises_data)
 | |
|         
 | |
|         return assessment
 | |
|     
 | |
|     @staticmethod
 | |
|     def process_exercises(assessment, exercises_data):
 | |
|         """Traite les exercices d'une évaluation"""
 | |
|         for ex_data in exercises_data:
 | |
|             # Validation des données d'exercice
 | |
|             if not ex_data.get('title'):
 | |
|                 raise ValidationError("Titre d'exercice requis")
 | |
|             
 | |
|             try:
 | |
|                 order = safe_int_conversion(ex_data.get('order', 1), "ordre de l'exercice")
 | |
|                 if order < 1:
 | |
|                     raise ValidationError("L'ordre de l'exercice doit être positif")
 | |
|             except ValueError as e:
 | |
|                 raise ValidationError(str(e))
 | |
|             
 | |
|             exercise = Exercise(
 | |
|                 title=ex_data['title'].strip(),
 | |
|                 description=ex_data.get('description', '').strip(),
 | |
|                 order=order,
 | |
|                 assessment_id=assessment.id
 | |
|             )
 | |
|             db.session.add(exercise)
 | |
|             db.session.flush()
 | |
|             
 | |
|             # Traitement des éléments de notation
 | |
|             grading_elements_data = ex_data.get('grading_elements', [])
 | |
|             AssessmentService.process_grading_elements(exercise, grading_elements_data)
 | |
|     
 | |
|     @staticmethod
 | |
|     def process_grading_elements(exercise, grading_elements_data):
 | |
|         """Traite les éléments de notation d'un exercice"""
 | |
|         for elem_data in grading_elements_data:
 | |
|             # Validation des données d'élément
 | |
|             if not elem_data.get('label'):
 | |
|                 raise ValidationError("Libellé d'élément de notation requis")
 | |
|             
 | |
|             grading_type = elem_data.get('grading_type', 'notes')
 | |
|             if grading_type not in ['notes', 'score']:
 | |
|                 raise ValidationError("Type de notation invalide")
 | |
|             
 | |
|             try:
 | |
|                 max_points = safe_decimal_conversion(elem_data.get('max_points'), "points maximum")
 | |
|                 if max_points <= 0:
 | |
|                     raise ValidationError("Les points maximum doivent être positifs")
 | |
|             except ValueError as e:
 | |
|                 raise ValidationError(str(e))
 | |
|             
 | |
|             # Gestion du domaine
 | |
|             domain_id = None
 | |
|             if 'domain_name' in elem_data and elem_data['domain_name']:
 | |
|                 # Récupérer ou créer le domaine
 | |
|                 from app_config import config_manager
 | |
|                 domain = config_manager.get_or_create_domain(
 | |
|                     elem_data['domain_name'], 
 | |
|                     elem_data.get('domain_color', '#6B7280')
 | |
|                 )
 | |
|                 domain_id = domain.id
 | |
|             elif 'domain_id' in elem_data:
 | |
|                 domain_id = elem_data['domain_id']
 | |
|             
 | |
|             grading_element = GradingElement(
 | |
|                 label=elem_data['label'].strip(),
 | |
|                 description=elem_data.get('description', '').strip(),
 | |
|                 skill=elem_data.get('skill', '').strip(),
 | |
|                 max_points=max_points,
 | |
|                 grading_type=grading_type,
 | |
|                 domain_id=domain_id,
 | |
|                 exercise_id=exercise.id
 | |
|             )
 | |
|             db.session.add(grading_element) |