--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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>.
+ -->
+
+<databaseChangeLog
+ xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd">
+
+ <changeSet id="1" author="bper">
+ <comment>
+ Ajout de la colonne 'mode_calcul_note' dans dans la table 'entnotes.brevet_epreuve'
+ </comment>
+
+ <addColumn schemaName="entnotes" tableName="brevet_epreuve">
+ <column name="mode_calcul_note" type="varchar(32)" defaultValue="PREMIERE_TROUVEE"/>
+ </addColumn>
+
+ <sql>
+ UPDATE entnotes.brevet_epreuve
+ SET personnalisable = false, mode_calcul_note = 'MOYENNE'
+ WHERE libelle = 'PREMIERE LANGUE VIVANTE'
+ AND serie_id IN (
+ SELECT id FROM entnotes.brevet_serie
+ WHERE libelle_court LIKE 'Professionnelle%'
+ )
+ </sql>
+
+ </changeSet>
+
+</databaseChangeLog>
import org.lilie.services.eliot.notes.resultat.CalculationService\r
import org.lilie.services.eliot.scolarite.anneescolaire.AnneeScolaireService\r
import org.lilie.services.eliot.brevet.BrevetFiche\r
+import org.lilie.services.eliot.brevet.BrevetModeCalculNote\r
\r
/**\r
* Gestion des notes de brevet\r
List<EpreuveInfo> epreuveInfos,\r
Personne eleve,\r
Periode periode) {\r
- List<Service> services = epreuveInfos.collect { it.services }.flatten().\r
+ List<Service> services = (List) epreuveInfos.collect { it.services }.flatten().\r
findAll { it != null }.unique { it.id }\r
\r
Map<Service, List<String>> apps =\r
)\r
\r
epreuveInfos.each { EpreuveInfo epreuveInfo ->\r
- if (epreuveInfo.services?.size()>0) {\r
- List<String> appsEpreuve = epreuveInfo.services.collect { Service service ->\r
+ if (epreuveInfo.services?.size() > 0) {\r
+ List<String> appsEpreuve = (List) epreuveInfo.services.collect { Service service ->\r
List<String> serviceApps = apps.get(service)\r
- if (serviceApps?.size()>0) {\r
+ if (serviceApps?.size() > 0) {\r
return serviceApps\r
} else {\r
return []\r
}\r
}.flatten().findAll { it != null }\r
- if (appsEpreuve?.size()>0) {\r
+ if (appsEpreuve?.size() > 0) {\r
// scotche les appreciations\r
epreuveInfo.appreciation = appsEpreuve.join(' ')\r
}\r
}\r
\r
/**\r
- * Ajoute les moyennes dans epreuveInfos\r
+ * Ajoute les moyennes dans epreuveInfos.\r
+ * Re-initialise les listes des matières et des services en fonction des moyennes utilisées.\r
+ * On ne garde que les matières et les services pour lesquels les moyennes ont été trouvées.\r
* @author msan\r
+ * @author bper\r
*/\r
void internalAjouteInfoMoyennes(SecuriteSession securiteSession,\r
List<EpreuveInfo> epreuveInfos,\r
Personne eleve,\r
Periode periode) {\r
\r
- List<Service> services = epreuveInfos.collect { it.services }.flatten().\r
+ List<Service> services = (List) epreuveInfos.collect { it.services }.flatten().\r
findAll { it != null }.unique { it.id }\r
\r
List<ResultatEleveServicePeriode> resultats = resultatEleveServicePeriodeService.\r
[NaturePeriodeEnum.NOTATION]\r
)\r
\r
- epreuveInfos.each { EpreuveInfo epreuveInfo ->\r
- List<Service> epreuveServices = epreuveInfo.services\r
- if (epreuveServices?.size()>0) {\r
- List<ResultatEleveServicePeriode> epreuveResultats = resultats.findAll {\r
- epreuveServices*.id.contains(it.service.id)\r
- }\r
- if (epreuveResultats.size()==1) {\r
- epreuveInfo.moyenne = epreuveResultats.first().moyenne\r
- } else {\r
- epreuveInfo.moyenne = internalCalculeMoyenneResultats(\r
- epreuveResultats,\r
- periode)\r
- }\r
+ resultats = (List) resultats.findAll {it.moyenne != null}\r
+ List<Service> serviceAvecMoyennes = resultats*.service\r
+\r
+ if (resultats.size() == 0) {\r
+ epreuveInfos*.matieres = []\r
+ epreuveInfos*.services = []\r
+ return\r
+ }\r
+\r
+ Map resultatsParMatiere = resultats.groupBy {it.service.matiere}\r
+\r
+ Map moyenneParMatiere = [:]\r
+\r
+ // Calcule les moyennes des matères. Si une matières correspond à plusieurs services,\r
+ // on calcule la moyenne des moyennes des services pondérée par les coeffs\r
+ // des services pour la période donnée .\r
+ resultatsParMatiere.each {Matiere matiere, List<ResultatEleveServicePeriode> ress ->\r
+ BigDecimal moyenne = ress.size() == 1 ? \r
+ ress.first().moyenne : internalCalculeMoyenneResultats(ress, periode)\r
+\r
+ moyenneParMatiere.put(matiere, moyenne)\r
+ }\r
+\r
+ epreuveInfos.each {EpreuveInfo epreuveInfo ->\r
+ Map moyenneParMatierePourEpreuve =\r
+ (Map) moyenneParMatiere.findAll {Matiere matiere, BigDecimal moyenne ->\r
+ epreuveInfo.matieres*.id.contains(matiere.id)\r
+ }\r
+\r
+ if (moyenneParMatierePourEpreuve.size() == 0) {\r
+ epreuveInfo.matieres = []\r
+ epreuveInfo.services = []\r
+ return\r
+ }\r
+\r
+ switch (epreuveInfo.epreuve.modeCalculNote) {\r
+ case BrevetModeCalculNote.PREMIERE_TROUVEE :\r
+ Matiere matiere = (Matiere) moyenneParMatierePourEpreuve.keySet().toList().first()\r
+ epreuveInfo.moyenne = (BigDecimal) moyenneParMatierePourEpreuve.get(matiere)\r
+ epreuveInfo.matieres = [matiere]\r
+ break\r
+\r
+ case BrevetModeCalculNote.MOYENNE :\r
+ List<BigDecimal> moyennes = (List<BigDecimal>) moyenneParMatierePourEpreuve.values().toList()\r
+ epreuveInfo.moyenne = calculationService.calculeMoyenne(moyennes, true)?.valeurNumerique\r
+ epreuveInfo.matieres = moyenneParMatierePourEpreuve.keySet().toList()\r
+ break\r
+\r
+ default: \r
+ throw new IllegalStateException(\r
+ "Le mode de calcul de note ${epreuveInfo.epreuve.modeCalculNote} " +\r
+ "pour l'épreuve ${epreuveInfo.epreuve} n'est pris en compte")\r
+ }\r
+\r
+ epreuveInfo.services = (List) serviceAvecMoyennes.findAll {\r
+ epreuveInfo.matieres.contains(it.matiere)\r
}\r
}\r
}\r
/**\r
* Ajoute la correspondence entre les epreuves et les services dans epreuve info\r
* @author msan\r
+ * @author bper\r
*/\r
void internalAjouteInfoServices(SecuriteSession securiteSession,\r
List<EpreuveInfo> epreuveInfos,\r
Personne eleve,\r
Periode periode) {\r
- List<Matiere> matieres = epreuveInfos.collect { it.matiere }.\r
- findAll { it != null }.toList()\r
+\r
+ List<Matiere> matieres = epreuveInfos*.matieres.flatten().toList()\r
\r
// get services\r
List<Service> services = notesServiceService.\r
- internalFindAllServiceByElevePeriodeMatieres(\r
+ internalFindAllServiceByElevePeriodeMatieres( \r
securiteSession,\r
eleve,\r
periode,\r
matieres\r
)\r
\r
- services.each { Service service ->\r
-\r
- // on peut avoir HiGeo + EduCivic lies a la meme matiere/service\r
- epreuveInfos.findAll {\r
- it.matiere?.id == service.matiere.id\r
- }.each { EpreuveInfo epreuveInfo ->\r
- List<Service> serviceList = epreuveInfo.services?:[]\r
- serviceList.add(service)\r
- epreuveInfo.services=serviceList\r
+ // Affecte les services en fonction des matières affectées\r
+ services.each {Service service ->\r
+ epreuveInfos.each {EpreuveInfo epreuveInfo ->\r
+ if (epreuveInfo.matieres*.id.contains(service.matiere.id)) {\r
+ epreuveInfo.services.add(service)\r
+ }\r
}\r
-\r
}\r
}\r
\r
/**\r
* Cherche les matieres correspondant a une epreuve pour un eleve donne\r
* @author msan\r
+ * @author bper\r
*/\r
List<EpreuveInfo> internalChercheMatieres(SecuriteSession securiteSession,\r
List<BrevetEpreuve> epreuves,\r
Boolean initialisation) {\r
List<EpreuveInfo> epreuveInfos = []\r
notes.each { BrevetNote note ->\r
- Matiere matiere = internalChercheMatiere(\r
+ List<Matiere> matieres = internalChercheMatiere(\r
securiteSession,\r
note.epreuve,\r
eleve,\r
)\r
epreuveInfos.add(new EpreuveInfo(\r
epreuve: note.epreuve,\r
- matiere: matiere\r
+ matieres: matieres\r
))\r
}\r
return epreuveInfos\r
/**\r
* Cherche le matiere correspondant a une epreuve pour un eleve donne\r
* @author msan\r
+ * @author bper\r
*/\r
- private Matiere internalChercheMatiere(SecuriteSession securiteSession,\r
- BrevetEpreuve epreuve,\r
- Personne eleve,\r
- Etablissement etablissement,\r
- List<BrevetRelEpreuveMatiere> relFixes,\r
- BrevetNote note,\r
- Periode periodeAnnee,\r
- Boolean initialisation) {\r
+ private List<Matiere> internalChercheMatiere(SecuriteSession securiteSession,\r
+ BrevetEpreuve epreuve,\r
+ Personne eleve,\r
+ Etablissement etablissement,\r
+ List<BrevetRelEpreuveMatiere> relFixes,\r
+ BrevetNote note,\r
+ Periode periodeAnnee,\r
+ Boolean initialisation) {\r
List<Matiere> matieres = null\r
\r
if (epreuve.personnalisable) {\r
}?.collect { it.matiere }\r
}\r
\r
- if (matieres == null || matieres.size()==0) {\r
- return null\r
- } else {\r
- // si on a plusieurs matieres, on prend la premiere\r
- return matieres.first()\r
- }\r
+ return matieres\r
}\r
\r
/**\r
[NaturePeriodeEnum.NOTATION]\r
)\r
\r
- resultats = resultats.findAll {it.moyenne != null}\r
+ resultats = (List) resultats.findAll {it.moyenne != null}\r
\r
if (resultats?.size()>0) {\r
return resultats.first().service.matiere\r
BrevetNote note3 = creeBrevetNote(eleve1, epreuve3, 3, 'zuzu')\r
\r
// cree le resultat 13 pour service 1\r
- creeResultat(eleve1, service1, 13)\r
+ ResultatEleveServicePeriode resService1 = creeResultat(eleve1, service1, 13)\r
\r
- // cree l'appreciation pour service 2\r
- creeAppreciation(eleve1, enseignement2, 'bubu')\r
+ // cree l'appreciation pour les services 1 et 2\r
+ AppreciationEleveEnseignementPeriode apprService1 =\r
+ creeAppreciation(eleve1, enseignement1, 'bien')\r
\r
- // cree rien pour epreuve 3\r
+ AppreciationEleveEnseignementPeriode apprService2 =\r
+ creeAppreciation(eleve1, enseignement2, 'pas mal')\r
\r
List<BrevetNoteInfo> notes = brevetNoteService.actualiseNotes(\r
securiteSessionDirection,\r
)\r
\r
BrevetNoteInfo note1changee = notes.find { it.noteId == note1.id }\r
- BrevetNoteInfo note2changee = notes.find { it.noteId == note2.id }\r
\r
- // notes de service 1 et service 2\r
+ // Une seule note doit etre mise à jour car il existe une seul moyenne.\r
+ // Les appréciation ne sont récupérées que dans le cas il exite une moyenne\r
+ // pour le service correspondant.\r
assertEquals(\r
"Le nombre des notes trouvees n'est pas comme attendu",\r
- 2,\r
+ 1,\r
notes.size()\r
)\r
+\r
assertEquals(\r
"La note trouve n'est pas comme prevue",\r
- 13,\r
+ resService1.moyenne,\r
note1changee.valeurNumerique\r
)\r
+\r
assertEquals(\r
"L'appreciation trouve n'est pas comme prevue",\r
- 'susu',\r
+ apprService1.appreciation,\r
note1changee.appreciation\r
)\r
- assertEquals(\r
- "La note trouve n'est pas comme prevue",\r
- 2,\r
- note2changee.valeurNumerique\r
- )\r
- assertEquals(\r
- "L'appreciation trouve n'est pas comme prevue",\r
- 'bubu',\r
- note2changee.appreciation\r
- )\r
}\r
\r
/**\r
\r
/**\r
* Cree une appreciation d'un eleve et d'un enseignement\r
- * @param eleve\r
- * @param enseignement\r
- * @param appreciation\r
*/\r
- void creeAppreciation(Personne eleve, Enseignement enseignement, String appreciation) {\r
- AppreciationEleveEnseignementPeriode apr =\r
+ AppreciationEleveEnseignementPeriode creeAppreciation(Personne eleve,\r
+ Enseignement enseignement,\r
+ String appreciation) {\r
+ AppreciationEleveEnseignementPeriode appr =\r
appreciationEleveEnseignementPeriodeService.internalFindOrCree(\r
eleve.autorite,\r
enseignement,\r
periodeAnnee\r
)\r
- apr.appreciation = appreciation\r
- apr.save()\r
+ appr.appreciation = appreciation\r
+ appr.save()\r
+ \r
+ return appr\r
}\r
\r
/**\r
* Cree un resultat d'eleve pour un service\r
- * @param eleve\r
- * @param service\r
- * @param note\r
*/\r
- void creeResultat(Personne eleve, Service service, BigDecimal note) {\r
+ ResultatEleveServicePeriode creeResultat(Personne eleve, Service service, BigDecimal note) {\r
ResultatEleveServicePeriode res = resultatEleveServicePeriodeService.\r
internalFindOrCree(\r
eleve.autorite,\r
)\r
res.moyenne = note\r
res.save()\r
+ \r
+ return res\r
}\r
\r
/**\r
\r
/**\r
* Cree une note de brevet\r
- * @param securiteSession\r
- * @param eleve\r
- * @param epreuve\r
- * @param note\r
- * @param appreciation\r
- * @return\r
*/\r
private BrevetNote creeBrevetNote(Personne eleve,\r
BrevetEpreuve epreuve,\r