[x] Capitalisation (check)

+ conception BDD (appartenance on enregistre les ue NON CAPITALISÉES)
	+ uniquement pour même (formation + rang + année±1 ) parcours (càd redoublement)
	+ affichage: moyenne UE / "non pris en compte"
		-> semestreRepo::getRedoublements(id_sem) retourne tableau des ID des semestre équivalents
	+ gestion de l'affichage
		+ lien pour capitaliser cet UE quand "non pris en compte"
	+ gestion du calcul de moyenne
		-> pb calcul moyenne semestre (croisement des moyennes)
	+ gestion des valeurs par défaut lors de la création (premier affichage)
		-> on garde normal si aucun UE inactif
		-> et on prend la moyenne de plusieurs si au moins un UE inactif
			-> on met tous les autres UEs (en doublons ducoup) inactifs sauf le dernier
This commit is contained in:
xdrm-brackets 2016-01-08 23:34:17 +01:00
parent 8f14bea624
commit 44555f6156
11 changed files with 341 additions and 15 deletions

View File

@ -200,6 +200,26 @@ class careerManager{
break;
/********************************************/
/* modification des capitalisations d'un UE */
/********************************************/
case 'capitaliser': if( permission('admin') ){
$areSetParam = isset($request->etudiant) && isset($request->ue) && isset($request->semestre); // les arguments existent
$etudiantCheck = $areSetParam && checkParam($request->etudiant, 'utilisateur.identifiant'); // identifiant etudiant bon format
$semestreCheck = $etudiantCheck && checkParam($request->semestre, 'auto_increment_id'); // id semestre bon format
$ueCheck = $semestreCheck && checkParam($request->ue, 'auto_increment_id'); // id ue bon format
if( $ueCheck ){ // si tout les paramètres sont bons
$answer->request = DataBase::getInstance()->capitaliserUE($request->ue, $request->semestre, $request->etudiant);
}else
$answer->request = 'param_error';
}else
$answer->request = 'permission_error';
break;
/****************************************************/

View File

@ -309,6 +309,63 @@ class DataBase{
/* effectue la capitalisation de l'ue
* @ue pour le semestre @semestre
* pour l'étudiant @etudiant
*/
public function capitaliserUE($ue, $semestre, $etudiant){
// on vérifie l'existence des paramètres (etudiant, semestre, ue)
if( !semestreRepo::exists($semestre) ) return 'unknown_semestre';
if( !groupRepo::forStudent($etudiant, $semestre) ) return 'unknown_user';
if( !($ueInfo=ueRepo::info($ue)) ) return 'unknown_ue';
// on vérifie que ce semestre a bien l'ue donnée
$UEs = ueRepo::forStudent($etudiant, $semestre);
$UEUIDList = array();
foreach($UEs as $UE)
if( !in_array($UE['id'], $UEUIDList) )
array_push($UEUIDList, $UE['id']);
// si l'UE n'est pas dans ce semestre, on retourne une erreur
if( !in_array($ue, $UEUIDList) ) return 'unknown_ue';
/* [1] On récupère les redoublements de ce semestre
======================================================*/
$redoublements = semestreRepo::getRedoublements($semestre, $etudiant);
/* [2] On retire ceux qui n'ont pas l'UE
======================================================*/
foreach($redoublements as $iter_s=>$SEM){
$listeUEs = ueRepo::forStudent($etudiant, $SEM['id_semestre']);
$hasUE = false;
// on vérifie que le semestre a bien l'UE
foreach($listeUEs as $UE)
if( $UE['id'] == $ue ) $hasUE = true;
// s'il n'a pas l'UE, on le supprime
if( !$hasUE ) unset($redoublements[$iter_s]);
}
/* [3] On applique les modifications
======================================================*/
$checker = true;
// on définit l'UE comme actif
$checker = $checker && ueRepo::capitalisation($semestre, $etudiant, $ue, true);
// on définit l'UE dans les autres semestres comme inactif
foreach($redoublements as $red)
$checker = $checker && ueRepo::capitalisation($red['id_semestre'], $etudiant, $ue, false);
return ($checker) ? 'success' : 'error';
}
/*************************************************************************************/
/* _ _ _______ _____ _ _____ _____ _______ ______ _ _ _____ */
/* | | | |__ __|_ _| | |_ _|/ ____| /\|__ __| ____| | | | __ \ */
@ -1004,9 +1061,25 @@ class DataBase{
$parcours = semestreRepo::getParcours($etudiantUID);
// contiendra les couples [id_formation, rang] pour les semestres capitalisables
$listeSemestresCapitalisables = array();
/* [1] Chaque semestre
==========================*/
foreach($parcours as $iter_s=>$semestre){
// on récupère les id des UEs non pris en compte
$inactiveUE = explode(',', $semestre['inactive']);
// on supprime les entrées vides
foreach($inactiveUE as $i=>$UE)
if( strlen($UE) == 0 )
unset($inactiveUE[$i]);
// si des UEs non pris en compte, on ajoute le rang+formation à la liste
if( count($inactiveUE) > 0 )
if( !in_array( array($semestre['id_formation'], $semestre['rang']), $listeSemestresCapitalisables) )
array_push($listeSemestresCapitalisables, array($semestre['id_formation'], $semestre['rang']));
$parcours[$iter_s]['UEs'] = ueRepo::forStudent($etudiantUID, $semestre['id']);
/* CALCUL DE MOYENNE DU SEMESTRE */
@ -1060,14 +1133,15 @@ class DataBase{
$parcours[$iter_s]['UEs'][$iter_ue]['moyenne'] = array('moyenne' => 20*$moyenneUE/$totalUE, 'base' => 20 );
// on complète la moyenne du semestre si l'UE a une moyenne
// on complète la moyenne du semestre
// SI l'UE a une moyenne
$tmpUE = $parcours[$iter_s]['UEs'][$iter_ue];
if( !is_bool($tmpUE['moyenne']) ){
$moyenneSemestre += $tmpUE['moyenne']['moyenne']/$tmpUE['moyenne']['base'] * $tmpUE['coefficient'];
$totalSemestre += $tmpUE['coefficient'];
// le semestre est non compensable si la moyenne d'au moins un UE < 8
// le semestre est non compensable si la moyenne d'au moins un UE < 8
if( 20*$tmpUE['moyenne']['moyenne']/$tmpUE['moyenne']['base'] < 8 )
$semestreCompensable = false;
@ -1080,10 +1154,15 @@ class DataBase{
/* ENREGISTREMENT DE LA MOYENNE DU SEMESTRE */
// on enregistre les valeurs du calcul pour pouvoir calculer avec compensation
$parcours[$iter_s]['calculMoyenne'] = array( 'sum' => $moyenneSemestre, 'count' => $totalSemestre );
if( $totalSemestre == 0 ) // si la somme vaut 0, on retourne FALSE
$parcours[$iter_s]['moyenne'] = false;
else
else{
// on enregistre la moyenne
$parcours[$iter_s]['moyenne'] = array('moyenne' => 20*$moyenneSemestre/$totalSemestre, 'base' => 20 );
}
$parcours[$iter_s]['compensable'] = $semestreCompensable;
@ -1093,6 +1172,79 @@ class DataBase{
else
$parcours[$iter_s]['compensation'] = false;
// on met la liste des id d'ue inactifs sous forme de tableau
$parcours[$iter_s]['inactive'] = $inactiveUE;
}
/* LISTE DES UES CAPITALISÉES PAR SEMESTRES REGROUPÉS (FORMATION+RANG) */
// On ajoute toutes les UE capitalisées
foreach($listeSemestresCapitalisables as $i=>$formationRang){
// pour cette formation+rang, on récupère toutes les UEs
$listeUEs = array();
$UEUIDS = array();
$listeSemestresIndexes = array();
foreach($parcours as $iter_s=>$semestre){
// si fait partie de la formation+rang courante
if( $formationRang == array( $semestre['id_formation'], $semestre['rang'] ) ){
// on ajoute l'index du semestre à la liste
array_push($listeSemestresIndexes, $iter_s);
// on ajoute chaque UE de ce semestre s'il est actif
foreach($semestre['UEs'] as $UE)
if( !in_array($UE['id'], $semestre['inactive']) ){
if( ($lastUEIndex=array_search($UE['id'], $UEUIDS)) === false ){
array_push( $listeUEs, $UE );
array_push( $UEUIDS, $UE['id'] );
}else // si UE existe déjà pour formation+rang, on créé la capitalisation du semestre (on le désactive)
DataBase::getInstance()->capitaliserUE($UEUIDS[$lastUEIndex], $semestre['id'], $etudiantUID);
}
}
}
// variables utiles pour la moyenne
$moyenneSemestre = 0; $totalSemestre = 0;
$semestreCompensable = true; $semestreCompensation = true;
// pour chaque UE capitalisée
foreach($listeUEs as $iter_ue=>$UE){
// si l'UE a une moyenne
if( !is_bool($UE['moyenne']) ){
$moyenneSemestre += $UE['moyenne']['moyenne']/$UE['moyenne']['base'] * $UE['coefficient'];
$totalSemestre += $UE['coefficient'];
// le semestre est non compensable si la moyenne d'au moins un UE < 8
if( 20*$UE['moyenne']['moyenne']/$UE['moyenne']['base'] < 8 )
$semestreCompensable = false;
// semestreCompensé est VRAI si au moins un semestre est entre 8 et 10
if( 20*$UE['moyenne']['moyenne']/$UE['moyenne']['base'] >= 8 && 20*$UE['moyenne']['moyenne']/$UE['moyenne']['base'] < 10 )
$semestreCompensation = true;
}
}
// attribution des moyennes aux semestres concernés
foreach($listeSemestresIndexes as $index){
if( $totalSemestre > 0 )
$parcours[$index]['moyenne'] = array( 'moyenne' => 20*$moyenneSemestre/$totalSemestre, 'base' => 20 );
else
$parcours[$index]['moyenne'] = array( 'moyenne' => 0, 'base' => 20 );
// on met à jour le semestre compensable, et compensation
$parcours[$index]['compensable'] = $semestreCompensable;
$parcours[$index]['compensation'] = $semestreCompensation;
}
}
return $parcours;

View File

@ -232,7 +232,7 @@ class groupRepo{
ORDER BY g.nom");
$getGroupe->execute(array( ':etudiant' => $etudiant, ':semestre' => $semestre ));
return DataBase::delNumeric( $getGroupe->fetch(), true );
return $getGroupe->fetch();
}

View File

@ -258,7 +258,7 @@ class semestreRepo{
*
*/
public static function getParcours($etudiant){
$getSemestreListe = DataBase::getPDO()->prepare("SELECT DISTINCT s.id_semestre as id, f.id_formation, f.code, f.nom as formation, f.nb_semestres, s.nom as semestre, s.rang, s.annee, app.mention
$getSemestreListe = DataBase::getPDO()->prepare("SELECT DISTINCT s.id_semestre as id, f.id_formation, f.code, f.nom as formation, f.nb_semestres, s.nom as semestre, s.rang, s.annee, app.mention, app.inactive
FROM formation as f, semestre as s, appartenance as app
WHERE s.id_formation = f.id_formation
AND app.id_semestre = s.id_semestre
@ -568,4 +568,47 @@ class semestreRepo{
return $prev;
}
/* RETOURNE LES SEMESTRES EQUIVALENTS (REDOUBLÉS)
*
* @semestre<int> UID du semestre de base
* @etudiant<String> UID de l'étudiant en question
*
*
* @return redoublements<Array> Retourne un tableau contenant les UIDs des semestre équivalents
* @return error<Boolean> Retourne FAUX si une erreur occure
*
*/
public static function getRedoublements($semestre, $etudiant){
/* [1] On récupère les informations du semestre
=================================================*/
$getSemestreInfo = DataBase::getPDO()->prepare("SELECT DISTINCT s.*
FROM semestre as s, appartenance as app
WHERE s.id_semestre = app.id_semestre
AND s.id_semestre = :semestre
AND app.id_etudiant = :etudiant");
$getSemestreInfo->execute(array( ':semestre' => $semestre, ':etudiant' => $etudiant ));
// aucun résultat, on retourne une erreur
if( !($semestreInfo=$getSemestreInfo->fetch()) ) return 'unknown_semestre';
/* [2] On cherche les semestre redoublés
=================================================*/
$getRedoublements = DataBase::getPDO()->prepare("SELECT s.id_semestre
FROM semestre as s, appartenance as app
WHERE s.id_semestre = app.id_semestre
AND s.id_formation = :formation
AND s.rang = :rang
AND app.id_etudiant = :etudiant
AND s.id_semestre <> :semestre
ORDER BY s.annee, s.rang ASC");
$getRedoublements->execute(array(
':formation' => $semestreInfo['id_formation'],
':rang' => $semestreInfo['rang'],
':etudiant' => $etudiant,
':semestre' => $semestre
));
return $getRedoublements->fetchAll();
}
}

View File

@ -56,7 +56,7 @@ class ueRepo extends DBAccess{
*
*/
public static function forStudent($etudiant, $semestre){
// on récupère les modules
// on récupère les UEs
$getUesForStudent = DataBase::getPDO()->prepare("SELECT DISTINCT ue.id_ue as id, s.id_semestre, s.nom as semestre, s.annee, ue.nom, ue.libelle, mcc_ue.coefficient
FROM appartenance as app, semestre as s, mcc_ue, ue
WHERE app.id_semestre = s.id_semestre
@ -247,4 +247,62 @@ class ueRepo extends DBAccess{
}
/* DEFINIT SI UN UE EST PRIS EN COMPTE OU NON (CAPITALISATION)
*
* @semestre<int> UID du semestre en question
* @etudiant<String> UID de l'étudiant en question
* @ue<int> UID de l'UE en question
* @active<Boolean> VRAI si on veut qu'il soit pris en compte, NON sinon
*
*
* @return state<Boolean> VRAI si les changements sont pris en compte, sinon FAUX
*
*/
public static function capitalisation($semestre, $etudiant, $ue, $active){
/* [1] On récupère l'appartenance
==========================================================================*/
$getUEState = DataBase::getPDO()->prepare("SELECT *
FROM appartenance
WHERE id_semestre = :semestre
AND id_etudiant = :etudiant");
$getUEState->execute(array( ':semestre' => $semestre, ':etudiant' => $etudiant ));
// si on trouve aucune appartenance, on retourne FAUX
if( !($ueState=$getUEState->fetch()) ) return false;
$stateArray = explode(',', $ueState['inactive'] );
// on supprime les entrées vides
foreach($stateArray as $i=>$state)
if( strlen($state) == 0 )
unset($stateArray[$i]);
/* [2] On met à jour "inactive" pour enlever ou mettre l'UE
==========================================================================*/
if( $active && in_array($ue, $stateArray) ) // si on doit enlever l'ue et qu'il y est
array_splice($stateArray, array_search($ue, $stateArray), 1 ); // => on enleve l'ue
if( !$active && !in_array($ue, $stateArray) ) // si on doit ajouter l'ue et qu'il n'y est pas encore
array_push($stateArray, $ue); // => on ajoute l'ue
$stateString = implode(',', $stateArray);
/* [3] On met à jour dans la base de données
==========================================================================*/
$setUEState = DataBase::getPDO()->prepare("UPDATE appartenance
SET inactive = :uestate
WHERE id_appartenance = :appartenance");
$setUEState->execute(array( ':uestate' => $stateString, ':appartenance' => $ueState['id_appartenance'] ));
/* [4] On vérifie que la modification a bien été faite
==========================================================================*/
$getVerifState = DataBase::getPDO()->prepare("SELECT inactive FROM appartenance WHERE id_appartenance = :appartenance");
$getVerifState->execute(array( ':appartenance' => $ueState['id_appartenance'] ));
if( !($verifState=$getVerifState->fetch()) ) return false;
return $verifState['inactive'] == $stateString;
}
}

View File

@ -746,8 +746,38 @@ if( importNotes.length > 0 ){
}
/****************************************/
/* GESTION DE LA CAPITALISATION D'UN UE */
/****************************************/
var capitalisationUE = document.querySelectorAll('.capitalisation_ue[data-stre][data-ue][data-etu]');
// si il y en a sur la page
if( capitalisationUE.length > 0 ){
for( var i = 0 ; i < capitalisationUE.length ; i++ ){
capitalisationUE[i].addEventListener('click', function(e){
// on créé la requête
request = {
level_0: 'career',
level_1: 'capitaliser',
semestre: e.target.dataset.stre,
ue: e.target.dataset.ue,
etudiant: e.target.dataset.etu
};
// on envoie la requête
API.send(request, function(answer){
if( answer.request == 'success' ) reload();
else makeBounce(e.target);
});
}, false);
}
}

View File

@ -1113,7 +1113,7 @@ if( (permission('master') || permission('admin')) && $etudiantOpt != null ){
$request->etudiant = $etudiantOpt;
careerManager::switch_level_1($request, $answer);
if( $answer->request == 'success' ){ // si on a bien récupéré les UE/notes
////////////////////////////////////////////////////////////////////////////////
echo "<section name='studentcase' data-title='Dossier étudiant' class='basic'>";
@ -1182,21 +1182,31 @@ if( (permission('master') || permission('admin')) && $etudiantOpt != null ){
/* MOYENNE MODULE */
if( is_bool($module['moyenne']) ) // si aucune note pour ce controle on affiche 'Pas de note'
echo "<td colspan=1><span class='link stressed' style='padding:.5em 1em; background:white;'>Pas de moyenne</span></td>";
echo "<td colspan=1><span class='link inactive stressed' style='padding:.5em 1em; background:white;'>Pas de moyenne</span></td>";
else // si une note, alors on l'affiche
echo "<td colspan=1><span class='link ".noteToClass($module['moyenne']['moyenne'], $module['moyenne']['base'])."' style='padding:.5em 1em; background:white;'>Moyenne module: <strong>".number_format($module['moyenne']['moyenne'], 2)." <span class=unstressed>/</span> ".$module['moyenne']['base']."</span></strong></td>";
echo "<td colspan=1><span class='link inactive ".noteToClass($module['moyenne']['moyenne'], $module['moyenne']['base'])."' style='padding:.5em 1em; background:white;'>Moyenne module: <strong>".number_format($module['moyenne']['moyenne'], 2)." <span class=unstressed>/</span> ".$module['moyenne']['base']."</span></strong></td>";
/* MOYENNE UE */
if( is_bool($UE['moyenne']) ) // si aucune note pour cet UE on affiche 'Pas de moyenne'
echo "<td colspan=1><span class='link stressed' style='padding:.5em 1em; background:white;'>Pas de moyenne</span></td>";
else // si un moyenne, alors on l'affiche
echo "<td colspan=1><span class='link ".noteToClass($UE['moyenne']['moyenne'], $UE['moyenne']['base'])."' style='padding:.5em 1em; background:white;'>Moyenne UE: <strong>".number_format($UE['moyenne']['moyenne'], 2)." <span class=unstressed>/</span> ".$UE['moyenne']['base']."</span></strong></td>";
// si UE non inactif dans la capitalisation, on affiche
if( !in_array($UE['id'], $semestre['inactive']) ){
if( is_bool($UE['moyenne']) ) // si aucune note pour cet UE on affiche 'Pas de moyenne'
echo "<td colspan=1><span class='link inactive stressed' style='padding:.5em 1em; background:white;'>Pas de moyenne</span></td>";
else // si un moyenne, alors on l'affiche
echo "<td colspan=1><span class='link inactive ".noteToClass($UE['moyenne']['moyenne'], $UE['moyenne']['base'])."' style='padding:.5em 1em; background:white;'>Moyenne UE: <strong>".number_format($UE['moyenne']['moyenne'], 2)." <span class=unstressed>/</span> ".$UE['moyenne']['base']."</span></strong></td>";
// UE pas utilisé dans la capitalisation, on affiche pas
}else{ // sert de lien pour l'activer dans la capitalisation
echo "<td colspan=1><span class='link capitalisation_ue' data-stre='".$semestre['id']."' data-ue='".$UE['id']."' data-etu='".$etudiantOpt."' style='padding:.5em 1em; background:white;'>Non pris en compte</span></strong></td>";
}
/* MOYENNE SEMESTRE */
if( is_bool($semestre['moyenne']) ) // si aucune note pour ce semestre on affiche 'Pas de moyenne'
echo "<td colspan=1><span class='link stressed' style='padding:.5em 1em; background:white;'>Pas de moyenne</span></td>";
echo "<td colspan=1><span class='link inactive stressed' style='padding:.5em 1em; background:white;'>Pas de moyenne</span></td>";
else // si un moyenne, alors on l'affiche
echo "<td colspan=1><span class='link ".noteToClassSemestre($semestre['moyenne']['moyenne'], $semestre['moyenne']['base'], $semestre['compensable'], $semestre['compensation'])."' style='padding:.5em 1em; background:white;'>Moyenne semestre: <strong>".number_format($semestre['moyenne']['moyenne'], 2)." <span class=unstressed>/</span> ".$semestre['moyenne']['base']."</span></strong></td>";
echo "<td colspan=1><span class='link inactive ".noteToClassSemestre($semestre['moyenne']['moyenne'], $semestre['moyenne']['base'], $semestre['compensable'], $semestre['compensation'])."' style='padding:.5em 1em; background:white;'>Moyenne semestre: <strong>".number_format($semestre['moyenne']['moyenne'], 2)." <span class=unstressed>/</span> ".$semestre['moyenne']['base']."</span></strong></td>";
echo '</tr>';

Binary file not shown.

BIN
src/files/admin2_import_jury.xlsx Executable file

Binary file not shown.

BIN
src/files/admin2_import_mcc.xlsx Executable file

Binary file not shown.

View File

@ -48,6 +48,19 @@ debug();
// var_dump(DataBase::getInstance()->getSemestreInfoFromTime( strtotime('2017-01-31') ));
// on récupère les année équivalentes (redoublées) pour un semestre
// var_dump( semestreRepo::getRedoublements(252, 'Etud100') );
// 35 = UE1,
// on veut que l'ue d'id 35 compte pour le semestre 252 et que les semestres de même rang et formation soient ignorés
$request = new stdClass; $answer = new stdClass;
$request->level_1 = 'capitaliser';
$request->ue = 35;
$request->semestre = 252;
$request->etudiant = 'Etud100';
careerManager::switch_level_1($request, $answer);
var_dump( $answer );
// $ts = time();
// $date1 = date('Y-m-d', $ts);