return result
}
-
EffectifsClasseGroupe findEffectifsClasseGroupe(List<StructureEnseignement> classes) {
List<StructureEnseignement> structures = classes + classes*.groupes.flatten()
private final Integer numero
private final String codeMessage
+ private final static Calendar calendar = Calendar.getInstance()
private Mois(Integer numero, String codeMessage) {
this.numero = numero
mois.numero == numero
}
}
+
+ static Mois parseByDate(Date date){
+ calendar.setTime(date)
+ return parseByNumero(calendar.get(Calendar.MONTH) + 1)
+ }
}
\ No newline at end of file
modele.put(k, (v as JSON))
}
- List<Motif> motifDefauts = motifService.findAllMotifForPriseEnCompteMotif(
- pref,
- PriseEnCompteMotif.STATS,
- false
- )
- List selectionParDefautIds = motifDefauts*.id
-
- List<Motif> motifDisponibles = motifService.getMotifsForPreferencesEtablissement(pref)
Map mapParams = [:]
if (params.params) {
mapParams = (Map) JSON.parse(params.params)
-
Map<String, Object> datasTempsReel =
construitDatasTempsReel(parseParams(mapParams))
modele.paramsTempsReel = params.params
modele.datasTempsReel = datasTempsReel as JSON
-
- if (mapParams.groupesMotif) {
- List groupeMotifIds = mapParams.groupesMotif.split(',').toList()
- if (!groupeMotifIds.contains('-1')) {
- motifDisponibles = getMotifs(groupeMotifIds)
- modele.dataMotifs = parseDataForJSON(motifDisponibles) as JSON
- selectionParDefautIds.retainAll(motifDisponibles*.id)
- }
- }
- }
-
- modele.selectionMotifsDefautCoche = mapParams.isSelectionParDefautChecked == null ?
- true :
- mapParams.isSelectionParDefautChecked
-
- //Si la liste est vide
- if (!modele.dataMotifs) {
- modele.dataMotifs = getAllMotifs(false) as JSON
- }
-
- modele.motifIdsDefaut = selectionParDefautIds.join(',')
-
- if (motifDisponibles.size() == selectionParDefautIds.size()) {
- if (modele.motifIdsDefaut) {
- modele.motifIdsDefaut = '-1,' + modele.motifIdsDefaut
- } else {
- modele.motifIdsDefaut = '-1'
- }
}
+ modele += prepareModeleMotifs(pref, mapParams)
}
render(
)
}
- /**
- * @param liste1
- * @param liste2
- * @return true si les listes d'ids sont identiques
- */
- private Boolean listeIdentiques(String liste1, String liste2) {
- List l1 = liste1.split(',')
- List l2 = liste2.split(',')
- return l1.sort() == l2.sort()
+ private Map prepareModeleMotifs(
+ PreferencesEtablissementAbsences pref,
+ Map mapParams
+ ) {
+ Map modeleMotif = [:]
+ List<Motif> motifDefauts = motifService.findAllMotifForPriseEnCompteMotif(
+ pref,
+ PriseEnCompteMotif.STATS,
+ false
+ )
+ List selectionParDefautIds = motifDefauts*.id
+
+ List<Motif> motifDisponibles = motifService.getMotifsForPreferencesEtablissement(pref)
+ if (mapParams.groupesMotif) {
+ List groupeMotifIds = mapParams.groupesMotif.split(',').toList()
+ if (!groupeMotifIds.contains('-1')) {
+ motifDisponibles = getMotifs(groupeMotifIds)
+ modeleMotif.dataMotifs = parseDataForJSON(motifDisponibles) as JSON
+ selectionParDefautIds.retainAll(motifDisponibles*.id)
+ }
+ }
+
+ modeleMotif.selectionMotifsDefautCoche = mapParams.isSelectionParDefautChecked == null ?
+ true :
+ mapParams.isSelectionParDefautChecked
+
+ //Si la liste est vide
+ if (!modeleMotif.dataMotifs) {
+ modeleMotif.dataMotifs = getAllMotifs(false) as JSON
+ }
+
+ modeleMotif.motifIdsDefaut = selectionParDefautIds.join(',')
+
+ if (motifDisponibles.size() == selectionParDefautIds.size()) {
+ if (modeleMotif.motifIdsDefaut) {
+ modeleMotif.motifIdsDefaut = '-1,' + modeleMotif.motifIdsDefaut
+ } else {
+ modeleMotif.motifIdsDefaut = '-1'
+ }
+ }
+
+ return modeleMotif
}
private Map construitDatasTempsReel(
import org.lilie.services.eliot.absences.PreferencesEtablissementAbsences
import org.lilie.services.eliot.parametrages.calendrier.PlageHoraireService
+import org.lilie.services.eliot.absences.statistiques.mensuelle.StatsMensuellesParams
+import org.lilie.services.eliot.absences.TauxAbsencesCalculMode
+import org.lilie.services.eliot.absences.statistiques.volumehoraire.EvenementsAllStructuresParMois
+import org.lilie.services.eliot.temps.Mois
+import org.lilie.services.eliot.absences.statistiques.volumehoraire.EvenementsUneStructureParMois
+
+import org.lilie.services.eliot.absences.statistiques.volumehoraire.VolumesAllStructureEnseignements
+import org.lilie.services.eliot.absences.statistiques.volumehoraire.VolumeMensuel
+import org.lilie.services.eliot.absences.statistiques.CalendrierAbsencesService
+import org.lilie.services.eliot.absences.statistiques.mensuelle.PeriodeMensuelle
+import org.lilie.services.eliot.absences.statistiques.volumehoraire.VolumesUneStructureEnseignement
+
/**
* Permet de manipuler des informations d'emploi du temps
* @author othe
LocalStructureEnseignementService localStructureEnseignementService
LocalPersonneService localPersonneService
PlageHoraireService plageHoraireService
+ CalendrierAbsencesService calendrierAbsencesService
/**
* @param securiteSession
ChronologieEvenement chronologieEvenement = construitChronologieEvenement(
pref,
- allEvenement,
- pasDecompte)
+ allEvenement)
switch (pasDecompte) {
*/
private ChronologieEvenement construitChronologieEvenement(
PreferencesEtablissementAbsences pref,
- List<Evenement> allEvenement,
- String pasDecompte) {
+ List<Evenement> allEvenement) {
List<PlageHoraire> plages = plageHoraireService.getPlageHoraires(pref)
)
}
+
+ /**
+ * Calcule les volumes horaires mensuels d'une liste de structure d'enseignements
+ * @param criteres
+ * @param pref
+ * @return une VolumesAllStructureEnseignements
+ */
+ VolumesAllStructureEnseignements getVolumeHoraireStructures(
+ SecuriteSession securiteSession,
+ PreferencesEtablissementAbsences pref,
+ StatsMensuellesParams criteres,
+ List<PeriodeMensuelle> periodeMensuelles
+ ) {
+ if (pref.tauxAbsencesCalculMode == TauxAbsencesCalculMode.NB_COURS_REEL_EDT) {
+ return getVolumeHoraireStructuresAvecEmploiDuTemps(criteres, pref)
+ } else {
+ return getVolumeHoraireStructureAvecCalendrier(
+ securiteSession,
+ pref,
+ criteres,
+ periodeMensuelles
+ )
+ }
+ }
+
+ /**
+ * Retourne le volume horaire mensuels par structure d'enseignement selon
+ * le calendrier de l'établissement
+ * @param criteres
+ * @return VolumesAllStructureEnseignements
+ */
+ private VolumesAllStructureEnseignements getVolumeHoraireStructureAvecCalendrier(
+ SecuriteSession securiteSession,
+ PreferencesEtablissementAbsences pref,
+ StatsMensuellesParams criteres,
+ List<PeriodeMensuelle> periodeMensuelles
+ ) {
+ VolumesAllStructureEnseignements result = new VolumesAllStructureEnseignements()
+ List<StructureEnseignement> structureEnseignements =
+ localStructureEnseignementService.findAllStructureForAllIds(
+ criteres.structIds
+ )
+
+ Map<Mois, Double> volumeParMois = [:]
+ periodeMensuelles.each {
+ PeriodeMensuelle periodeMensuelle ->
+ volumeParMois.put(
+ periodeMensuelle.mois,
+ calendrierAbsencesService.countPasDeDecompteOuvertSurPeriode(
+ securiteSession,
+ periodeMensuelle.dateDebut,
+ periodeMensuelle.dateFin,
+ pref
+ )
+ )
+ }
+
+ /**
+ * Affecte pour chaque structure et chaque mois, le volume mensuel du
+ * calendrier pour le mois donné
+ */
+ structureEnseignements.each {
+ StructureEnseignement structureEnseignement ->
+ VolumesUneStructureEnseignement volumesStructure = result.
+ findOrCreateVolumesForStructure(structureEnseignement)
+ volumeParMois.each {
+ Mois mois, Double volume ->
+ volumesStructure.findOrCreateVolumeMensuelle(mois).volumeHeure = volume
+ }
+ }
+ return result
+ }
+
+ /**
+ * Calcule les volumes horaires mensuel des structures selon l'emploi du temps
+ * @param criteres
+ * @return VolumesAllStructureEnseignements
+ */
+ private VolumesAllStructureEnseignements getVolumeHoraireStructuresAvecEmploiDuTemps(
+ StatsMensuellesParams criteres,
+ PreferencesEtablissementAbsences pref) {
+
+ VolumesAllStructureEnseignements result = new VolumesAllStructureEnseignements()
+
+ //Récupère les événements les structures
+ EvenementsAllStructuresParMois evenementsAllStructuresParMois =
+ findEvenementsAllStructureParMois(criteres)
+
+ //Pour chaque structure d'enseignement
+ evenementsAllStructuresParMois.eachStructureEnseignement {
+ StructureEnseignement structureEnseignement ->
+
+ EvenementsUneStructureParMois evenementsUneStructureParMois =
+ evenementsAllStructuresParMois.findOrCreateEvenementStructure(
+ structureEnseignement
+ )
+ //Pour chaque mois
+ evenementsUneStructureParMois.evenementParMois.each {
+ Mois mois, List<Evenement> evenements ->
+ ChronologieEvenement chronologieEvenement = new ChronologieEvenement(
+ pref.plageHoraires.toList(),
+ evenements
+ )
+
+ VolumeMensuel volumeMensuel = result.findOrCreateVolumesForStructure(
+ structureEnseignement
+ ).findOrCreateVolumeMensuelle(mois)
+
+ switch (pref.pasDecompte) {
+ case PreferencesEtablissementAbsences.DECOMPTE_HEURE:
+ volumeMensuel.volumeHeure += chronologieEvenement.plageHoraireCount *
+ pref.longueurPlage
+ break
+ case PreferencesEtablissementAbsences.DECOMPTE_DEMIJOUR:
+ volumeMensuel.volumeHeure += chronologieEvenement.demiJourneeCount
+ break
+ case PreferencesEtablissementAbsences.DECOMPTE_JOUR:
+ volumeMensuel.volumeHeure += chronologieEvenement.journeeCount
+ break
+ }
+ }
+ }
+ return result
+ }
+
+ private EvenementsAllStructuresParMois findEvenementsAllStructureParMois(
+ StatsMensuellesParams criteres) {
+ Set<StructureEnseignement> structureEnseignements =
+ localStructureEnseignementService.findAllStructureForAllIds(criteres.structIds)
+
+ //On ajoute les groupes associés aux classes
+ structureEnseignements += structureEnseignements*.groupes.flatten()
+
+ EvenementsAllStructuresParMois result = new EvenementsAllStructuresParMois()
+ List<Evenement> evenements = findAllEvenementForAllStructureEnseignementAndDates(
+ structureEnseignements.toList(),
+ criteres.dateDebut.getTime(),
+ criteres.dateFin.getTime()
+ )
+
+ evenements.each {
+ Evenement evenement ->
+ result.findOrCreateEvenementStructure(
+ evenement.enseignement.service.structureEnseignement
+ ).addEvenementMois(evenement, Mois.parseByDate(evenement.dateHeureDebut))
+ }
+ return result
+ }
}
Date fin = DateUtil.getHeure(evenement.dateHeureFin)
plages.each {PlageHoraire plageHoraire ->
- if ((fin >= plageHoraire.debut) && (debut <= plageHoraire.fin)) {
+ if (!(fin <= plageHoraire.debut) && !(debut >= plageHoraire.fin)) {
allPlageHoraire << plageHoraire
}
}
PreferencesEtablissementAbsencesService preferencesEtablissementAbsencesService
AppelLigneService appelLigneService
-
/**
* Enregistre en base les données de l'absence journée et retourne les
* AbsenceJourneeLigneInfo correspondant aux AppelLigne créées
* @return une List<AbsenceJourneeLigneInfo>
*/
List<AbsenceJourneeLigneInfo> enregistreAbsenceJournee(
- SecuriteSession securiteSession,
- AbsenceJourneeParams params) throws AutorisationException {
+ SecuriteSession securiteSession,
+ AbsenceJourneeParams params) throws AutorisationException {
List<AbsenceJourneeLigneInfo> result = []
droitsService.verifieDroitsCRUDAbsenceJournee(
securiteSession,
}
private void internalSupprimeLignesAbsenceJournee(
- List<AbsenceJourneeLigneParams> absenceJourneeLigneParams) {
+ List<AbsenceJourneeLigneParams> absenceJourneeLigneParams) {
absenceJourneeLigneParams.each {
if (it.appelLigne.appel) {
it.appelLigne.appel.appelLignes.remove(it.appelLigne)
}
private void internalModifieLignesAbsenceJournee(
- List<AbsenceJourneeLigneParams> absenceJourneeLigneParams) {
+ List<AbsenceJourneeLigneParams> absenceJourneeLigneParams) {
absenceJourneeLigneParams.each {
AbsenceJourneeLigneParams ligne ->
Date finJournee = cal.getTime()
PreferencesEtablissementAbsences preferences =
- preferencesEtablissementAbsencesService.getPreferencesEtablissementForEtablissement(sanction.etablissement)
+ preferencesEtablissementAbsencesService.getPreferencesEtablissementForEtablissement(sanction.etablissement)
AbsenceJournee absenceJournee = findOrCreateAbsenceJournee(
sanction.etablissement,
* @return un AbsenceJourneeInfo
*/
AbsenceJourneeInfo findAbsencesJourneeForJourAndStructure(
- Date jour,
- StructureEnseignement structure) {
+ Date jour,
+ StructureEnseignement structure) {
Calendar cal = Calendar.getInstance()
cal.setTime(jour)
*/
AbsenceJournee findOrCreateAbsenceJournee(Etablissement etablissement,
Date jour,
- PreferencesEtablissementAbsences preferences )
+ PreferencesEtablissementAbsences preferences)
throws AbsenceJourneeChampObligatoireException {
AbsenceJournee absenceJournee = findAbsenceJournee(
etablissement,
* @param numJour : le numéro du jour de la semaine
*/
private List<AbsenceJourneeLigneInfo> internalCreeLignesAbsenceJournee(
- AbsenceJournee absenceJournee,
- List<AbsenceJourneeLigneParams> lignes,
- Byte numJour
+ AbsenceJournee absenceJournee,
+ List<AbsenceJourneeLigneParams> lignes,
+ Byte numJour
) {
List<AbsenceJourneeLigneInfo> result = []
lignes.each {
* @return une List<AbsenceJourneeLigneInfo>
*/
List<AbsenceJourneeLigneInfo> internalCreeLignesAppel(
- List<AbsenceJourneeLigneParams> lignes,
- Byte numJour
+ List<AbsenceJourneeLigneParams> lignes,
+ Byte numJour
) {
List<AbsenceJourneeLigneInfo> result = []
lignes.each {
* @return une AppelLigne
*/
private AppelLigne getAppelLigneFromAbsenceJourneeLigneInfo(
- AbsenceJourneeLigneParams ligne) {
+ AbsenceJourneeLigneParams ligne) {
AppelLigne appelLigne = new AppelLigne(
presence: ligne.presence,
retard: ligne.retard,
date: absenceJourneeParams.date,
preferencesEtablissementAbsences: absenceJourneeParams.preferencesEtablissementAbsences
)
-
+
absenceJournee.save(flush: true, failOnError: true)
return absenceJournee
return absenceJournee
}
- //TODOC
-
+ /**
+ * Extrait les données d'absences d'un élève depuis une liste d'absences
+ * hors appel (absences journées)
+ * @param absenceJourneeInfo : liste d'absences journées
+ * @param autorite : élève dont on veut extraire les absences
+ * @param plageHoraires : plages horaires de l'étab
+ * @return une liste d'AbsenceJourneeEleveInfo
+ */
List<AbsenceJourneeEleveInfo> getAbsenceJourneeForEleve(
- AbsenceJourneeInfo absenceJourneeInfo,
- Autorite autorite,
- List<PlageHoraire> plageHoraires) {
+ AbsenceJourneeInfo absenceJourneeInfo,
+ Autorite autorite,
+ List<PlageHoraire> plageHoraires) {
+
List<AbsenceJourneeEleveInfo> result = []
//on récupère les lignes concernant l'élève
List<AbsenceJourneeEleveInfo> absenceJourneeEleve = absenceJourneeInfo.
abstractAppelLigneInfo.motifId = appelLigne.motif.id
}
- //TODOC
-
+ /**
+ * Extrait les informations d'absence d'un élève depuis une liste d'AppelLigne
+ * avec les informations d'accessibilité (modifiable ou non)
+ * @param appelLignesEleve : la liste de départ
+ * @param eleve : l'élève dont on veut extraire les lignes
+ * @param isCpeOuDirecteur : fonction de celui qui consulte
+ * @param securiteSession
+ * @param etablissementCourant
+ * @return une liste de StatutEleveAppelInfo
+ */
List<StatutEleveAppelInfo> getAppelLignesForEleve(List<AppelLigne> appelLignesEleve,
Autorite eleve,
boolean isCpeOuDirecteur,
import org.lilie.services.eliot.absences.parametrage.general.PasDeDecompteEnum
import org.lilie.services.eliot.parametrages.calendrier.JourFerieInfo
import org.lilie.services.eliot.absences.PreferencesEtablissementAbsences
-import org.lilie.services.eliot.scolarite.StructureEnseignement
class CalendrierAbsencesService extends CalendrierService {
--- /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.absences.statistiques
+
+/**
+ * utilitaires pour les stats d'absences
+ * @author jbui
+ */
+class StatistiqueAbsencesUtils {
+
+ static Double calculePourcentageArrondi(Double valeur, Double base) {
+ return ((int) ((valeur / base) * 10000)) / 100
+ }
+
+}
result.put(mois.name(), total)
totalGeneral += total
}
- result += ['total': totalGeneral]
+ result += ['total': statsMensuelles.totalGeneral]
return result
}
}.each {
StatsMensuellesEleve ligneStat ->
Map statEleve = (Map) [
- classe: ligneStat.structureEnseignementCode,
+ classe: ligneStat.structureEnseignement.code,
nomPrenom: ligneStat.eleve.nomAffichage(),
eleveId: ligneStat.eleve.autorite.id,
total: ligneStat.tableauStatsMensuelles.totalLigne
package org.lilie.services.eliot.absences.statistiques
-import org.lilie.services.eliot.absences.PlageHoraire
-
-/**
- * Created with IntelliJ IDEA.
- * User: jeff
- * Date: 22/03/13
- * Time: 14:52
- * To change this template use File | Settings | File Templates.
- */
class StatsUnePlageHoraire {
//<JourSemaine, Nb>
Map<Integer, Integer> datas = [:]
package org.lilie.services.eliot.absences.statistiques.hebdomadaire
-import org.lilie.services.eliot.scolarite.Matiere
import org.lilie.services.eliot.absences.PlageHoraire
import org.lilie.services.eliot.securite.Autorite
List<StatsHebdoData> datas = findAllStatsHebdoData(securiteSession, criteres, classes)
List<StatsHebdosMatiere> statsHebdosMatiereList =
- findAllStatsHebdosMatiere(securiteSession, criteres, plages)
+ findAllStatsHebdosMatiere(criteres, plages)
stats.statsPlages = calculeStatsHebdosPlage(plages, datas, statsHebdosMatiereList)
}
- private List<StructureEnseignement> findAllClasse(SecuriteSession securiteSession,
- StatsParams criteres) {
+ private List<StructureEnseignement> findAllClasse(
+ SecuriteSession securiteSession,
+ StatsParams criteres) {
List<StructureEnseignement> classes = StructureEnseignement.findAllByIdInList(criteres.structIds)
"L'établissement des classes ne correspond pas à celui de l'utilisateur")
}
- List<Autorite> eleves = localStructureEnseignementService.
- findAllAutoritesElevesForAllStructures(classes as Set)
-
return classes
}
-
/* Retourne la liste des absences/retards/départs composée de l'élève, la date
- et la plage horaire concernés*/
+et la plage horaire concernés*/
+
private List<StatsHebdoData> findAllStatsHebdoData(SecuriteSession securiteSession,
StatsParams criteres,
List<StructureEnseignement> classes) {
/* Retourne la liste des matières concernées par la classe sélectionnée et ses
* groupes */
- private List<StatsHebdosMatiere> findAllStatsHebdosMatiere(SecuriteSession securiteSession,
- StatsParams criteres,
- List<PlageHoraire> plages){
+
+ private List<StatsHebdosMatiere> findAllStatsHebdosMatiere(
+ StatsParams criteres,
+ List<PlageHoraire> plages) {
Date dateDebut = DateUtil.setDebutJour(criteres.dateDebut.getTime())
Date dateFin = DateUtil.setFinJour(criteres.dateFin.getTime())
AND ev.dateHeureDebut BETWEEN :dateDebut AND :dateFin
""")
- List<Evenement, Matiere> list = (List<Evenement, Matiere>)Evenement.executeQuery(hqlMatieres.toString(), params)
+ List<Evenement, Matiere> list = (List<Evenement, Matiere>) Evenement.executeQuery(hqlMatieres.toString(), params)
// Retrouve la/les plages horaires de chaque évènement/matière remonté et crée
// les statsHebdosMatiere
List<StatsHebdosMatiere> statsHebdosMatiereList = []
- list.each{ Object it ->
- Date timeDebutEvenement = Date.parse("HH:mm:ss",it[0].dateHeureDebut.format("HH:mm:ss"))
- Date timeFinEvenement = Date.parse("HH:mm:ss",it[0].dateHeureFin.format("HH:mm:ss"))
- plages.each{ PlageHoraire plage ->
+ list.each { Object it ->
+ Date timeDebutEvenement = Date.parse("HH:mm:ss", it[0].dateHeureDebut.format("HH:mm:ss"))
+ Date timeFinEvenement = Date.parse("HH:mm:ss", it[0].dateHeureFin.format("HH:mm:ss"))
+ plages.each { PlageHoraire plage ->
if (timeDebutEvenement < plage.fin &&
- timeFinEvenement > plage.debut){
+ timeFinEvenement > plage.debut) {
StatsHebdosMatiere statsHebdosMatiere = new StatsHebdosMatiere()
statsHebdosMatiere.date = it[0].dateHeureDebut
statsHebdosMatiere.matiere = it[1]
return statsHebdosPlages
}
-
/**
* Retourne les matières correspondant à des évènements se passant pendant la plage
* horaire et le jour en paramètres
*/
private List<Matiere> getMatieres(PlageHoraire plage,
Jour jour,
- List<StatsHebdosMatiere> statsHebdosMatiereList){
+ List<StatsHebdosMatiere> statsHebdosMatiereList) {
List<Matiere> matiereList = []
- statsHebdosMatiereList.each{ StatsHebdosMatiere statsHebdosMatiere ->
+ statsHebdosMatiereList.each { StatsHebdosMatiere statsHebdosMatiere ->
if (statsHebdosMatiere.plageHoraire == plage &&
Jour.getJourByDate(statsHebdosMatiere.date) == jour &&
- !matiereList.contains(statsHebdosMatiere.matiere)){
+ !matiereList.contains(statsHebdosMatiere.matiere)) {
matiereList.add(statsHebdosMatiere.matiere)
}
}
--- /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.absences.statistiques.mensuelle
+
+import org.lilie.services.eliot.temps.Mois
+
+/**
+ * Décrit un mois, avec sa date de début et sa date de fin pour le calcul des
+ * stats mensuelles
+ * @author jbui
+ */
+class PeriodeMensuelle {
+ Mois mois
+ Date dateDebut
+ Date dateFin
+}
import org.lilie.services.eliot.temps.Mois
import org.lilie.services.eliot.scolarite.StructureEnseignement
import org.lilie.services.eliot.scolarite.Personne
-import org.lilie.services.eliot.annuaire.Niveau
import org.lilie.services.eliot.scolarite.NiveauGeneral
+import org.lilie.services.eliot.absences.statistiques.volumehoraire.VolumesAllStructureEnseignements
+import org.lilie.services.eliot.absences.statistiques.StatistiqueAbsencesUtils
+import org.lilie.services.eliot.scolarite.structureenseignement.EffectifsClasseGroupe
/**
* Représente le résultat d'une requête de stats mensuelles par classe
List<Mois> mois = []
NiveauDetail niveauDetail
+ ModeCalcul modeCalcul
List<StatsMensuellesStructure> statsStructures = []
List<StatsMensuellesEleve> statsEleves = []
* @param structureId : id de la structure
* @return une StatsMensuellesStructure
*/
- StatsMensuellesStructure findOrCreateStatsStructure(StructureEnseignement structureEnseignement) {
+ StatsMensuellesStructure findStatsStructure(StructureEnseignement structureEnseignement) {
StatsMensuellesStructure statStruct = (StatsMensuellesStructure) this.
statsStructures.find {
it.structureEnseignement.id == structureEnseignement.id
}
- if (!statStruct) {
- statStruct = new StatsMensuellesStructure(
- structureEnseignement: structureEnseignement
- )
- this.statsStructures << statStruct
- }
return statStruct
}
* @param eleveId : id de l'élève
* @return une StatsMensuellesEleve
*/
- StatsMensuellesEleve findOrCreateStatsEleve(Personne eleve,
- String structureEnseignementCode) {
+ StatsMensuellesEleve findStatsEleve(
+ Personne eleve,
+ StructureEnseignement structureEnseignement) {
+
StatsMensuellesEleve statEleve = (StatsMensuellesEleve) this.
statsEleves.find {
it.eleve.id == eleve.id
}
- if (!statEleve) {
- statEleve = new StatsMensuellesEleve(
- eleve: eleve,
- structureEnseignementCode: structureEnseignementCode
- )
- this.statsEleves << statEleve
- }
return statEleve
}
* @param NiveauId : id de l'élève
* @return une StatsMensuellesNiveau
*/
- StatsMensuellesNiveau findOrCreateStatsNiveau(NiveauGeneral niveauGeneral) {
+ StatsMensuellesNiveau findStatsNiveau(NiveauGeneral niveauGeneral) {
if (!niveauGeneral) {
return null
}
statsNiveau.find {
it.niveauGeneral.id == niveauGeneral.id
}
- if (!statNiveau) {
- statNiveau = new StatsMensuellesNiveau(
- niveauGeneral: niveauGeneral
- )
- this.statsNiveau << statNiveau
- }
return statNiveau
}
/**
- * Transforme les données exprimées en volume en données exprimées en
- * pourcentage du total de la structure
+ * @return une Map associant les totaux à chaque mois
*/
- void transformeVolumeEnPourcentage(Double diviseur, NiveauDetail niveauDetail) {
-
- switch (niveauDetail) {
-
- case NiveauDetail.STRUCTURE_ENSEIGNEMENT:
- this.statsStructures.each {
- it.transformeVolumeEnPourcentage(diviseur)
+ Map<Mois, Double> getTotauxMensuels() {
+ List<StatsMensuellesLigne> lignes = this.getLignes()
+ Map result = [:]
+ if (modeCalcul == ModeCalcul.VOLUME) {
+ lignes.each {
+ StatsMensuellesLigne ligne ->
+ ligne.tableauStatsMensuelles.valeurs.each {
+ StatsMensuellesValeur valeur ->
+ if (!result.get(valeur.mois)) {
+ result.put(valeur.mois, 0.0)
+ }
+ result[valeur.mois] = result[valeur.mois] + valeur.valeurBrute
}
- break
-
- case NiveauDetail.ELEVE:
- this.statsEleves.each {
- it.transformeVolumeEnPourcentage(diviseur)
+ }
+ } else {
+ Map<Mois, Double> valeursBrutes = [:]
+ Map<Mois, Double> volumeEffectifs = [:]
+ lignes.each {
+ StatsMensuellesLigne ligne ->
+ ligne.tableauStatsMensuelles.valeurs.each {
+ StatsMensuellesValeur valeur ->
+ if (!valeursBrutes.get(valeur.mois)) {
+ valeursBrutes.put(valeur.mois, 0.0)
+ }
+ valeursBrutes[valeur.mois] = valeursBrutes[valeur.mois] + valeur.valeurBrute
+ if (!volumeEffectifs.get(valeur.mois)) {
+ volumeEffectifs.put(valeur.mois, 0.0)
+ }
+ volumeEffectifs[valeur.mois] = volumeEffectifs[valeur.mois] + valeur.volumeEffectif
}
- break
+ }
- case NiveauDetail.NIVEAU:
- this.statsNiveau.each {
- it.transformeVolumeEnPourcentage(diviseur)
+ valeursBrutes.each {
+ Mois mois, Double valeurBrute ->
+ Double volumeEffectif = volumeEffectifs.get(mois)
+ if (volumeEffectif) {
+ result.put(
+ mois,
+ StatistiqueAbsencesUtils.calculePourcentageArrondi(
+ valeurBrute,
+ volumeEffectif
+ )
+ )
+ } else {
+ result.put(mois, 0.0)
}
- break
-
-
+ }
}
+ return result
}
- /**
- * @return une Map associant les totaux à chaque mois
- */
- Map<Mois, Double> getTotauxMensuels() {
- List<StatsMensuellesLigne> lignes = this.getLignes()
- Map result = [:]
- lignes.each {
- StatsMensuellesLigne ligne ->
- ligne.tableauStatsMensuelles.valeurs.each {
- StatsMensuellesValeur valeur ->
- if (!result.get(valeur.mois)) {
- result.put(valeur.mois, 0.0)
+ Double getTotalGeneral() {
+ Double result = 0.0
+ if (modeCalcul == ModeCalcul.VOLUME) {
+ lignes.each {
+ StatsMensuellesLigne ligne ->
+ ligne.tableauStatsMensuelles.valeurs.each {
+ StatsMensuellesValeur valeur ->
+ result += valeur.valeurBrute
+ }
+ }
+ } else {
+ Double totalValeurBrutes = 0.0
+ Double totalVolumeEffectif = 0.0
+ lignes.each {
+ StatsMensuellesLigne ligne ->
+ ligne.tableauStatsMensuelles.valeurs.each {
+ StatsMensuellesValeur valeur ->
+ totalValeurBrutes += valeur.valeurBrute
+ totalVolumeEffectif += valeur.volumeEffectif
}
- result[valeur.mois] = result[valeur.mois] + valeur.valeur
}
+ result = StatistiqueAbsencesUtils.calculePourcentageArrondi(
+ totalValeurBrutes,
+ totalVolumeEffectif
+ )
}
return result
}
}
/**
- * Calcule le volume horaire global
- * @return
+ * Transforme les résultats en résultats en pourcentage en utilisant les
+ * données de volume horaires des structures d'enseignement
+ * @param volumesAllStructureEnseignements
*/
- public Double volumeTotalHoraire() {
-
- Double resultat = 0
+ void calculeVolumesEffectifs(
+ VolumesAllStructureEnseignements volumesAllStructureEnseignements,
+ EffectifsClasseGroupe effectifsClasseGroupe,
+ StatsMensuellesParams criteres) {
- getLignes().each {StatsMensuellesLigne ligne ->
- resultat += ligne.volumeTotalHoraire()
+ this.getLignes().each {
+ StatsMensuellesLigne ligne ->
+ ligne.calculeVolumeEffectif(
+ volumesAllStructureEnseignements,
+ effectifsClasseGroupe
+ )
}
- return resultat
}
}
package org.lilie.services.eliot.absences.statistiques.mensuelle
import org.lilie.services.eliot.scolarite.Personne
+import org.lilie.services.eliot.scolarite.StructureEnseignement
+
+import org.lilie.services.eliot.absences.statistiques.volumehoraire.VolumesUneStructureEnseignement
+import org.lilie.services.eliot.absences.statistiques.volumehoraire.VolumesAllStructureEnseignements
+import org.lilie.services.eliot.absences.statistiques.volumehoraire.VolumeMensuel
+import org.lilie.services.eliot.scolarite.structureenseignement.EffectifsClasseGroupe
/**
* Représente les stats mensuelles pour un élève
*/
-class StatsMensuellesEleve extends StatsMensuellesLigne {
+class StatsMensuellesEleve extends StatsMensuellesLigne {
Personne eleve
- String structureEnseignementCode
+ StructureEnseignement structureEnseignement
+
+ StatsMensuellesEleve(ModeCalcul modeCalcul,
+ Personne eleve,
+ StructureEnseignement structureEnseignement){
+ super(modeCalcul)
+ this.eleve = eleve
+ this.structureEnseignement = structureEnseignement
+ }
+
+ @Override
+ void calculeVolumeEffectif(
+ VolumesAllStructureEnseignements volumesAllStructureEnseignements,
+ EffectifsClasseGroupe effectifsClasseGroupe) {
+
+ tableauStatsMensuelles.valeurs.each {
+ StatsMensuellesValeur statsMensuellesValeur ->
+
+ VolumesUneStructureEnseignement volumesUneStructureEnseignement =
+ volumesAllStructureEnseignements.
+ findOrCreateVolumesForStructure(structureEnseignement)
+
+ VolumeMensuel valeurMensuelle = volumesUneStructureEnseignement.
+ findOrCreateVolumeMensuelle(statsMensuellesValeur.mois)
+
+ statsMensuellesValeur.volumeEffectif = valeurMensuelle.volumeHeure
+ }
+
+ }
}
package org.lilie.services.eliot.absences.statistiques.mensuelle
+import org.lilie.services.eliot.absences.statistiques.volumehoraire.VolumesAllStructureEnseignements
+import org.lilie.services.eliot.temps.Mois
+import org.lilie.services.eliot.scolarite.structureenseignement.EffectifsClasseGroupe
+
/**
* Représente une ligne de stats mensuelles.
* Surchargée par StatsMensuellesEleve, StatsMensuellesStructure et Niveau
* @author jbui
*/
-class StatsMensuellesLigne {
+abstract class StatsMensuellesLigne {
- TableauStatsMensuelles tableauStatsMensuelles = new TableauStatsMensuelles()
+ ModeCalcul modeCalcul
+ TableauStatsMensuelles tableauStatsMensuelles
- /**
- * Transforme les données exprimées en volume en données exprimées en
- * pourcentage du total de la structure
- */
- void transformeVolumeEnPourcentage(Double diviseur) {
- if (diviseur > 0) {
- tableauStatsMensuelles.valeurs.each {
- it.valeur = (it.valeur * 100) / diviseur
- }
- } else {
- tableauStatsMensuelles.valeurs.each {
- it.valeur = 0
- }
- }
+ StatsMensuellesLigne(ModeCalcul modeCalcul){
+ this.modeCalcul = modeCalcul
+ this.tableauStatsMensuelles = new TableauStatsMensuelles(
+ modeCalcul: modeCalcul
+ )
}
- /**
- * Calcule un volume global
- * @return
- */
- public Double volumeTotalHoraire() {
- Double resultat = 0.0
- tableauStatsMensuelles.valeurs.each {StatsMensuellesValeur statsMensuellesValeur ->
- resultat += statsMensuellesValeur.valeur
+ void initialiseTableau(List<Mois> listeMois){
+ listeMois.each {
+ this.tableauStatsMensuelles.findOrCreateStatValeur(it)
}
- return resultat
}
+// /**
+// * Calcule un volume global
+// * @return
+// */
+// public Double volumeTotalHoraire() {
+// Double resultat = 0.0
+// tableauStatsMensuelles.valeurs.each {StatsMensuellesValeur statsMensuellesValeur ->
+// resultat += statsMensuellesValeur.valeurBrute
+// }
+// return resultat
+// }
+
+ abstract void calculeVolumeEffectif(
+ VolumesAllStructureEnseignements volumesAllStructureEnseignements,
+ EffectifsClasseGroupe effectifsClasseGroupe
+ )
}
package org.lilie.services.eliot.absences.statistiques.mensuelle
import org.lilie.services.eliot.scolarite.NiveauGeneral
+import org.lilie.services.eliot.absences.statistiques.volumehoraire.VolumesAllStructureEnseignements
+import org.lilie.services.eliot.scolarite.StructureEnseignement
+import org.lilie.services.eliot.scolarite.structureenseignement.EffectifsClasseGroupe
/**
* Représente les stats mensuelles par niveau
* @author jbui
*/
-class StatsMensuellesNiveau extends StatsMensuellesLigne {
+class StatsMensuellesNiveau extends StatsMensuellesLigne {
NiveauGeneral niveauGeneral
+ List<StructureEnseignement> structureEnseignements
+
+ StatsMensuellesNiveau(ModeCalcul modeCalcul, NiveauGeneral niveauGeneral, List<StructureEnseignement> structureEnseignements){
+ super(modeCalcul)
+ this.niveauGeneral = niveauGeneral
+ this.structureEnseignements = structureEnseignements
+ }
+
+ @Override
+ void calculeVolumeEffectif(
+ VolumesAllStructureEnseignements volumesAllStructureEnseignements,
+ EffectifsClasseGroupe effectifsClasseGroupe) {
+
+ tableauStatsMensuelles.valeurs.each {
+ StatsMensuellesValeur statsMensuellesValeur ->
+
+ Long volumeEffectif = 0
+
+ structureEnseignements.each {
+ StructureEnseignement structureEnseignement ->
+ volumeEffectif += effectifsClasseGroupe.getEffectifClasse(structureEnseignement) *
+ volumesAllStructureEnseignements.
+ findOrCreateVolumesForStructure(structureEnseignement).
+ findOrCreateVolumeMensuelle(statsMensuellesValeur.mois).volumeHeure
+ }
+
+
+ statsMensuellesValeur.volumeEffectif = volumeEffectif
+ }
+
+ }
}
import org.lilie.services.eliot.annuaire.FonctionEnum
import org.lilie.services.eliot.applications.absences.BilanAbsencesParPersonneInfo
import org.lilie.services.eliot.applications.absences.BilanAbsenceInfo
-import org.lilie.services.eliot.scolarite.Calendrier
+
import java.text.SimpleDateFormat
import org.lilie.services.eliot.absences.parametrage.incidentpunitionsanction.TypePunitionService
import org.lilie.services.eliot.absences.parametrage.incidentpunitionsanction.TypeIncidentService
import org.lilie.services.eliot.absences.ScolariteService
import org.lilie.services.eliot.absences.emploidutemps.EmploiDuTempsService
import org.lilie.services.eliot.scolarite.NiveauGeneral
-import org.lilie.services.eliot.absences.TauxAbsencesCalculMode
-import org.lilie.services.eliot.absences.statistiques.CalendrierAbsencesService
-import org.lilie.services.eliot.scolarite.personne.eleve.EleveAnnuaireService
-import org.lilie.services.eliot.scolarite.StructureEnseignementPreferences
+
import org.lilie.services.eliot.absences.statistiques.Type
+import org.lilie.services.eliot.absences.statistiques.volumehoraire.VolumesAllStructureEnseignements
+import org.lilie.services.eliot.scolarite.structureenseignement.EffectifsClasseGroupe
class StatsMensuellesService extends AbstractConsultationService {
LocalStructureEnseignementService localStructureEnseignementService
ScolariteService scolariteService
EmploiDuTempsService emploiDuTempsService
- CalendrierAbsencesService calendrierAbsencesService
- EleveAnnuaireService eleveAnnuaireService
final static String VALEUR_TOUS = '-1'
PreferencesEtablissementAbsences pref) {
StatsMensuelles result = comptageStatistique(
+ securiteSession,
criteres,
pref
)
- if (criteres.modeCalcul == ModeCalcul.POURCENTAGE) {
-
- result = transformeVolumeEnPourcentage(
- securiteSession,
- criteres,
- pref,
- result
- )
-
- }
-
return result
}
* @param pref
* @return un objet stat mensuelle contenant les infos de comptage définie par le paramètre critères
*/
- private StatsMensuelles comptageStatistique(StatsMensuellesParams criteres,
+ private StatsMensuelles comptageStatistique(SecuriteSession securiteSession,
+ StatsMensuellesParams criteres,
PreferencesEtablissementAbsences pref) {
- StatsMensuelles result = new StatsMensuelles(niveauDetail: criteres.niveauDetail)
+ StatsMensuelles result = new StatsMensuelles(
+ niveauDetail: criteres.niveauDetail,
+ modeCalcul: criteres.modeCalcul
+ )
result.mois = calculeListeMois(criteres)
break
}
- result
- }
-
- /**
- * Calcul du pourcentage à partir des données d'un objet StatsMensuelles
- * @param securiteSession
- * @param criteres
- * @param pref
- * @param result
- * @return
- */
- private StatsMensuelles transformeVolumeEnPourcentage(
- SecuriteSession securiteSession,
- StatsMensuellesParams criteres,
- PreferencesEtablissementAbsences pref,
- StatsMensuelles result) {
- Double diviseur = 0.0
-
- switch (criteres.type) {
-
- case Type.ABSENCES:
-
- diviseur = calculeDiviseurPourcentageAbsences(
- securiteSession,
- pref,
- criteres
- )
-
- break
+ if (criteres.modeCalcul == ModeCalcul.POURCENTAGE) {
- case Type.RETARDS:
- case Type.DEPARTS_ANTICIPES:
+ List<PeriodeMensuelle> periodeMensuelles = prepareIntervalles(
+ criteres.dateDebut.getTime(),
+ criteres.dateFin.getTime()
+ )
- diviseur = calculeDiviseurPourcentageRetardDepart(
+ VolumesAllStructureEnseignements volumeHoraireStructures =
+ emploiDuTempsService.getVolumeHoraireStructures(
securiteSession,
pref,
- criteres
- )
-
- break
- }
-
- result.transformeVolumeEnPourcentage(
- diviseur,
- criteres.niveauDetail
- )
-
- return result
- }
-
- /**
- * Calcul du diviseur pour les % d'absences
- * @param securiteSession
- * @param pref
- * @param criteres
- * @return
- */
- private Double calculeDiviseurPourcentageAbsences(SecuriteSession securiteSession,
- PreferencesEtablissementAbsences pref,
- StatsMensuellesParams criteres) {
-
-
- Calendrier calendrier = calendrierService.getCalendrierForEtablissement(pref.etablissement)
-
- List<StructureEnseignement> allClasse = []
- criteres.structIds.each {
- allClasse << StructureEnseignement.get(it)
- }
-
- if (criteres.isResultatsParNiveau) {
-
- // On récupère tous les niveaux de toutes les classes.
- List<NiveauGeneral> niveauxGeneraux = localStructureEnseignementService.
- findAllStructureForAllIds(allClasse*.id)*.niveauGeneral
-
- List<StructureEnseignementPreferences> allStructureEnseignementPreferences =
- StructureEnseignementPreferences.withCriteria {
- 'in'('niveauGeneral', niveauxGeneraux)
- }
-
- allClasse = allStructureEnseignementPreferences*.structureEnseignement
-
- }
-
- Double diviseur
-
- switch (pref.tauxAbsencesCalculMode) {
- // NOTE : la spec précise que la période du diviseur est TOUJOURS l'année.
-
- case TauxAbsencesCalculMode.NB_COURS_REEL_EDT:
-
- diviseur = emploiDuTempsService.volumeHorairePourAllClasse(
- pref,
- allClasse,
- pref.pasDecompte,
- calendrier.premierJour,
- calendrier.dernierJour
- )
- break
-
- case TauxAbsencesCalculMode.NB_PLG_HOR_CAL_HEBDO:
-
- diviseur = calendrierAbsencesService.countPasDeDecompteOuvertSurPeriode(
- securiteSession,
- calendrier.premierJour,
- calendrier.dernierJour,
- pref
+ criteres,
+ periodeMensuelles,
)
- break
- }
-
- Integer nombreEleveEtablissement
- if (criteres.isResultatsParNiveau) {
-
- nombreEleveEtablissement = eleveAnnuaireService.countAllEleveByAllClasse(
- pref.etablissement,
- allClasse
+ EffectifsClasseGroupe effectifsClasseGroupe = null
+ if (criteres.niveauDetail != NiveauDetail.ELEVE) {
+ effectifsClasseGroupe =
+ localStructureEnseignementService.findEffectifsClasseGroupe(
+ localStructureEnseignementService.findAllStructureForAllIds(
+ criteres.structIds
+ )
+ )
+ }
+ result.calculeVolumesEffectifs(
+ volumeHoraireStructures,
+ effectifsClasseGroupe,
+ criteres
)
-
- } else {
-
- nombreEleveEtablissement = eleveAnnuaireService.countAllEleveByEtablissement(pref.etablissement)
-
}
- return diviseur * nombreEleveEtablissement
- }
-
- /**
- * Calcul du diviseur pour les % de départ/retard. Le calcul se fait sur le nombre de retard/départ annuel
- *
- * En cas de refactoring du calcul du diviseur de la période, c'est cette méthode qui devra être modifiée
- * @param securiteSession
- * @param pref
- * @param criteres
- * @return
- */
- private Double calculeDiviseurPourcentageRetardDepart(SecuriteSession securiteSession,
- PreferencesEtablissementAbsences pref,
- StatsMensuellesParams criteres
- ) {
-
- Calendrier calendrier = calendrierService.getCalendrierForEtablissement(pref.etablissement)
-
- Calendar calendarDebutJour = Calendar.getInstance()
- calendarDebutJour.setTime(calendrier.premierJour)
-
- Calendar calendarFinJour = Calendar.getInstance()
- calendarFinJour.setTime(calendrier.dernierJour)
-
- criteres.dateDebut = calendarDebutJour
- criteres.dateFin = calendarFinJour
-
- StatsMensuelles annuelles = calculeStatsMensuelles(
- securiteSession,
- criteres,
- pref)
-
- return annuelles.volumeTotalHoraire()
-
+ return result
}
/**
private StatsMensuelles initialiseLignesNiveaux(
StatsMensuelles statsMensuelles,
StatsMensuellesParams statsMensuellesParams) {
- List<NiveauGeneral> niveaux = localStructureEnseignementService.
- findAllStructureForAllIds(statsMensuellesParams.structIds)*.niveauGeneral
- ((Set) niveaux).each {
- NiveauGeneral niveauGeneral ->
+
+ List<StructureEnseignement> structureEnseignements = localStructureEnseignementService.
+ findAllStructureForAllIds(statsMensuellesParams.structIds)
+
+ Map<NiveauGeneral, List<StructureEnseignement>> structuresParNiveau = [:]
+ structureEnseignements.each {
+ StructureEnseignement structureEnseignement ->
+ NiveauGeneral niveauGeneral = structureEnseignement.niveauGeneral
+ if (!structuresParNiveau.get(niveauGeneral)) {
+ structuresParNiveau.put(niveauGeneral, [])
+ }
+ structuresParNiveau.get(niveauGeneral).add(structureEnseignement)
+ }
+
+ structuresParNiveau.each {
+ NiveauGeneral niveauGeneral, List<StructureEnseignement> structuresDuNiveau ->
if (niveauGeneral) {
- statsMensuelles.statsNiveau.add(
- new StatsMensuellesNiveau(niveauGeneral: niveauGeneral)
+ StatsMensuellesNiveau statsNiveau = new StatsMensuellesNiveau(
+ statsMensuellesParams.modeCalcul,
+ niveauGeneral,
+ structuresDuNiveau
)
+ statsNiveau.initialiseTableau(statsMensuelles.mois)
+ statsMensuelles.statsNiveau.add(statsNiveau)
}
}
return statsMensuelles
List<StructureEnseignement> classes = localStructureEnseignementService.
findAllStructureForAllIds(statsMensuellesParams.structIds)
classes.each {
- statsMensuelles.statsStructures.add(
- new StatsMensuellesStructure(structureEnseignement: it)
+ StatsMensuellesStructure statsStructure = new StatsMensuellesStructure(
+ statsMensuellesParams.modeCalcul,
+ it
)
+ statsStructure.initialiseTableau(statsMensuelles.mois)
+ statsMensuelles.statsStructures.add(statsStructure)
}
return statsMensuelles
}
localStructureEnseignementService.findAllClassesForAllEleves((Set) eleves)
eleves.each {
Personne personne ->
- statsMensuelles.statsEleves.add(
- new StatsMensuellesEleve(
- eleve: personne,
- structureEnseignementCode: classeEleves.get(personne).code
- )
+ StatsMensuellesEleve statsEleve = new StatsMensuellesEleve(
+ statsMensuellesParams.modeCalcul,
+ personne,
+ classeEleves.get(personne)
)
+ statsEleve.initialiseTableau(statsMensuelles.mois)
+ statsMensuelles.statsEleves.add(statsEleve)
}
return statsMensuelles
}
stats,
criteres.getNiveauDetail()
)
-
}
private void calculeCountAbsences(BilanAbsencesParPersonneInfo absencesDatas,
findOrCreateStatValeur(mois)
//Incrémentation de la valeur
- statValeur.valeur += (nbPlages * pref.longueurPlage)
+ statValeur.valeurBrute += (nbPlages * pref.longueurPlage)
}
}
}
* @param niveauDetail
* @return une StatsMensuellesLigne
*/
- private StatsMensuellesLigne getLigneStat(StructureEnseignement struct,
- Personne personne,
- StatsMensuelles stats,
- NiveauDetail niveauDetail) {
+ private StatsMensuellesLigne getLigneStat(
+ StructureEnseignement structureEnseignement,
+ Personne personne,
+ StatsMensuelles stats,
+ NiveauDetail niveauDetail) {
+
StatsMensuellesLigne statLigne
switch (niveauDetail) {
case NiveauDetail.STRUCTURE_ENSEIGNEMENT:
//Récupération des stats de la structure
- statLigne = stats.findOrCreateStatsStructure(
- struct
+ statLigne = stats.findStatsStructure(
+ structureEnseignement
)
break
case NiveauDetail.ELEVE:
//Récupération des stats de l'élève
- statLigne = stats.findOrCreateStatsEleve(
+ statLigne = stats.findStatsEleve(
personne,
- struct.code
+ structureEnseignement
)
break
case NiveauDetail.NIVEAU:
//Récupération des stats du niveau
- statLigne = stats.findOrCreateStatsNiveau(struct.niveauGeneral)
+ statLigne = stats.findStatsNiveau(structureEnseignement.niveauGeneral)
}
return statLigne
}
)
- statValeur.valeur += getIncrementValeur(
+ statValeur.valeurBrute += getIncrementValeur(
nbDemiJours,
lastDemiJour,
currentJour,
findOrCreateStatValeur(
Mois.parseByNumero(cal.get(Calendar.MONTH) + 1)
)
- statsValeur.valeur += 1
+ statsValeur.valeurBrute += 1
}
}
lastEleveId = currentEleveId
private void calculeStatsMensuellesDiscipline(StatsMensuellesParams criteres,
StatsMensuelles stats
) {
- List intervalles = prepareIntervalles(
+ List<PeriodeMensuelle> intervalles = prepareIntervalles(
criteres.dateDebut.getTime(),
criteres.dateFin.getTime()
)
break
}
- intervalles.each { List coupleDates ->
+ intervalles.each { PeriodeMensuelle periodeMensuelle ->
Calendar date = Calendar.getInstance()
- date.setTime(coupleDates[0] as Date)
+ date.setTime(periodeMensuelle.dateDebut)
Mois mois = Mois.parseByNumero(date.get(Calendar.MONTH) + 1)
List resultats = functionRequete(
structuresIds,
typesDisciplines,
- coupleDates[0] as Date,
- coupleDates[1] as Date
+ periodeMensuelle.dateDebut,
+ periodeMensuelle.dateFin
)
resultats.each { def coupleStructCalcul ->
- StatsMensuellesStructure state = stats.findOrCreateStatsStructure(
- coupleStructCalcul[0]
+ StatsMensuellesStructure state = stats.findStatsStructure(
+ (StructureEnseignement)coupleStructCalcul[0]
)
StatsMensuellesValeur stateMensuelle = state.tableauStatsMensuelles.
mois
)
- stateMensuelle.valeur = coupleStructCalcul[1]
+ stateMensuelle.valeurBrute = (Double)coupleStructCalcul[1]
}
}
StatsMensuelles stats
) {
- List intervalles = prepareIntervalles(
+ List<PeriodeMensuelle> intervalles = prepareIntervalles(
criteres.dateDebut.getTime(),
criteres.dateFin.getTime()
)
break
}
- intervalles.each { List coupleDates ->
+ intervalles.each { PeriodeMensuelle periodeMensuelle ->
Calendar date = Calendar.getInstance()
- date.setTime(coupleDates[0] as Date)
+ date.setTime(periodeMensuelle.dateDebut)
Mois mois = Mois.parseByNumero(date.get(Calendar.MONTH) + 1)
List resultats = executeRequeteRetardsOrDeparts(
criteres,
isRetard,
- coupleDates[0] as Date,
- coupleDates[1] as Date
+ periodeMensuelle.dateDebut,
+ periodeMensuelle.dateFin
)
resultats.each { def resultatCalcul ->
)
if (ligne) {
ligne.tableauStatsMensuelles.
- findOrCreateStatValeur(mois).valeur += resultatCalcul[0]
+ findOrCreateStatValeur(mois).valeurBrute += resultatCalcul[0]
}
}
}
* @param fin date de fin
* @return liste de couple date de début/ date de fin
*/
- private List prepareIntervalles(Date debut, Date fin) {
- List intervales = []
+ private List<PeriodeMensuelle> prepareIntervalles(Date debut, Date fin) {
+ List<PeriodeMensuelle> result = []
Calendar dateDebut = Calendar.getInstance()
dateDebut.setTime(debut)
*/
if ((dateMin.get(Calendar.MONTH) == dateMax.get(Calendar.MONTH)) &&
(dateMin.get(Calendar.YEAR) == dateMax.get(Calendar.YEAR))) {
- intervales << [
- dateMin.getTime(),
- dateMax.getTime()
- ]
+ result << new PeriodeMensuelle(
+ mois: Mois.parseByDate(dateMin.getTime()),
+ dateDebut: dateMin.getTime(),
+ dateFin: dateMax.getTime()
+ )
} else {
- intervales << [
- dateMin.getTime(),
- DateUtil.getMaximumDayOfMonth(dateMin).getTime()
- ]
-
- intervales << [
- DateUtil.getMinimumDayOfMonth(dateMax).getTime(),
- dateMax.getTime()
- ]
+ result << new PeriodeMensuelle(
+ mois: Mois.parseByDate(dateMin.getTime()),
+ dateDebut: dateMin.getTime(),
+ dateFin: DateUtil.getMaximumDayOfMonth(dateMin).getTime()
+ )
+
+ result << new PeriodeMensuelle(
+ mois: Mois.parseByDate(dateMax.getTime()),
+ dateDebut: DateUtil.getMinimumDayOfMonth(dateMax).getTime(),
+ dateFin: dateMax.getTime()
+ )
}
Calendar date = Calendar.getInstance()
while (
date > dateMin && date < DateUtil.getMinimumDayOfMonth(dateMax)
) {
- intervales << [
- date.getTime(),
- DateUtil.getMaximumDayOfMonth(date).getTime()
- ]
+ result << new PeriodeMensuelle(
+ mois: Mois.parseByDate(date.getTime()),
+ dateDebut: date.getTime(),
+ dateFin: DateUtil.getMaximumDayOfMonth(date).getTime()
+ )
date.add(Calendar.MONTH, 1)
}
- return intervales
+ return result
}
StatsMensuellesFiltresContenu getStatsMensuellesFiltresContenu(
import org.lilie.services.eliot.scolarite.StructureEnseignement
+import org.lilie.services.eliot.absences.statistiques.volumehoraire.VolumesAllStructureEnseignements
+import org.lilie.services.eliot.absences.statistiques.volumehoraire.VolumesUneStructureEnseignement
+import org.lilie.services.eliot.absences.statistiques.volumehoraire.VolumeMensuel
+import org.lilie.services.eliot.scolarite.structureenseignement.EffectifsClasseGroupe
+
/**
* Représente les stats mensuelles d'une structure d'enseignement
* @author jbui
StructureEnseignement structureEnseignement
+ StatsMensuellesStructure(ModeCalcul modeCalcul,
+ StructureEnseignement structureEnseignement){
+ super(modeCalcul)
+ this.structureEnseignement = structureEnseignement
+ }
+
+ @Override
+ void calculeVolumeEffectif(
+ VolumesAllStructureEnseignements volumesAllStructureEnseignements,
+ EffectifsClasseGroupe effectifsClasseGroupe) {
+
+ tableauStatsMensuelles.valeurs.each {
+ StatsMensuellesValeur statsMensuellesValeur ->
+
+ VolumesUneStructureEnseignement volumesUneStructureEnseignement =
+ volumesAllStructureEnseignements.
+ findOrCreateVolumesForStructure(structureEnseignement)
+
+ VolumeMensuel volumeMensuel = volumesUneStructureEnseignement.
+ findOrCreateVolumeMensuelle(statsMensuellesValeur.mois)
+
+ Long effectif = effectifsClasseGroupe.
+ getEffectifClasse(structureEnseignement)
+
+ statsMensuellesValeur.volumeEffectif = volumeMensuel.volumeHeure *
+ effectif
+
+ structureEnseignement.groupes.each {
+ StructureEnseignement groupe ->
+ Long effectifGroupe = effectifsClasseGroupe.getEffectifClasseGroupe(
+ structureEnseignement,
+ groupe
+ )
+ VolumesUneStructureEnseignement volumeMensuelUnGroupe =
+ volumesAllStructureEnseignements.findOrCreateVolumesForStructure(groupe)
+ VolumeMensuel volumeMensuelGroupe = volumeMensuelUnGroupe.
+ findOrCreateVolumeMensuelle(statsMensuellesValeur.mois)
+ statsMensuellesValeur.volumeEffectif += volumeMensuelGroupe.volumeHeure *
+ effectifGroupe
+ }
+ }
+ }
}
package org.lilie.services.eliot.absences.statistiques.mensuelle
import org.lilie.services.eliot.temps.Mois
+import org.lilie.services.eliot.absences.statistiques.StatistiqueAbsencesUtils
/**
* Représente une valeur de stat mensuelle (mois = valeur)
*/
class StatsMensuellesValeur {
Mois mois
- Double valeur = 0.0
+ Double valeurBrute = 0.0
+ Double volumeEffectif = 0.0
+ ModeCalcul modeCalcul
+
+ Double getValeur() {
+ if (this.modeCalcul == ModeCalcul.POURCENTAGE) {
+ if (volumeEffectif) {
+ return StatistiqueAbsencesUtils.calculePourcentageArrondi(
+ valeurBrute,
+ volumeEffectif
+ )
+ } else {
+ return 0
+ }
+ } else {
+ return this.valeurBrute
+ }
+ }
}
package org.lilie.services.eliot.absences.statistiques.mensuelle
import org.lilie.services.eliot.temps.Mois
+import org.lilie.services.eliot.absences.statistiques.StatistiqueAbsencesUtils
/**
* Représente un tableau de stats mensuelles
* @author jbui
*/
class TableauStatsMensuelles {
+ ModeCalcul modeCalcul
List<StatsMensuellesValeur> valeurs = []
/**
find { it.mois == mois}
if (!statValeur) {
statValeur = new StatsMensuellesValeur(
+ modeCalcul: modeCalcul,
mois: mois,
- valeur: 0
+ valeurBrute: 0
)
this.valeurs << statValeur
}
return statValeur
}
- Double getTotalLigne(){
+ Double getTotalLigne() {
Double result = 0.0
- valeurs.each {
- result += it.valeur
+ if (this.modeCalcul == ModeCalcul.VOLUME) {
+ valeurs.each {
+ result += it.valeurBrute
+ }
+ } else {
+ Double totalValeur = 0.0
+ Double totalVolumeEffectif = 0.0
+ valeurs.each {
+ totalValeur += it.valeurBrute
+ totalVolumeEffectif += it.volumeEffectif
+ }
+ result = StatistiqueAbsencesUtils.calculePourcentageArrondi(
+ totalValeur,
+ totalVolumeEffectif
+ )
}
return result
}
--- /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.absences.statistiques.volumehoraire
+
+import org.lilie.services.eliot.scolarite.StructureEnseignement
+
+/**
+ * Contient les événements par mois d'une liste de structures
+ * @author jbui
+ */
+class EvenementsAllStructuresParMois {
+ Map<StructureEnseignement, EvenementsUneStructureParMois> evenementAllStructures = [:]
+
+ /**
+ * Retourne les événements par mois d'une structure d'enseignement
+ * @param structureEnseignement
+ * @return EvenementsUneStructureParMois
+ */
+ EvenementsUneStructureParMois findOrCreateEvenementStructure(
+ StructureEnseignement structureEnseignement){
+ EvenementsUneStructureParMois result = evenementAllStructures.
+ get(structureEnseignement)
+ if(!result){
+ result = new EvenementsUneStructureParMois(
+ structureEnseignement: structureEnseignement
+ )
+ evenementAllStructures.put(structureEnseignement, result)
+ }
+ return result
+ }
+
+ void eachStructureEnseignement(Closure closure){
+ evenementAllStructures.each {
+ StructureEnseignement structureEnseignement,
+ EvenementsUneStructureParMois evenementsUneStructureParMois ->
+ closure.call(structureEnseignement)
+ }
+ }
+}
--- /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.absences.statistiques.volumehoraire
+
+import org.lilie.services.eliot.scolarite.StructureEnseignement
+import org.lilie.services.eliot.temps.Mois
+import org.lilie.services.eliot.temps.Evenement
+
+/**
+ * Stocke les événements d'une structure, par mois
+ * @author jbui
+ */
+class EvenementsUneStructureParMois {
+ StructureEnseignement structureEnseignement
+ Map<Mois, List<Evenement>> evenementParMois = [:]
+
+ /**
+ * Ajoute un événement à un mois
+ * @param evenement
+ * @param mois
+ */
+ void addEvenementMois(Evenement evenement, Mois mois){
+ getEvenementDuMois(mois).add(evenement)
+ }
+
+ /**
+ * Retourne les événements du mois
+ * @param mois
+ * @return List<Evenement>
+ */
+ List<Evenement> getEvenementDuMois(mois){
+ List<Evenement> result = evenementParMois.get(mois)
+ if(!result){
+ result = []
+ evenementParMois.put(mois, result)
+ }
+ return result
+ }
+}
--- /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.absences.statistiques.volumehoraire
+
+import org.lilie.services.eliot.temps.Mois
+
+/**
+ * Représente un volume horaire mensuel
+ */
+class VolumeMensuel {
+ Mois mois
+ Double volumeHeure
+}
--- /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.absences.statistiques.volumehoraire
+
+import org.lilie.services.eliot.scolarite.StructureEnseignement
+
+/**
+ * Contient les stats de volume horaire pour toutes les structure d'enseignement
+ * par mois
+ * @author jbui
+ */
+class VolumesAllStructureEnseignements {
+ Map<StructureEnseignement, VolumesUneStructureEnseignement> volumesParStructure = [:]
+
+ VolumesUneStructureEnseignement findOrCreateVolumesForStructure(
+ StructureEnseignement structureEnseignement){
+ VolumesUneStructureEnseignement result = volumesParStructure.get(structureEnseignement)
+ if(!result){
+ result = new VolumesUneStructureEnseignement(
+ structureEnseignement: structureEnseignement
+ )
+ volumesParStructure.put(structureEnseignement, result)
+ }
+ return result
+ }
+}
--- /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.absences.statistiques.volumehoraire
+
+import org.lilie.services.eliot.temps.Mois
+import org.lilie.services.eliot.scolarite.StructureEnseignement
+
+/**
+ * Contient les stats de volume horaire pour une structure d'enseignement
+ * par mois
+ * @author jbui
+ */
+class VolumesUneStructureEnseignement {
+ StructureEnseignement structureEnseignement
+ Map<Mois, VolumeMensuel> volumeParMois = [:]
+
+ VolumeMensuel findOrCreateVolumeMensuelle(Mois mois){
+ VolumeMensuel result = volumeParMois.get(mois)
+ if(!result){
+ result = new VolumeMensuel(mois: mois, volumeHeure: 0.0)
+ volumeParMois.put(mois, result)
+ }
+ return result
+ }
+}
*/
private Map extraitStats(StatsMensuelles stats) {
Map result = (Map) [:]
- result.put(STRUCT_1_SEPT, stats.findOrCreateStatsStructure(structure1).
+ result.put(STRUCT_1_SEPT, stats.findStatsStructure(structure1).
tableauStatsMensuelles.findOrCreateStatValeur(Mois.SEPTEMBRE))
result.put(STRUCT_2_SEPT, stats.
- findOrCreateStatsStructure(structure2).
+ findStatsStructure(structure2).
tableauStatsMensuelles.findOrCreateStatValeur(Mois.SEPTEMBRE))
result.put(STRUCT_1_OCT, stats.
- findOrCreateStatsStructure(structure1).
+ findStatsStructure(structure1).
tableauStatsMensuelles.findOrCreateStatValeur(Mois.OCTOBRE))
result.put(STRUCT_2_OCT, stats.
- findOrCreateStatsStructure(structure2).
+ findStatsStructure(structure2).
tableauStatsMensuelles.findOrCreateStatValeur(Mois.OCTOBRE))
return result
}
AppelLigne.withSession { session -> session.flush()}
pref = initDonneesCommunesTestPreferencesAbsencesService.prefEtab1
+ pref.pasDecompte = PreferencesEtablissementAbsences.DECOMPTE_DEMIJOUR
}
protected void tearDown() {