--- /dev/null
+package org.lilie.services.eliot.applications.absences.bilan
+
+import org.lilie.services.eliot.absences.PreferencesEtablissementAbsences
+import org.lilie.services.eliot.absences.Appel
+import org.lilie.services.eliot.absences.AppelLigne
+import org.lilie.services.eliot.applications.scolarite.calendrier.PlageHoraireService
+import org.lilie.services.eliot.absences.PlageHoraire
+import org.lilie.services.eliot.temps.DateUtil
+import org.lilie.services.eliot.applications.scolarite.horaire.HeureService
+import org.hibernate.SQLQuery
+import org.lilie.services.eliot.requetage.RequetageUtilsService
+
+class BilanPasDecompteService extends RequetageUtilsService{
+
+ PlageHoraireService plageHoraireService
+ HeureService heureService
+
+ protected static final Byte AUCUN = 0
+ protected static final Byte MATIN = 1
+ protected static final Byte APRES_MIDI = 2
+ protected static final Byte MATIN_ET_APRES_MIDI = 3
+
+ /**
+ * Fait le comptage en fonction des données trouvées en base et du paramétrage
+ * @param pref : les préférences de l'établissement
+ * @param appelsDatas : les données de la base
+ * @return un Float
+ */
+ public Float calculeCount(PreferencesEtablissementAbsences pref,
+ List appelsDatas) {
+ switch (pref.pasDecompte) {
+ case PreferencesEtablissementAbsences.DECOMPTE_HEURE:
+ return calculeCountHeure(pref, appelsDatas)
+ case PreferencesEtablissementAbsences.DECOMPTE_DEMIJOUR:
+ return calculeCountDemiJour(
+ appelsDatas,
+ plageHoraireService.getPlageHoraires(pref)
+ )
+ case PreferencesEtablissementAbsences.DECOMPTE_JOUR:
+ return BilanUtils.calculeCountJour(appelsDatas)
+ }
+ }
+
+ /**
+ * Retourne pour chaque appel de la liste, le nombre de demi-journées sur
+ * lesquelles il porte
+ * @param appels : une liste d'appels
+ * @return une map associant à chaque id d'appel, un flag indiquant si l'appel
+ * porte sur le matin, l'après-midi ou les deux
+ */
+ public Map findAllDemiJoursForAllAppels(List<Long> appelIds) {
+ Map result = [:]
+ if (appelIds.size() > 0) {
+ List liste = findAllAppelsWithPlages(appelIds)
+ Boolean matin
+ Boolean apresMidi
+ liste.each {
+ Appel appel ->
+ matin = false
+ apresMidi = false
+ appel.plageHoraires.each {
+ PlageHoraire plage ->
+ if (plage.matin) {
+ matin = true
+ } else {
+ apresMidi = true
+ }
+ }
+ Byte flag = AUCUN
+ if (matin) {
+ flag += MATIN
+ }
+ if (apresMidi) {
+ flag += APRES_MIDI
+ }
+ result.put(appel.id, flag)
+ }
+ }
+ return result
+ }
+
+ /**
+ * Retourne le nombre de demi-journées concernées par un AppelLigne
+ * @param plages : les plages horaires de l'établissement
+ * @return un Byte
+ */
+ public Byte getNbDemiJoursForAppelLigne(AppelLigne appelLigne,
+ List<PlageHoraire> plages) {
+ Date heurePivot = heureService.getHeurePivotFromListPlages(plages)
+ Boolean matin = false
+ Boolean apresMidi = false
+ if (appelLigne.heureDebut < heurePivot) {
+ matin = true
+ }
+ if (appelLigne.heureFin > heurePivot) {
+ apresMidi = true
+ }
+ Byte result = 0
+
+ if (matin) {
+ result++
+ }
+
+ if (apresMidi) {
+ result++
+ }
+
+ return result
+ }
+
+
+ /**
+ * Retourne une map associant à chauqe appel passé en paramètre, le nombre
+ * de plages horaires qu'il concerne
+ * @param appelIds : une List<Long>
+ * @return une map
+ * @author jbui
+ */
+ public Map findPlagesCountForAllAppels(List<Long> appelIds) {
+ List liste = findAllAppelsWithPlages(appelIds)
+ Map result = [:]
+ liste.each {
+ Appel appel ->
+ result.put(appel.id, appel.plageHoraires.size())
+ }
+ return result
+ }
+
+ /**
+ * Retourne le numéro (1 ou 2) de la dernière demi-journée de l'appelLigne
+ * @param plages : plages horaires de l'établissement
+ * @return 1 si l'appel se termine le matin, 2 pour l'après-midi
+ */
+ public Byte getLastDemiJourForAppelLigne(AppelLigne appelLigne,
+ List<PlageHoraire> plages) {
+ Date heurePivot = heureService.getHeurePivotFromListPlages(plages)
+ if (appelLigne.heureFin > heurePivot) {
+ return 2
+ } else {
+ return 1
+ }
+ }
+
+ /**
+ * Retourne les appels de la liste avec leurs plages horaires fetchées
+ * @return une List<Appel>
+ */
+ private List findAllAppelsWithPlages(List<Long> appelIds) {
+ def result = []
+ if (appelIds && appelIds[0]) {
+
+ SQLQuery sqlQuery = prepareRequete(BilanRequetesConstantes.SQL_GET_APPELS)
+
+ sqlQuery.addEntity(Appel)
+
+ sqlQuery.setParameterList(BilanRequetesConstantes.ALL_APPEL, appelIds)
+
+ result = sqlQuery.list()
+ }
+ return result
+ }
+
+ /**
+ * Fait le comptage des absences en heures
+ * @return un Float
+ */
+ private Float calculeCountHeure(PreferencesEtablissementAbsences pref,
+ List appelsDatas) {
+ Set<Long> appelIds = []
+ appelsDatas.each {
+ if (it[1]?.id) {
+ appelIds << it[1].id
+ }
+ }
+ Map nbPlagesParAppel = findPlagesCountForAllAppels(appelIds.toList())
+ Float result = 0.0
+ appelsDatas.each {
+ Appel appel = (Appel) it[1]
+ if (appel) {
+ Integer nbPlages = (Integer) nbPlagesParAppel.getAt(appel.id)
+ result += (nbPlages * pref.longueurPlage)
+ } else {
+ Integer nbPlages = BilanUtils.calculeNbPlagesForAppelLigne(
+ plageHoraireService.getPlageHoraires(pref),
+ (AppelLigne) it[0]
+ )
+ result += (nbPlages * pref.longueurPlage)
+ }
+ }
+ return result
+ }
+
+ /**
+ * Fait le comptage des absences en demi-journées
+ * @return un Float
+ */
+ private Float calculeCountDemiJour(List appelsDatas, List<PlageHoraire> plages) {
+ Set<Long> appelIds = []
+ appelsDatas.each {
+ if (it[1]?.id) {
+ appelIds << it[1].id
+ }
+ }
+ Map demiJoursParAppel = findAllDemiJoursForAllAppels(appelIds.toList())
+
+ Calendar cal = Calendar.getInstance()
+ Float result = 0.0
+ Date currentJour
+ Byte currentDemiJour
+ Date lastJour
+ Byte lastDemiJour
+
+ appelsDatas.sort {
+ def data1, def data2 ->
+ BilanUtils.getDateDebut(data1) <=> BilanUtils.getDateDebut(data2)
+ }.each {
+ Appel appel = (Appel) it[1]
+ AppelLigne appelLigne = (AppelLigne) it[0]
+ Byte demiJours
+ Byte nbDemiJours
+
+ if (appel) {
+ demiJours = (Byte) demiJoursParAppel.getAt(appel.id)
+ nbDemiJours = 1
+ if (demiJours == MATIN_ET_APRES_MIDI) {
+ nbDemiJours = 2
+ }
+ cal.setTime(appel.dateHeureDebut)
+ } else {
+ nbDemiJours = getNbDemiJoursForAppelLigne(appelLigne, plages)
+ demiJours = getLastDemiJourForAppelLigne(appelLigne, plages)
+ cal.setTime(appelLigne.absenceJournee.date)
+ }
+
+ DateUtil.setDebutJour(cal)
+ currentJour = cal.getTime()
+ cal.clear()
+ currentDemiJour = demiJours
+ if (currentDemiJour == MATIN_ET_APRES_MIDI) {
+ currentDemiJour = APRES_MIDI
+ } else {
+ if (currentDemiJour == AUCUN) {
+ throw new IllegalStateException(
+ "L'appel ne porte ni sur le matin, ni sur l'après-midi."
+ )
+ }
+ }
+ if ((lastJour != currentJour) || (lastDemiJour != currentDemiJour)) {
+ result += nbDemiJours
+ }
+ lastDemiJour = currentDemiJour
+ lastJour = currentJour
+ }
+ return result
+ }
+
+}