/** * * Mets à jour la table d'agrégation des absences pour cet élève * Pour éviter des calculs trop long par erreurs, l'algorithme est limité à 3 ans dans le passé et le futur * de la date courante * * @param DateTime $dateDebut date de début pour la prise en compte de la mise à jours * @param DateTime $dateFin date de fin pour la prise en compte de la mise à jours * */ public function updateAbsenceAgregationTable(DateTime $dateDebut = null, DateTime $dateFin = null) { $now = new DateTime(); $dateDebutClone = null; $dateFinClone = null; if ($dateDebut != null && $dateFin != null && $dateDebut->format('U') > $dateFin->format('U')) { throw new PropelException('Erreur: la date de debut ne peut être postérieure à la date de fin'); } if ($dateDebut != null) { if (abs($dateDebut->format('U') - $now->format('U')) > 3600*24*365*3) { throw new PropelException('Erreur: la date de debut ne doit pas être éloignées de plus de 3 ans de la date courante'); } } if ($dateFin != null) { if (abs($dateFin->format('U') - $now->format('U')) > 3600*24*365*3) { throw new PropelException('Erreur: la date de fin ne doit pas être éloignées de plus de 3 ans de la date courante'); } } //on initialise les date clone qui seront manipulés dans l'algoritme, c'est nécessaire pour ne pas modifier les date passée en paramêtre. if ($dateDebut != null) { $dateDebutClone = clone $dateDebut; $dateDebutClone->setTime(0,0); } if ($dateFin != null) { $dateFinClone = clone $dateFin; $dateFinClone->setTime(23,59); } //on commence par supprimer les anciennes entrée $queryDelete = AbsenceAgregationDecompteQuery::create()->filterByEleve($this); if ($dateDebutClone != null) { $queryDelete->filterByDateDemiJounee($dateDebutClone, Criteria::GREATER_EQUAL); } if ($dateFinClone != null) { $queryDelete->filterByDateDemiJounee($dateFinClone, Criteria::LESS_EQUAL); } $queryDelete->delete(); //on supprime le marqueur qui certifie que le calcul pour cet eleve a été terminé correctement AbsenceAgregationDecompteQuery::create()->filterByEleve($this)->filterByMarqueurFinMiseAJour()->delete(); $DMabsenceNonJustifiesCol = $this->getDemiJourneesNonJustifieesAbsence($dateDebutClone,$dateFinClone); $DMabsencesCol = $this->getDemiJourneesAbsence($dateDebutClone,$dateFinClone); $retards = $this->getRetards($dateDebutClone,$dateFinClone); $saisiesCol = clone $this->getAbsenceEleveSaisiesParDate($dateDebutClone, $dateFinClone);//cette collection de saisie va nous permettre de récupérer les notifications et les motifs // préférence admin pour la demi journée $heure_demi_journee = 11; $minute_demi_journee = 50; if (getSettingValue("abs2_heure_demi_journee") != null) { try { $dt_demi_journee = new DateTime(getSettingValue("abs2_heure_demi_journee")); $heure_demi_journee = $dt_demi_journee->format('H'); $minute_demi_journee = $dt_demi_journee->format('i'); } catch (Exception $x) { } } //on initialise le début de l'itération pour creer les entrées si aucune date n'est précisée if ($dateDebutClone == null) { if (!$DMabsencesCol->isEmpty()) { $dateDebutClone= clone $DMabsencesCol->getFirst(null); $dateDebutClone->setTime(0,0); } if (!$retards->isEmpty()) { if ($dateDebutClone == null || $dateDebutClone->format('U') > $retards->getFirst()->getDebutAbs('U')) { $dateDebutClone= clone $retards->getFirst()->getDebutAbs(null); $dateDebutClone->setTime(0,0); } } if ($dateDebutClone != null && abs($dateDebutClone->format('U') - $now->format('U')) > 3600*24*365*3) { $dateDebutClone = new DateTime('@'.($now->format('U') - 3600*24*365*3));//on limite la mise à jour à 4 ans en arrière } } if ($dateDebutClone == null) { //rien à remplir //on va quand même mettre une entrée pour dire qu'on est passé par la pour une vérification ultérieures $newAgregation = new AbsenceAgregationDecompte(); $newAgregation->setEleve($this); if ($dateFinClone != null) { $dateFinClone->setTime(12,0); } else { //on a aucune date ni aucune saisie, on va mettre la date du jour $dateFinClone = new DateTime('now'); $dateFinClone->setTime(0,0); } $newAgregation->setDateDemiJounee($dateFinClone); $newAgregation->save(); } else { $dateDemiJourneeIteration = clone $dateDebutClone; $DMabsencesCol_start_compute = false;//obligatoire pour tester la fin de la collection car le pointeur retourne au début $retards_start_compute = false; //on va creer une collections d'entrées dans la table d'agrégation //dans la boucle while on utilise les tests isFirst pour vérifier qu'on a pas fini les collections et qu'on est pas retourné au début do { $newAgregation = new AbsenceAgregationDecompte(); $newAgregation->setEleve($this); $newAgregation->setDateDemiJounee($dateDemiJourneeIteration); if (($DMabsencesCol->getCurrent() != null) && $dateDemiJourneeIteration->format('d/m/Y H') == $DMabsencesCol->getCurrent()->format('d/m/Y H')) { $DMabsencesCol_start_compute = true; $newAgregation->setManquementObligationPresence(true); $newAgregation->setNonJustifiee(false); $DMabsencesCol->getNext(); //on regarde si l'absence est non justifiée if (($DMabsenceNonJustifiesCol->getCurrent() != null) && $dateDemiJourneeIteration->format('d/m/Y H') == $DMabsenceNonJustifiesCol->getCurrent()->format('d/m/Y H')) { $newAgregation->setNonJustifiee(true); $DMabsenceNonJustifiesCol->getNext(); } //on va voir si il y a eu des motifs et des notifications $date_debut_cherche_motif = clone $dateDemiJourneeIteration; $date_fin_cherche_motif = clone $dateDemiJourneeIteration; if ($dateDemiJourneeIteration->format('H') == 0) { $date_debut_cherche_motif->setTime(0,0); $date_fin_cherche_motif->setTime($heure_demi_journee,$minute_demi_journee); } else { $date_debut_cherche_motif->setTime($heure_demi_journee,$minute_demi_journee); $date_fin_cherche_motif->setTime(23,59); } foreach ($saisiesCol as $saisie) { if ($saisie->getDebutAbs('U') <= $date_fin_cherche_motif->format('U') && $saisie->getFinAbs('U') >= $date_debut_cherche_motif->format('U') && $saisie->getManquementObligationPresence()) { if (!$newAgregation->getNotifiee() && $saisie->getNotifiee()) { $newAgregation->setNotifiee(true); } if ($saisie->getMotif() != null) { foreach ($saisie->getAbsenceEleveTraitements() as $traitement) { if ($traitement->getAbsenceEleveMotif() != null) { $newAgregation->addMotifsAbsence($traitement->getAMotifId()); } } } } } } //on regarde si il y a des retards pendant cette demijournée $date_fin_decompte_retard = clone $dateDemiJourneeIteration; if ($date_fin_decompte_retard->format('H') == 0) { $date_fin_decompte_retard->setTime($heure_demi_journee,$minute_demi_journee); } else { $date_fin_decompte_retard->setTime(23,59); } while ($retards->getCurrent() != null && $retards->getCurrent()->getDebutAbs('U')<$date_fin_decompte_retard->format('U')) { $retards_start_compute = true; $newAgregation->setRetards($newAgregation->getRetards() + 1); if (!$retards->getCurrent()->getJustifiee()) { $newAgregation->setRetardsNonJustifies($newAgregation->getRetardsNonJustifies() + 1); } if ($retards->getCurrent()->getMotif() != null) { foreach ($retards->getCurrent()->getAbsenceEleveTraitements() as $traitement) { if ($traitement->getAbsenceEleveMotif() != null) { $newAgregation->addMotifsRetard($traitement->getAMotifId()); } } } $retards->getNext(); } $newAgregation->save(); $dateDemiJourneeIteration->modify("+12 hours"); } while ( ($dateDemiJourneeIteration->format('U') - $now->format('U') < 3600*24*365*3) //on continue si on est pas trop éloigné dans le futur && (($dateFinClone != null && $dateDemiJourneeIteration <= $dateFinClone)//on continue si on a pas dépassé la date de fin || ($dateFinClone == null && ((!$DMabsencesCol->isFirst() || !$DMabsencesCol_start_compute) || (!$retards->isFirst() || !$retards_start_compute)) ))//ou continue si la date de fin n'est pas précisé et qu'on a pas encore épuisé toutes les absences et retards ); } //on enregistre le marqueur qui certifie que le calcul pour cet eleve a été terminé correctement $newAgregation = new AbsenceAgregationDecompte(); $newAgregation->setEleve($this); $newAgregation->setDateDemiJounee('0001-01-01 00:00:00'); $newAgregation->save(); }