Gestion de congé

Eléphant du PHP | 398 Messages

20 juin 2008, 10:59

Yop,
Pour le boulot, je dois développer une petite application de gestion d'absence sous la forme d'un calendrier, afin de remplacer la feuille Excel utilisée.

La calendrier est bien affiché (youhou) mais j ai un soucis dans le cas ou une personne à deux absence dans le mois (pour l'instant l'application est uniquement pour le moins de juin, je ferai les modifs de mois apres).
Pour ce, j ai 3 tables :
cal_user : avec id_user, nom, prenom
cal_motif : code, libelle (num de type d absence, type d'absence)
cal_absence : id_row, id_user, date_debut, date_fin, motif, commentaire (motif correspond au numero de type d'absence).

Le code :
Je fais une première boucle foreach qui liste les différents utilisateurs, dans cette boucle, j ai un for qui permet d afficher les jours du mois, le calendrier étant sur une ligne).
Pour chaque numéro de motif, une couleur est attribué. A coté de ça, j ai une classe qui récupère les infos dans les tables.

La page : (je ne poste que la partie du code concernant les lignes des utilisateurs)
require_once('calendrier.class.php');
$oUser = new Calendrier();

[...]

/********** Boucle "verticale" pour afficher les données des utilisateurs ***************/
foreach($oUser->m_aListeLogin as $calendarByUser){
				
	echo '<tr width="10">';
	echo '<td>';
	$idUser = $calendarByUser['id']; //recuperation de l'ID d'un utilisateur
	echo '<p>'.$calendarByUser['nom'].'&nbsp;'.$calendarByUser['prenom'].'</p></td>';
	
	/** Boucle "horizontale" pour afficher le calendrier **/
	for($jour = 1,$n = $nomJourPremier; $jour <= $nombreJoursMois; $jour++, $n++){

		$nomJour = date("D", mktime(0,0,0,$moisActuel,$jour,$anActuel)); //donne nom du jour en fonction du num du jour passé en parametre
		$nomJourFr = $nomJoursFr[$nomJour];//affichage en FR des nom 
		$weekEnd = array("S","D"); //Stockage des jours fériers		
		
		$date = date("$jour/$moisActuel/$anActuel"); //echo $date;
		//$oUser->_infoUser($idUser); //recuperation des infos
		$oUser->_recupDate($idUser,$jour);
		
		//tableau declaration des couleurs
		$couleur = array( 1 => "#ea1f29", 2 => "#0000FF", 3 => "#00FF00", 4 => "#FF00FF", 5 => "#FFFF00", 6 => "#f48425" );

		//recuperation des dates
		//$dateDeb = date("d",strtotime($oUser->m_aListeDate["date_debut"]));
		//$dateFin = date("d",strtotime($oUser->m_aListeDate["date_fin"]));
		
		echo '<td align="center" ';		
		//Pour les WE, on affiche les cases en gris
		if(in_array($nomJourFr,$weekEnd)){
			echo ' bgcolor="#e3e3e3"';
		}

		//if(($jour >= $dateDeb) && ($jour <= $dateFin)){
			echo ' bgcolor="'.$couleur[$oUser->m_aListeDate['motif']].'" >'.$numAbs['motif'].'</td>';	
		//}//fin if
		//else { echo ' bgcolor="#FFFFFF">'; }
		echo '</td>';
	}//fin for
	echo '</tr>';
}//fin foreach
Et ma classe :
require_once('connexionBD.php');
require_once('absence.class.php');

class Calendrier extends Absence{

    function calendrier() {
	
		$this->m_nAccesBD = new connexionBD();
		$this->m_aListeLogin = $this->_GenereListeLogin('cal_user');
		//$this->m_aListeLogin = $this->_InfoByLogin('cal_absence');
		$this->m_aListeMotif = $this->_GenereListeMotif('cal_motif');
		
        $oldlocale = setlocale(LC_TIME, NULL);
        setlocale(LC_TIME, 'fr_FR');
    }
	function _recupDate($idUser,$date){
		
		$sRequete = 'SELECT * FROM cal_absence WHERE id_user = '.$idUser;
//$sRequete .= ' AND date_debut >to_date(\''.$date.'\',\'dd/mm/yyyy\')  AND date_fin <to_date(\''.$date.'\',\'dd/mm/yyyy\')';
		$this->m_nAccesBD->connexion();
		$rResultatDate = $this->m_nAccesBD->requete($sRequete);
		$this->m_nAccesBD->deconnexion();
		
		$m_aListeDate = array();
		return $this->m_aListeDate = pg_fetch_array($rResultatDate);
		//while($aResultatDate = pg_fetch_assoc($rResultatDate)){
			//return $this->m_aListeDate[$aResultatDate['id_row']] = $aResultatDate;
		//}//fin while
	}
	
	//Fonction qui retourne le motif en fonction du numero de motif de la personne
	function _motifCouleur($num_motif){
	
		$sRequete = "SELECT code,libelle FROM cal_motif WHERE code = '".$num_motif."'";
		if($m_bRequeteValide == true){
			$this->m_nAccesBD->connexion();
			//Récupération de la liste des code ainsi que les libellé associé
			$rResultatMotif = $this->m_nAccesBD->requete($sRequete);
			$this->m_nAccesBD->deconnexion();			
		}
		while ($aResultatMotif = pg_fetch_array($ResultatMotif)) {
			return $this->aResultatMotif = $aResultatMotif['code'];
		}//fin while
	}
}//fin classe
Comme je disais, lorsque l'user n'a qu'une seule absence dans le mois, l' affichage est bon, mais des que ça dépasse ou égale 2 absences, je n affiche pas à récupérer les données.
Je penses que ceci est du à ma fonction qui récupère les données.
Et n'étant pas encore vmt familier avec l'objet, il se peut que je récupère mal aussi les données.

Merci d'avance :)
----------------------------------------------------------------------------------
https://astro-otter.space - Discover wonders and mysteries of Universe

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

20 juin 2008, 12:47

Bonjour,

Mes Remarques:

1. Dans l'instruction :
$oUser->_recupDate($idUser,$jour);

Tu passe le paramètre $jour qui est un entier alors que ta méthode attend une date.

2. La méthode $oUser->_recupDate() retourne un tableau array() qui normalement doit contenir toutes les absences du user. Il faut traiter son résultat par une boucle

3. Dans la méthode $oUser->_recupDate() tu as désactivé la condition sur la date dans la requête SELECT mais elle est importante pour limiter la recherche des absences à une plage de temps
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Eléphant du PHP | 398 Messages

24 juin 2008, 16:17

** EDIT de mon post **

Mon script fonctionne nickel genial...sauf qu'il est lent...Je dois gerer les absences pour 80 personnes à peu pres, donc ça met un peu de temps à s'afficher...juste 87secondes.
Pourriez vous me donner quelques astuces à indiquer à mon code pour l'optimiser afn que l'affichage soit plus rapide svp.
La partie affichage des absences par utilisateurs :
foreach($oUser->m_aListeLogin as &$calendarByUser){
	reset($calendarByUser);
//for($i = 1; $i < count($calendarByUser[$i]); $i++){				
	echo '<tr>';
	echo '<th>';
	$idUser = $calendarByUser['id']; //recuperation de l'ID d'un utilisateur
	echo $calendarByUser['nom'].'&nbsp;'.$calendarByUser['prenom'].'</th>';

	
	/** Boucle "horizontale" pour afficher le calendrier **/
	//for($jour = 1,$n = $nomJourPremier; $jour <= $nombreJoursMois; $jour++, $n++){
	for($jour = 1; $jour <= $nombreJoursMois; $jour++){
		$nomJour = date("D", mktime(0,0,0,$moisActuel,$jour,$anActuel)); //donne nom du jour en fonction du num du jour passé en parametre
		$nomJourFr = $nomJoursFr[$nomJour];//affichage en FR des nom 
		
		$weekEnd = array("S","D"); //Stockage des jours fériers		
		
		if($jour < 10 ) { $jourA = '0'.$jour; } else $jourA = $jour;
		$date = date("$anActuel-$moisActuel-$jourA");//affichage de la date au format jj/mm/aaaa
		//on recupere le numero de motif de l utilisateur en fonction du jour
		
		echo '<td';		
		//Pour les WE, on affiche les cases en gris
		if(in_array($nomJourFr,$weekEnd)){
			echo ' bgcolor="#e3e3e3"';
		}
		//On lance la requete SQL en dehors des WE
		else if($m_aNumMotif = $oUser->_recupMotif($idUser,$date)){
			
			//tableau declaration des couleurs
			$couleur = array(1 => "#ea1f29", 2 => "#0000FF", 3 => "#00FF00", 4 => "#FF00FF", 5 => "#f7f12b", 6 => "#f48425" );
			echo ' bgcolor="'.$couleur[$m_aNumMotif['motif']].'" >';
			echo '<a href ="javascript:window.open(\'modif.php?id_absence='.$m_aNumMotif['id_row'].'\',\'pop1\',\'status=yes,resizable=yes,
scrollbars=yes,width=380,height=470\');void(0);" alt="modification" id="info_bulle" class="info_bulle" />';
			
			/*Affichage des commentaire dans une info-bulle*/
			 echo '<span class="info_bulle">';
				 echo '<span class="header">Commentaire :</span>';
				 echo '<span class="content">'.$m_aNumMotif['comm'].'</span>';
				 echo '<span class="footer"></span>';
			 echo '</span>';			
			 echo '&nbsp;</a>';
		}//fin elseif
		else { echo ' bgcolor="#FFFFFF">'; }
		echo '</td>';
	}//fin for
	echo '</tr>';
}//fin foreach
unset($calendarByUser);
?>
et la méthode de la classe :
    function calendrier() {
	
		$this->m_nAccesBD = new connexionBD();
		$this->m_aListeLogin = $this->_GenereListeLogin('cal_user');
		$this->m_aListeMotif = $this->_GenereListeMotif('cal_motif');
		
        $oldlocale = setlocale(LC_TIME, NULL);
        setlocale(LC_TIME, 'fr_FR');
    }

	function _recupMotif($idUser,$date){
		
		$this->m_bRequeteValide = true;
		$sRequete = 'SELECT id_row,motif,comm FROM cal_absence' ;
		$sRequete .= ' WHERE \''.$date.'\' BETWEEN date_debut AND date_fin';
		$sRequete .= ' AND id_user = '.$idUser; 
		$this->m_nAccesBD->connexion();
		$rNumMotif = $this->m_nAccesBD->requete($sRequete);
		$this->m_nAccesBD->deconnexion();
		
		$m_aResultRow = pg_fetch_assoc($rNumMotif);
	//	while(($date >= $m_aResultRow['date_debut'] ) && ($date <= $m_aResultRow['date_fin'])){
			return $m_aResultRow;
		//}/*
	}
Merci d'avance :).
Modifié en dernier par BaLiSTiK le 24 juin 2008, 16:31, modifié 1 fois.
----------------------------------------------------------------------------------
https://astro-otter.space - Discover wonders and mysteries of Universe

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

24 juin 2008, 16:30

Tu limite l'affichage à 10 par page et tu gère la pagination. Des liens de pages dispo permettront la navigation de page à page et la clause "Limit" dans la requête SELECT permet de réguler le flot d'enregistrement sélectionné.

Côté PHP, tu peux utiliser le vidage du buffer par ob_flush() et flush() pour accélérer l'affichage avant la fin du script.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

ViPHP
ViPHP | 5924 Messages

24 juin 2008, 16:43

sadeq, ta dernière astuce ne marchera pas sur IE, lequel attend d'avoir toutes les données avant d'afficher la page...

Eléphant du PHP | 398 Messages

24 juin 2008, 17:19

Mon chef ne veut pas d'un affichage paginé, il souhaite que tout s'affiche en une fois.
Le soucis sur IE avec la derniere astuce risque de poser soucis car la plupart des users à qui c'est adressé, sont sur IE >_<
----------------------------------------------------------------------------------
https://astro-otter.space - Discover wonders and mysteries of Universe

ViPHP
ViPHP | 2144 Messages

24 juin 2008, 17:28

J'ai l'impression que c'est avant tout un problème d'optimisation, plus qu'une question d'affichage.

Si j'ai bien compris tu lances une requête au serveur pour chaque jour ouvrable de chaques personnes ?? 80 personnes X 20 : 800 requêttes, ça fait beaucoup.

Il vaudrait mieux faire une requête récupérant toutes les données de tout le monde d'un coup et ensuite les parcourir pour gérer l'affichage.

Eléphant du PHP | 398 Messages

24 juin 2008, 17:52

J'ai l'impression que c'est avant tout un problème d'optimisation, plus qu'une question d'affichage.

Si j'ai bien compris tu lances une requête au serveur pour chaque jour ouvrable de chaques personnes ?? 80 personnes X 20 : 800 requêttes, ça fait beaucoup.

Il vaudrait mieux faire une requête récupérant toutes les données de tout le monde d'un coup et ensuite les parcourir pour gérer l'affichage.
C est exactement ça.
Donc pour ça, comme tu dis, là j ai (encore) changé, j ai une methode qui me récupère tout dans un tableau et ensuite je vais devoir faire l'affichage avec toute sortes de boucles.
Donc je reprend petit à petit mais je vois encore un peu flou, notammennt dans le cas ou y a plus d'une absence pour un utilisateur, qui etait mon premier probleme !!
----------------------------------------------------------------------------------
https://astro-otter.space - Discover wonders and mysteries of Universe

Eléphant du PHP | 377 Messages

24 juin 2008, 21:13

Hello
La piste que je suivrais :

Code : Tout sélectionner

Récupérer toutes les absences de tous les employés parcourir les enregistrements pour chaque absence, on a la date de début et la date de fin faire une boucle qui décompte le nombre de jours (du 12 juin au 17 juin par exemple) stocker le jour en question et le motif, exemple : $absences[$id_user][$jour] = $motif } }
à la fin on se retrouve donc avec un tableau qui contient, pour chaque utilisateur, les différents jours où il est absent, avec la raison associée (en supposant que deux absences ne se chevauchent pas pour un même employé ^^)

Ensuite, tu affiches le calendrier de chaque utilisateur : pour chaque jour que tu affiches dans le calendrier, tu vas regarder si il existe dans le tableau $absences
Si oui -> affichage du code couleur idoine
Si non -> affichage dans la couleur par défaut

La seule partie "difficile" dans ce code est la façon de faire "avancer" les jours (au changement de mois etc...) mais si tu nous dis qu'il ne faut le faire que pour un certain mois, aucun souci

J'espère ne pas t'avoir encore plus embrouillé ;)
Petit scarabée deviendra grand

Eléphant du PHP | 398 Messages

26 juin 2008, 14:58

j edite mon post.
Le code fonctionne, mais j'aimerai bien un dernier coup de main. Je voudrai savoir comment faire pour reactualiser le calendrier automatiquement des que la BD est modifiée (genre changement de date par ex') sans avoir à recharger la page...si possible sans passer par AJAX :P
----------------------------------------------------------------------------------
https://astro-otter.space - Discover wonders and mysteries of Universe