--- /dev/null
+/*
+ * Copyright © FYLAB and the Conseil Régional d'Île-de-France, 2009
+ * This file is part of L'Interface Libre et Interactive de l'Enseignement (Lilie).
+ *
+ * Lilie is free software. You can redistribute it and/or modify since
+ * you respect the terms of either (at least one of the both license) :
+ * - under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ * - the CeCILL-C as published by CeCILL-C; either version 1 of the
+ * License, or any later version
+ *
+ * There are special exceptions to the terms and conditions of the
+ * licenses as they are applied to this software. View the full text of
+ * the exception in file LICENSE.txt in the directory of this software
+ * distribution.
+ *
+ * Lilie is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Licenses for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * and the CeCILL-C along with Lilie. If not, see :
+ * <http://www.gnu.org/licenses/> and
+ * <http://www.cecill.info/licences.fr.html>.
+ */
+
+package org.lilie.services.eliot.notes.notes
+
+import org.lilie.services.eliot.scolarite.Enseignement
+import org.lilie.services.eliot.scolarite.Periode
+import org.lilie.services.eliot.scolarite.Service
+import org.lilie.services.eliot.securite.AutorisationException
+import org.lilie.services.eliot.securite.impl.Autorite
+import org.lilie.services.eliot.exception.SauvegardeEchoueException
+import org.hibernate.FetchMode
+import org.lilie.services.eliot.exception.SuppresionEchoueException
+import org.lilie.services.eliot.scolarite.Etablissement
+import org.lilie.services.eliot.applications.notes.EvaluationService
+import org.lilie.services.eliot.notes.scolarite.NotesEnseignementService
+import org.lilie.services.eliot.notes.resultat.UptodateService
+import org.lilie.services.eliot.notes.Evaluation
+import org.lilie.services.eliot.notes.Note
+import org.lilie.services.eliot.scolarite.SousService
+import org.lilie.services.eliot.scolarite.TypePeriode
+import org.lilie.services.eliot.notes.scolarite.NotesTypePeriodeService
+import org.lilie.services.eliot.notes.scolarite.NotesPeriodeService
+import org.springframework.context.ApplicationContext
+import org.springframework.context.ApplicationContextAware
+import org.lilie.services.eliot.notes.scolarite.NotesSousServiceService
+import org.lilie.services.eliot.notes.exception.PeriodeVerrouilleException
+import org.lilie.services.eliot.notes.NotesDroitService
+import org.lilie.services.eliot.notes.ActionEnum
+import org.hibernate.exception.ConstraintViolationException
+import org.lilie.services.eliot.annuaire.SecuriteSession
+import org.lilie.services.eliot.notes.utils.NotesHibernateSessionService
+import org.lilie.services.eliot.scolarite.ModaliteMatiere
+import org.lilie.services.eliot.notes.exception.NoteMaxNonValideException
+import org.lilie.services.eliot.notes.exception.NoteMaxSurpasseeException
+import org.lilie.services.eliot.notes.NotesFonction
+
+/**
+ * Service sur les évaluations
+ * @author fsil
+ * @author msan
+ */
+class NotesEvaluationService extends EvaluationService implements ApplicationContextAware {
+
+ static transactional = true
+
+ // ApplicationContext est aussi un service singleton
+ @SuppressWarnings('GrailsStatelessService')
+ ApplicationContext applicationContext
+
+ NotesDroitService notesDroitService
+ NotesEnseignementService notesEnseignementService
+ UptodateService uptodateService
+ NoteService noteService
+ NotesTypePeriodeService notesTypePeriodeService
+ NotesHibernateSessionService notesHibernateSessionService
+
+ /**
+ * Retourne les Evaluations si le service est évaluable pour le type de période
+ * donné et le type équivalent. Les notes sont retournées uniquement pour les
+ * sous-services évaluables.
+ * @author msan
+ * @author bper
+ */
+ List<Evaluation> findAllEvaluations(SecuriteSession securiteSession,
+ Service service,
+ TypePeriode typePeriode,
+ Autorite enseignant,
+ Etablissement etab)
+ throws AutorisationException, IllegalArgumentException {
+
+ notesDroitService.verifieAutorisationByEtablissement(
+ securiteSession,
+ etab,
+ ActionEnum.CONSULTATION,
+ (List) (NotesFonction.ENSEIGNANT_ASSIMILE +
+ NotesFonction.DIRECTION_ASSIMILE
+ )
+ )
+
+ if (typePeriode == null) {
+ throw new IllegalArgumentException(
+ "La valeur null pour le paramètre {typePeriode} n'est pas acceptée"
+ )
+ }
+
+ if (service == null) {
+ throw new IllegalArgumentException(
+ "La valeur null pour le paramètre {service} n'est pas acceptée"
+ )
+ }
+
+ if (enseignant == null) {
+ throw new IllegalArgumentException(
+ "La valeur null pour le paramètre {enseignant} n'est pas acceptée"
+ )
+ }
+
+ Enseignement enseignement = notesEnseignementService.findEnseignement(
+ service,
+ enseignant
+ )
+
+ if (enseignement == null) {
+ throw new IllegalStateException(
+ "Enseignement n'existe pas pour [service: $service enseignant: $enseignant]"
+ )
+ }
+
+ TypePeriode typePeriodeEquiv =
+ notesTypePeriodeService.getTypePeriodeEquivalent(typePeriode)
+
+ // Dans le cas où le service n'est pas évaluable pour les deux types de périodes
+ // retourne liste vide
+ if (!service.isEvaluable(typePeriode)) {
+ if (typePeriodeEquiv) {
+ if (!service.isEvaluable(typePeriodeEquiv)) {
+ return []
+ }
+ } else {
+ return []
+ }
+ }
+
+ // Get evaluations
+ List<Evaluation> evaluations = Evaluation.createCriteria().listDistinct {
+ eq('enseignement', enseignement)
+ periodes {
+ or {
+ eq('typePeriode', typePeriode)
+ if (typePeriodeEquiv) {
+ eq('typePeriode', typePeriodeEquiv)
+ }
+ }
+ }
+ and {
+ order('dateEvaluation', 'asc')
+ order('dateCreation', 'asc')
+ }
+ fetchMode('notes', FetchMode.JOIN)
+ fetchMode('modaliteMatiere', FetchMode.JOIN)
+ }
+
+ // Si l'évaluation est rattachée à un sous-service, on vérifie si le sous-service
+ // est évaluable
+ List<Evaluation> evaluationsEvaluables = []
+ evaluations.each { Evaluation evaluation ->
+ if (evaluation.modaliteMatiere == null) {
+ evaluationsEvaluables << evaluation
+ } else {
+ // get sous-services pour cet évaluation
+ NotesSousServiceService sousServiceService =
+ applicationContext.getBean('notesSousServiceService')
+
+ List<TypePeriode> typePeriodes = [typePeriode]
+ if (typePeriodeEquiv) {
+ typePeriodes << typePeriodeEquiv
+ }
+
+ List<SousService> sousServices = sousServiceService.
+ internalFindAllSousServices(securiteSession,
+ service,
+ evaluation.modaliteMatiere,
+ typePeriodes)
+
+ // l'évaluabilité devrait être pareille pour tout les sous-services
+ if (sousServices.any { it.evaluable }) {
+ evaluationsEvaluables << evaluation
+ }
+ }
+ }
+
+ return evaluationsEvaluables
+ }
+
+ /**
+ * Mis à jour de la moyenne d'évaluation
+ * @param evaluation
+ * @param moyenne
+ * @return évaluation
+ * @author msan
+ */
+ Evaluation internalMAJMoyenne(Evaluation evaluation, BigDecimal moyenne) {
+ evaluation.moyenne = moyenne
+ try {
+ if (!evaluation.save(flush: true)) {
+ throw new SauvegardeEchoueException(evaluation)
+ }
+ } catch (ConstraintViolationException e) {
+ throw new SauvegardeEchoueException(evaluation, e)
+ }
+ return evaluation
+ }
+
+ /**
+ * Crée une évaluation
+ * @param securiteSession
+ * @param params EvaluationParams
+ * @return Evaluation
+ * @author bper
+ */
+ Evaluation creeEvaluation(SecuriteSession securiteSession,
+ EvaluationParams params)
+ throws PeriodeVerrouilleException, NoteMaxNonValideException {
+
+ if (params.typePeriode.isAnnee()) {
+ throw new IllegalArgumentException(
+ "Il n'est pas autorisé de créer une évaluation pour la période \"Année\""
+ )
+ }
+
+ if (params.noteMax != null) {
+ internalVerifieNoteMax(params.noteMax)
+ }
+
+ NotesPeriodeService notesPeriodeService =
+ (NotesPeriodeService) applicationContext.getBean('notesPeriodeService')
+
+ Enseignement enseignement = params.enseignement
+
+ notesDroitService.verifieAutorisationByEnseignement(
+ securiteSession,
+ enseignement,
+ ActionEnum.CREATION,
+ (NotesFonction.ENSEIGNANT_ASSIMILE + NotesFonction.DIRECTION_ASSIMILE).toList()
+ )
+
+ // Périodes
+ List<Periode> periodes =
+ notesPeriodeService.findAllPeriodesByServiceAndTypePeriode(
+ securiteSession,
+ params.enseignement.service,
+ params.typePeriode
+ )
+
+ // La création de l'évaluation est interdite si au moins une période est verrouillée
+ periodes.each {
+ if (it.verrouille) {
+ throw new PeriodeVerrouilleException(it)
+ }
+ }
+
+ Evaluation evaluation = new Evaluation(
+ titre: params.titre,
+ dateEvaluation: params.dateEvaluation,
+ noteMaxPossible: params.noteMax,
+ coefficient: params.coeff,
+ publiable: params.publiable,
+ periodes: periodes,
+ enseignement: enseignement,
+ creeParWebservice: params.creeParWebservice
+ )
+
+ // Modalité de matière
+ evaluation.modaliteMatiere = internalGetModaliteMatiereForEvaluation(
+ params.enseignement.service,
+ params.typePeriode,
+ params.modaliteMatiere)
+
+ if (!evaluation.save(flush: true) || evaluation.hasErrors()) {
+ throw new SauvegardeEchoueException(evaluation)
+ }
+
+ return evaluation
+ }
+
+ /**
+ * Vérifie que la modalité de matière peut être utilisée pour un service et un type de
+ * période. Sinon retourne une autre modalite de matière valide.
+ * @param service
+ * @param typePeriode
+ * @param modaliteMatiere
+ * @return ModaliteMatiere valide
+ */
+ private ModaliteMatiere internalGetModaliteMatiereForEvaluation(Service service,
+ TypePeriode typePeriode,
+ ModaliteMatiere modaliteMatiere) {
+
+ ModaliteMatiere modaliteMatiereValide = null
+
+ NotesSousServiceService sousServiceService =
+ (NotesSousServiceService) applicationContext.getBean('notesSousServiceService')
+
+ // Liste des relations pour le service et le type de période
+ Set<SousService> sousServices =
+ sousServiceService.findAllSousServiceByServiceAndTypePeriode(
+ service,
+ typePeriode,
+ true
+ ) as Set
+
+ List<ModaliteMatiere> modaliteMatieres = sousServices.collect {
+ it.modaliteMatiere
+ }
+
+ if (modaliteMatieres) {
+ if (modaliteMatiere) {
+ modaliteMatiereValide = (ModaliteMatiere) modaliteMatieres.find {
+ it.id == modaliteMatiere.id
+ }
+ }
+
+ if (!modaliteMatiereValide) {
+ modaliteMatiereValide = modaliteMatieres.first()
+ }
+ }
+
+ return modaliteMatiereValide
+ }
+
+ /**
+ * Modifie une évaluation
+ * @param securiteSession
+ * @param params EvaluationParams
+ * @return Evaluation
+ * @author bper
+ */
+ Evaluation modifieEvaluation(SecuriteSession securiteSession,
+ EvaluationParams params)
+ throws AutorisationException,
+ IllegalArgumentException,
+ SauvegardeEchoueException,
+ PeriodeVerrouilleException,
+ NoteMaxNonValideException {
+
+ Evaluation evaluation = params.evaluation
+
+ if (evaluation == null) {
+ throw new IllegalArgumentException(
+ "Le paramètre {params.evaluaion} ne doit etre null"
+ )
+ }
+
+ if (params.noteMax != null && params.noteMax < evaluation.noteMaxSaisie) {
+ throw new NoteMaxSurpasseeException(params.noteMax)
+ }
+
+ if (params.noteMax != null) {
+ internalVerifieNoteMax(params.noteMax)
+ }
+
+ notesDroitService.verifieAutorisationByEnseignement(
+ securiteSession,
+ evaluation.enseignement,
+ ActionEnum.MODIFICATION,
+ (NotesFonction.ENSEIGNANT_ASSIMILE + NotesFonction.DIRECTION_ASSIMILE).toList()
+ )
+
+ // La modififcation de l'évaluation est interdite si au moins une période est verrouillée
+ evaluation.periodes.each {
+ if (it.verrouille) {
+ throw new PeriodeVerrouilleException(it)
+ }
+ }
+
+ // Si l'évolution change sa modalité de matière il faut marquer les moyennes
+ // des sous-services correspondantes à l'ancienne et nouvelle modalité
+ ModaliteMatiere ancienneModaliteMatiere = null
+ if (params.modaliteMatiere != null) {
+ ModaliteMatiere nouvelleModaliteMatiere =
+ internalGetModaliteMatiereForEvaluation(
+ params.evaluation.enseignement.service,
+ params.typePeriode,
+ params.modaliteMatiere
+ )
+
+ if (evaluation.modaliteMatiere.id != nouvelleModaliteMatiere.id) {
+ ancienneModaliteMatiere = evaluation.modaliteMatiere
+ evaluation.modaliteMatiere = nouvelleModaliteMatiere
+ }
+ }
+
+ if (params.titre) {evaluation.titre = params.titre}
+
+ Boolean dateChange = false
+ if (params.dateEvaluation) {
+ dateChange = (evaluation.dateEvaluation != params.dateEvaluation)
+ evaluation.dateEvaluation = params.dateEvaluation
+ }
+
+ Boolean noteMaxChange = false
+ if (params.noteMax != null) {
+ noteMaxChange = (evaluation.noteMaxPossible != params.noteMax)
+ evaluation.noteMaxPossible = params.noteMax
+ }
+
+ Boolean coeffChange = false
+ if (params.coeff != null) {
+ coeffChange = (evaluation.coefficient != params.coeff)
+ evaluation.coefficient = params.coeff
+ }
+
+ if (params.publiable != null) {evaluation.publiable = params.publiable}
+
+ if (!evaluation.save(flush: true) || evaluation.hasErrors()) {
+ throw new SauvegardeEchoueException(evaluation)
+ }
+
+ // si le coeff de l'évaluation existant a changé - il faut recalculer les moyennes
+ if (coeffChange || noteMaxChange || ancienneModaliteMatiere || dateChange) {
+ // invalidate les moyennes correspondantes
+ uptodateService.marqueDirtyEvaluation(
+ securiteSession,
+ evaluation,
+ ancienneModaliteMatiere
+ )
+ }
+
+ return evaluation
+ }
+
+ /**
+ * Verifie que la note maximale n'est pas negative ou zero.
+ * @param noteMax
+ * @throws IllegalArgumentException si la noteMax n'est pas valide
+ */
+ private void internalVerifieNoteMax(BigDecimal noteMax)
+ throws NoteMaxNonValideException {
+ if (noteMax <= 0) {
+ throw new NoteMaxNonValideException(noteMax)
+ }
+ }
+
+ /**
+ * Supprime une évaluation et ses notes
+ * @param evaluation
+ * @param securiteSession
+ * @throws AutorisationException
+ * @throws SuppresionEchoueException
+ * @author bper
+ */
+ void supprimeEvaluation(SecuriteSession securiteSession,
+ Evaluation evaluation)
+ throws AutorisationException,
+ SuppresionEchoueException,
+ IllegalArgumentException {
+
+ if (!evaluation) {
+ throw new IllegalArgumentException(
+ "La paramètre {evaluation} ne doit pas etre null"
+ )
+ }
+
+ // Vérifie autorisation de supprimer évaluation
+ notesDroitService.verifieAutorisationByEnseignement(
+ securiteSession,
+ evaluation.enseignement,
+ ActionEnum.SUPPRESSION,
+ (NotesFonction.ENSEIGNANT_ASSIMILE + NotesFonction.DIRECTION_ASSIMILE).toList()
+ )
+
+ Boolean evalHadNotes = internalEvaluationHasNotes(evaluation)
+ //List<Periode> evalPeriodes = evalHadNotes ? evaluation.periodes.toList() : null
+
+ // Si évaluation avait les notes, il faut recalculer les moyennes
+ if (evalHadNotes) {
+ uptodateService.marqueDirtyEvaluation(securiteSession, evaluation)
+ }
+
+ // Supprime évaluation et les notes en cascade
+ evaluation.delete(flush: true)
+ if (evaluation.hasErrors()) {
+ throw new SuppresionEchoueException(evaluation)
+ }
+
+ }
+
+ /**
+ * Vérifie si l'évaluation a des notes
+ * @param evaluation
+ * @return
+ * @author bper
+ */
+ Boolean internalEvaluationHasNotes(Evaluation evaluation) {
+
+ Note note = (Note) Note.createCriteria().get {
+ eq('evaluation', evaluation)
+ maxResults(1)
+ }
+
+ if (note) {
+ return true
+ } else {
+ return false
+ }
+ }
+
+ /**
+ * Evaluations d'une période avec les notes fetchées.
+ * @param periode
+ * @param seulementMonoperiodeEvals si true, les évaluation qui sont liées
+ * seulement à une période sont retournées
+ * @return Evaluations d'une période avec les notes fetchées
+ * @author msan
+ */
+ List<Evaluation> internalFindAllEvaluationsByPeriode(Periode periode,
+ Boolean seulementMonoperiodeEvals = true) {
+ return Evaluation.createCriteria().listDistinct {
+ periodes {
+ eq('id', periode.id)
+ }
+ if (seulementMonoperiodeEvals) {
+ sizeEq('periodes', 1)
+ }
+ fetchMode('notes', FetchMode.JOIN)
+ }
+ }
+
+ /**
+ * Supprime les évaluation et les notes qui vont avec
+ * @param enseignement
+ * @author msan
+ */
+ void internalSupprimeEvaluations(Enseignement enseignement) {
+ internalSupprimeEvaluations(
+ internalFindAllEvaluationByEnseignement(enseignement)
+ )
+ }
+
+ /**
+ * Supprime les évaluation et les notes qui vont avec
+ * @param sousServices liste des sousServices
+ * @author msan
+ */
+ void internalSupprimeEvaluationsBySousServices(List<SousService> sousServices) {
+ List<Evaluation> evals = []
+ sousServices?.each { SousService sousService ->
+ List<Evaluation> evalsSS =
+ internalFindAllEvaluationBySousService(sousService)
+ if (!evalsSS.isEmpty()) {
+ evals.addAll(evalsSS)
+ }
+ }
+ if (evals.size() > 0) {
+ internalSupprimeEvaluations(evals)
+ }
+ }
+
+ /**
+ * Cherche les évaluations liées à un sous-service
+ * @param sousService
+ * @return les évaluations liées à un sous-service
+ * @author msan
+ */
+ List<Evaluation> internalFindAllEvaluationBySousService(SousService sousService) {
+ return Evaluation.withCriteria {
+ eq('modaliteMatiere', sousService.modaliteMatiere)
+ enseignement {
+ eq('service', sousService.service)
+ }
+ periodes {
+ eq('typePeriode', sousService.typePeriode)
+ }
+ }
+ }
+
+ /**
+ * Supprime les evaluations et les notes qui vont avec
+ * @param evaluations
+ * @author msan
+ */
+ void internalSupprimeEvaluations(List<Evaluation> evaluations) {
+ if (evaluations?.size() > 0) {
+
+ // supprime les notes
+ noteService.internalSupprimeNotes(evaluations)
+
+ // supprime les evaluations +
+ // enlève relations evaluation - période
+ evaluations.each { Evaluation evaluation ->
+ // rattache évaluations après le vidage de cache
+ if (!evaluation.isAttached()) {
+ evaluation = Evaluation.get(evaluation.id)
+ }
+
+ // on fait le get pour eviter ConcurrentModificationException dans le each suivant
+ List<Periode> periodes = evaluation.periodes.collect {
+ Periode.get(it.id)
+ }
+
+ periodes.each { Periode periode ->
+ evaluation.removeFromPeriodes(periode)
+ }
+ }
+
+ // N.B. executeUpdate n'arrive pas à prendre une liste comme un paramètre
+ // de la requête HQL
+ if (evaluations?.size() > 0) {
+ notesHibernateSessionService.prepareExecuteUpdate()
+ Evaluation.withSession { session ->
+ session.createQuery("delete Evaluation e where e in (:evaluations)").
+ setParameterList('evaluations', evaluations).executeUpdate()
+ }
+ }
+ }
+ }
+
+ /**
+ * Liste des evaluations d'un enseignement
+ * @param ens
+ * @return
+ */
+ List<Evaluation> internalFindAllEvaluationByEnseignement(Enseignement ens) {
+ return Evaluation.withCriteria {
+ enseignement {
+ eq('service', ens.service)
+ eq('enseignant', ens.enseignant)
+ }
+ }
+ }
+
+ /**
+ * Retourne la liste des évaluations pour un enseignement et une liste des périodes
+ * @param enseignement
+ * @param listePeriodes
+ * @return List < Evaluation >
+ * @author bper
+ */
+ List<Evaluation> internalFindAllEvaluationByEnseignementAndPeriode(Enseignement enseignement,
+ List<Periode> listePeriodes) {
+ return Evaluation.createCriteria().listDistinct {
+ eq('enseignement', enseignement)
+ periodes {
+ 'in'('id', listePeriodes*.id)
+ }
+ }
+ }
+
+ /**
+ * Total des evaluations pour les enseignements données
+ * @param enseignements
+ * @return
+ * @author msan
+ */
+ Long internalCompteEvaluationsByEnseignement(List<Enseignement> enseignements) {
+ Long evalCount = Evaluation.createCriteria().get {
+ 'in'('enseignement', enseignements)
+ projections {
+ count('id')
+ }
+ }
+
+ return evalCount
+ }
+
+ /**
+ * Cherche s'il y a des évaluations pour les sous-services données
+ * @param enseignements
+ * @return
+ * @author msan
+ */
+ Boolean internalExistentEvaluationsBySousServices(List<SousService> sousServices) {
+ Boolean evalsExistent = false
+ for (int i = 0; i < sousServices.size() && !evalsExistent; i++) {
+ if (!internalFindAllEvaluationBySousService(sousServices.get(i)).isEmpty()) {
+ evalsExistent = true
+ }
+ }
+ return evalsExistent
+ }
+
+ /**
+ * Ajoute la période dans la relation de l'évaluation. Vérifie si la période
+ * est rattachée au service de l'évaluation.
+ * @param evaluation
+ * @param periode
+ *
+ */
+ void internalRattachePeriode(Evaluation evaluation, Periode periode) {
+
+ // La période est bloquée
+ if (periode.verrouille) {
+ return
+ }
+
+ // L'évoluation a déjà cette periode
+ if (evaluation.periodes.find {it.id == periode.id}) {
+ return
+ }
+
+ // Vérifie que la période est rattachée au service
+ if (!evaluation.enseignement.service.relPeriodeServices.find {it.periode.id == periode.id}) {
+ throw new IllegalArgumentException(
+ "La periode [$periode] n'est pas rattachée au service " +
+ "[${evaluation.enseignement.service}]"
+ )
+ }
+
+ // Rattache la periode à l'évaluation
+ evaluation.addToPeriodes(periode)
+ if (!evaluation.save(flush: true)) {
+ throw new SauvegardeEchoueException(evaluation)
+ }
+ }
+
+ /**
+ * Attache les évaluations du service pour typePeriode donnée à la modalité matière
+ * @param service
+ * @param modaliteMatiere
+ * @param typePeriode
+ * @author msan
+ */
+ void internalRattacheEvaluationsAModaliteMatiere(Service service,
+ ModaliteMatiere modaliteMatiere,
+ TypePeriode typePeriode) {
+ // get evals
+ List<Evaluation> evalsABasculer = Evaluation.withCriteria {
+ periodes {
+ eq('typePeriode', typePeriode)
+ }
+ enseignement {
+ eq('service.id', service.id)
+ }
+ }
+ // attache evals
+ if (evalsABasculer?.size() > 0) {
+ notesHibernateSessionService.prepareExecuteUpdate()
+ Evaluation.withSession { session ->
+ session.createQuery("update Evaluation e set modaliteMatiere = :modaliteMatiere where e in (:evaluations)").
+ setParameterList('evaluations', evalsABasculer).
+ setParameter('modaliteMatiere', modaliteMatiere).
+ executeUpdate()
+ }
+ }
+ }
+
+ /**
+ * Supprime toutes les évaluations
+ */
+ void internalSupprimeToutes() {
+ Evaluation.withSession { session ->
+ session.createQuery("delete Evaluation e").executeUpdate()
+ }
+ }
+
+}
\ No newline at end of file