diff --git a/routes/grading.py b/routes/grading.py index ffefaac..eb05e27 100644 --- a/routes/grading.py +++ b/routes/grading.py @@ -1,4 +1,4 @@ -from flask import Blueprint, render_template, redirect, url_for, flash, request +from flask import Blueprint, render_template, redirect, url_for, flash, request, jsonify from models import db, Assessment, Student, Grade, GradingElement, Exercise from app_config import config_manager @@ -35,66 +35,98 @@ def assessment_grading(assessment_id): @bp.route('/assessments//grading/save', methods=['POST']) def save_grades(assessment_id): assessment = Assessment.query.get_or_404(assessment_id) + errors = [] - for key, value in request.form.items(): - if key.startswith('grade_'): - # Parse key: grade__ - parts = key.split('_') - if len(parts) == 3: - student_id = int(parts[1]) - element_id = int(parts[2]) - - # Find or create grade - grade = Grade.query.filter_by( - student_id=student_id, - grading_element_id=element_id - ).first() - - if value.strip(): # If value is not empty - # Validation unifiée selon le nouveau système - grading_element = GradingElement.query.get(element_id) - if grading_element: - # Passer max_points pour la validation des notes - max_points = grading_element.max_points if grading_element.grading_type == 'notes' else None - - # Normaliser virgule en point pour les notes avant sauvegarde - normalized_value = value.strip() - if grading_element.grading_type == 'notes' and ',' in normalized_value: - normalized_value = normalized_value.replace(',', '.') - - if config_manager.validate_grade_value(normalized_value, grading_element.grading_type, max_points): - if not grade: - grade = Grade( - student_id=student_id, - grading_element_id=element_id, - value=normalized_value - ) - db.session.add(grade) + try: + for key, value in request.form.items(): + if key.startswith('grade_'): + # Parse key: grade__ + parts = key.split('_') + if len(parts) == 3: + student_id = int(parts[1]) + element_id = int(parts[2]) + + # Find or create grade + grade = Grade.query.filter_by( + student_id=student_id, + grading_element_id=element_id + ).first() + + if value.strip(): # If value is not empty + # Validation unifiée selon le nouveau système + grading_element = GradingElement.query.get(element_id) + if grading_element: + # Passer max_points pour la validation des notes + max_points = grading_element.max_points if grading_element.grading_type == 'notes' else None + + # Normaliser virgule en point pour les notes avant sauvegarde + normalized_value = value.strip() + if grading_element.grading_type == 'notes' and ',' in normalized_value: + normalized_value = normalized_value.replace(',', '.') + + if config_manager.validate_grade_value(normalized_value, grading_element.grading_type, max_points): + if not grade: + grade = Grade( + student_id=student_id, + grading_element_id=element_id, + value=normalized_value + ) + db.session.add(grade) + else: + grade.value = normalized_value else: - grade.value = normalized_value + errors.append(f'Valeur invalide pour {grading_element.label if grading_element else "cet élément"}: {value}') else: - flash(f'Valeur invalide pour {grading_element.label if grading_element else "cet élément"}: {value}', 'warning') - else: - flash(f'Élément de notation non trouvé: {element_id}', 'error') - elif grade: # If value is empty but grade exists, delete it - db.session.delete(grade) - - # Handle comments - for key, value in request.form.items(): - if key.startswith('comment_'): - parts = key.split('_') - if len(parts) == 3: - student_id = int(parts[1]) - element_id = int(parts[2]) - - grade = Grade.query.filter_by( - student_id=student_id, - grading_element_id=element_id - ).first() - - if grade: - grade.comment = value.strip() if value.strip() else None - - db.session.commit() - flash('Notes sauvegardées avec succès !', 'success') - return redirect(url_for('grading.assessment_grading', assessment_id=assessment_id)) \ No newline at end of file + errors.append(f'Élément de notation non trouvé: {element_id}') + elif grade: # If value is empty but grade exists, delete it + db.session.delete(grade) + + # Handle comments + for key, value in request.form.items(): + if key.startswith('comment_'): + parts = key.split('_') + if len(parts) == 3: + student_id = int(parts[1]) + element_id = int(parts[2]) + + grade = Grade.query.filter_by( + student_id=student_id, + grading_element_id=element_id + ).first() + + if grade: + grade.comment = value.strip() if value.strip() else None + + db.session.commit() + + # Check if it's an AJAX request + if request.headers.get('X-Requested-With') == 'XMLHttpRequest': + if errors: + return jsonify({ + 'success': False, + 'message': 'Certaines notes n\'ont pas pu être sauvegardées', + 'errors': errors + }) + else: + return jsonify({ + 'success': True, + 'message': 'Notes sauvegardées avec succès !' + }) + else: + # Traditional form submission + if errors: + for error in errors: + flash(error, 'warning') + flash('Notes sauvegardées avec succès !', 'success') + return redirect(url_for('grading.assessment_grading', assessment_id=assessment_id)) + + except Exception as e: + db.session.rollback() + if request.headers.get('X-Requested-With') == 'XMLHttpRequest': + return jsonify({ + 'success': False, + 'message': f'Erreur lors de la sauvegarde: {str(e)}' + }), 500 + else: + flash(f'Erreur lors de la sauvegarde: {str(e)}', 'error') + return redirect(url_for('grading.assessment_grading', assessment_id=assessment_id)) \ No newline at end of file diff --git a/templates/assessment_grading.html b/templates/assessment_grading.html index 06193d7..7156519 100644 --- a/templates/assessment_grading.html +++ b/templates/assessment_grading.html @@ -23,7 +23,7 @@
F1 : Afficher/Masquer cette aide
-
+
{% else %}
- -
-
-

Grille de notation

+ +
+ +
+

+ Grille de notation + +

- + @@ -377,975 +429,720 @@