<?php
/**
 * @version $Id$
 * @author Thomas Crespin <thomas.crespin@sesamath.net>
 * @copyright Thomas Crespin 2009-2022
 * 
 * ****************************************************************************************************
 * SACoche <https://sacoche.sesamath.net> - Suivi d’Acquisitions de Compétences
 * © Thomas Crespin pour Sésamath <https://www.sesamath.net> - Tous droits réservés.
 * Logiciel placé sous la licence libre Affero GPL 3 <https://www.gnu.org/licenses/agpl-3.0.html>.
 * ****************************************************************************************************
 * 
 * Ce fichier est une partie de SACoche.
 * 
 * SACoche est un logiciel libre ; vous pouvez le redistribuer ou le modifier suivant les termes 
 * de la “GNU Affero General Public License” telle que publiée par la Free Software Foundation :
 * soit la version 3 de cette licence, soit (à votre gré) toute version ultérieure.
 * 
 * SACoche est distribué dans l’espoir qu’il vous sera utile, mais SANS AUCUNE GARANTIE :
 * sans même la garantie implicite de COMMERCIALISABILITÉ ni d’ADÉQUATION À UN OBJECTIF PARTICULIER.
 * Consultez la Licence Publique Générale GNU Affero pour plus de détails.
 * 
 * Vous devriez avoir reçu une copie de la Licence Publique Générale GNU Affero avec SACoche ;
 * si ce n’est pas le cas, consultez : <http://www.gnu.org/licenses/>.
 * 
 */

if(!defined('SACoche')) {exit('Ce fichier ne peut être appelé directement !');}
if(($_SESSION['SESAMATH_ID']==ID_DEMO)&&(empty($_POST['f_action'])||($_POST['f_action']!='Afficher_demandes'))){Json::end( FALSE , 'Action désactivée pour la démo.' );}

$action               = Clean::post('f_action'              , 'texte');          // pour le form_prechoix
$action               = Clean::post('f_quoi'                , 'texte', $action); // pour le form_gestion
$matiere_id           = Clean::post('f_matiere'             , 'entier');
$matiere_nom          = Clean::post('f_matiere_nom'         , 'texte');
$groupe_id            = Clean::post('f_groupe_id'           , 'entier');   // C’est l’id du groupe d’appartenance de l’élève, pas l’id du groupe associé à un devoir
$groupe_type          = Clean::post('f_groupe_type'         , 'lettres');
$groupe_nom           = Clean::post('f_groupe_nom'          , 'texte');
$prof_id              = Clean::post('f_prof'                , 'entier');
$encours              = Clean::post('f_encours'             , 'entier', 1);
$periode              = Clean::post('f_periode'             , 'entier');
$date_debut           = Clean::post('f_date_debut'          , 'date_fr');
$date_fin             = Clean::post('f_date_fin'            , 'date_fr');

$qui                  = Clean::post('f_qui'                 , 'texte');
$date_devoir          = Clean::post('f_date_devoir'         , 'date_fr');
$choix_devoir_visible = Clean::post('f_choix_devoir_visible', 'texte');
$date_devoir_visible  = Clean::post('f_date_devoir_visible' , 'date_fr'); // JJ/MM/AAAA ou rien de transmis
$choix_saisie_visible = Clean::post('f_choix_saisie_visible', 'texte');
$date_saisie_visible  = Clean::post('f_date_saisie_visible' , 'date_fr'); // JJ/MM/AAAA ou rien de transmis
$date_autoeval        = Clean::post('f_date_autoeval'       , 'date_fr');
$description          = Clean::post('f_description'         , 'texte', 60);
$devoir_ids           = Clean::post('f_devoir'              , 'texte', '');
$suite                = Clean::post('f_suite'               , 'texte');
$message              = Clean::post('f_message'             , 'texte');
$devoir_saisie        = Clean::post('devoir_saisie'         , 'entier');

$score                = Clean::post('f_score'               , 'entier'); // entier entre 0 et 100 ou -1 si non évalué
$debut_date           = Clean::post('f_debut_date'          , 'date_sql');
$note_val             = Clean::post('f_note'                , 'texte');

$tab_notes = array_merge( $_SESSION['NOTE_ACTIF'] , array( 'NN' , 'NE' , 'NF' , 'NR' , 'AB' , 'DI' ) ); // , 'PA' , 'X'

$tab_demande_id = array();
$tab_user_id    = array();
$tab_item_id    = array();
$tab_user_item  = array();
// Récupérer et contrôler la liste des items transmis
$tab_ids = Clean::post('ids', array('array',','));
if(count($tab_ids))
{
  foreach($tab_ids as $ids)
  {
    $tab_id = explode('x',$ids);
    $tab_demande_id[] = $tab_id[0];
    $tab_user_id[]    = $tab_id[1];
    $tab_item_id[]    = $tab_id[2];
    $tab_user_item[]  = (int)$tab_id[1].'x'.(int)$tab_id[2];
  }
  $tab_demande_id = array_filter( Clean::map('entier',$tab_demande_id)            ,'positif');
  $tab_user_id    = array_filter( Clean::map('entier',array_unique($tab_user_id)) ,'positif');
  $tab_item_id    = array_filter( Clean::map('entier',array_unique($tab_item_id)) ,'positif');
}
$nb_demandes = count($tab_demande_id);
$nb_users    = count($tab_user_id);
$nb_items    = count($tab_item_id);

// Contrôler la liste des profs transmis
$tab_profs   = array();
$tab_droits  = array( 'v'=>'voir' , 's'=>'saisir' , 'm'=>'modifier' );
$tab_temp    = Clean::post('f_prof_liste', array('array','_'));
$profs_liste = implode('_',$tab_temp);

foreach($tab_temp as $valeur)
{
  $droit   = $valeur[0];
  $id_prof = (int)substr($valeur,1);
  if( isset($tab_droits[$droit]) && ($id_prof>0) && ($id_prof!=$_SESSION['USER_ID']) )
  {
    $tab_profs[$id_prof] = $tab_droits[$droit];
  }
  else
  {
    $profs_liste = str_replace( array( '_'.$valeur , $valeur.'_' , $valeur ) , '' , $profs_liste );
  }
}
$nb_profs   = count($tab_profs);

$tab_types  = array('Classes'=>'classe' , 'Groupes'=>'groupe' , 'Besoins'=>'groupe');
$tab_qui    = array('groupe','select');
$tab_suite  = array('changer_aggree','changer_ready','changer_done');

list($devoir_id,$devoir_groupe_id) = (substr_count($devoir_ids,'_')==1) ? explode('_',$devoir_ids) : array(0,0);

$tab_td_score_bad = array( '<td class="hc'       ,                                                                                                 '</td>' );
$tab_td_score_bon = array( '<td class="hd label' , ' <q class="actualiser"'.infobulle('Actualiser le score (enregistré lors de la demande).').'></q></td>' );

$abonnement_ref = 'demande_evaluation_prof';

if( $choix_devoir_visible && !is_null($date_devoir) )
{
  if($choix_devoir_visible == 'toujours')
  {
    $date_devoir_visible = '00/00/0000'; // sera transformé en NULL pour SQL ; évite un test de transmission négatif
  }
  else if($choix_devoir_visible == 'devoir')
  {
    $date_devoir_visible = $date_devoir;
  }
  else if($choix_devoir_visible == 'lendemain')
  {
    $date_devoir_visible = To::jour_decale( $date_devoir , '+1' , 'fr' );
  }
  else if($choix_devoir_visible == 'veille')
  {
    $date_devoir_visible = To::jour_decale( $date_devoir , '-1' , 'fr' );
  }
}
if( $choix_saisie_visible && !is_null($date_devoir) )
{
  if($choix_saisie_visible == 'toujours')
  {
    $date_saisie_visible = '00/00/0000'; // sera transformé en NULL pour SQL ; évite un test de transmission négatif
  }
  else if($choix_saisie_visible == 'devoir')
  {
    $date_saisie_visible = $date_devoir;
  }
  else if($choix_saisie_visible == 'lendemain')
  {
    $date_saisie_visible = To::jour_decale( $date_devoir , '+1' , 'fr' );
  }
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Fonction utilisée plusieurs fois
// ////////////////////////////////////////////////////////////////////////////////////////////////////

function ajouter_notifications( $listing_abonnes , $tab_item_for_user , $devoir_id , $notification_date , $notification_contenu )
{
  global $abonnement_ref;
  $tab_item_infos = array();
  $tab_abonnes = explode(',',$listing_abonnes);
  foreach($tab_abonnes as $abonne_id)
  {
    foreach($tab_item_for_user[$abonne_id] as $item_id)
    {
      if(!isset($tab_item_infos[$item_id]))
      {
        // Récupérer la référence et le nom de l’item
        $DB_ROW = DB_STRUCTURE_DEMANDE::DB_recuperer_item_infos($item_id);
        $item_ref = ($DB_ROW['ref_perso']) ? $DB_ROW['ref_perso'] : $DB_ROW['ref_auto'] ;
        $tab_item_infos[$item_id] = $DB_ROW['matiere_ref'].'.'.$item_ref.' "'.$DB_ROW['item_nom'].'"';
      }
      $notification_intro = 'Demande '.$tab_item_infos[$item_id].' ';
      DB_STRUCTURE_NOTIFICATION::DB_ajouter_log_attente( $abonne_id , $abonnement_ref , $devoir_id , $notification_date , $notification_intro.$notification_contenu );
    }
  }
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Afficher une liste de demandes
// ////////////////////////////////////////////////////////////////////////////////////////////////////

$selection_matiere = ($matiere_id) ? TRUE : FALSE ;
$selection_groupe  = ($groupe_id)  ? TRUE : FALSE ;

if( ($action=='Afficher_demandes') && ( $matiere_nom || !$selection_matiere ) && ( ( isset($tab_types[$groupe_type]) && $groupe_nom ) || !$selection_groupe ) && ( $periode || ($date_debut && $date_fin) || $encours ) )
{
  if($encours)
  {
    $date_debut_sql = NULL;
    $date_fin_sql   = NULL;
  }
  else
  {
    // Restreindre la recherche à une période donnée, cas d’une date personnalisée (toujours le cas pour une sélection d’élèves)
    if(!$periode)
    {
      // Formater les dates
      $date_debut_sql = To::date_french_to_sql($date_debut);
      $date_fin_sql   = To::date_french_to_sql($date_fin);
      // Vérifier que la date de début est antérieure à la date de fin
      if($date_debut_sql>$date_fin_sql)
      {
        Json::end( FALSE , 'Date de début postérieure à la date de fin !' );
      }
    }
    // Restreindre la recherche à une période donnée, cas d’une période associée à une classe ou à un groupe
    else
    {
      $DB_ROW = DB_STRUCTURE_COMMUN::DB_recuperer_dates_periode( $groupe_id , $periode );
      if(empty($DB_ROW))
      {
        Json::end( FALSE , 'Cette classe et cette période ne sont pas reliées !' );
      }
      // Formater les dates
      $date_debut_sql = $DB_ROW['jointure_date_debut'];
      $date_fin_sql   = $DB_ROW['jointure_date_fin'];
    }
  }
  // Récupérer la liste des élèves concernés
  $DB_TAB = ($selection_groupe) ? DB_STRUCTURE_COMMUN::DB_OPT_eleves_regroupement( $tab_types[$groupe_type] , $groupe_id , 1 /*user_statut*/ , 'nom' /*eleves_ordre*/ )
                                : DB_STRUCTURE_PROFESSEUR::DB_OPT_lister_eleves_professeur( $_SESSION['USER_ID'] , $_SESSION['USER_JOIN_GROUPES'] ) ;
  if(!is_array($DB_TAB))
  {
    Json::end( FALSE , $DB_TAB );  // Aucun élève trouvé. | Aucun élève ne vous est affecté.
  }
  $tab_eleves  = array();
  $tab_autres  = array();
  $tab_groupes = array();
  foreach($DB_TAB as $DB_ROW)
  {
    if( ($selection_groupe) || !isset($tab_eleves[ $DB_ROW['valeur']]) ) // Un élève peut être une classe + un groupe associé au prof ; dans ce cas on ne garde que la 1e entrée (la classe)
    {
      $tab_eleves[ $DB_ROW['valeur']] = $DB_ROW['texte'];
      $tab_autres[ $DB_ROW['valeur']] = $DB_ROW['texte'];
      $tab_groupes[$DB_ROW['valeur']] = ($selection_groupe) ? $groupe_nom : $DB_ROW['optgroup'] ;
    }
  }
  $listing_user_id = implode(',', array_keys($tab_eleves) );
  $DB_TAB = DB_STRUCTURE_DEMANDE::DB_lister_demandes_prof( $prof_id , $matiere_id , $listing_user_id , (bool)$encours /*is_en_cours*/ , $date_debut_sql , $date_fin_sql );
  if(empty($DB_TAB))
  {
    $txt = ($encours) ? 'demande n’a été formulée' : 'demande archivée n’a été trouvée' ;
    Json::end( FALSE , 'Aucune '.$txt.' selon les critères indiqués !' );
  }
  // CAS DES DEMANDES EN COURS
  if($encours)
  {
    $retour = '';
    // Lister les demandes (et les messages associés)
    $fnom_export = 'messages_'.$_SESSION['BASE'].'_'.Clean::fichier($matiere_nom).'_'.Clean::fichier($groupe_nom).'_'.FileSystem::generer_fin_nom_fichier__date_et_alea();
    $messages_html = '<table><thead><tr><th>Matière - Item</th><th>Groupe - Élève</th><th>Message(s)</th></tr></thead><tbody>';
    $csv = new CSV();
    $csv->add( array('Matière','Item Ref','Item Nom','Groupe','Élève','Score','Date','Message') , 2 );
    $tab_demandes = array();
    $tab_statut = array(
      'request' => array( 'br' , 'en attente d’étude'   ),
      'aggree'  => array( 'bj' , 'acceptée, à préparer' ),
      'ready'   => array( 'bv' , 'évaluation prête'     ),
    );
    foreach($DB_TAB as $DB_ROW)
    {
      unset($tab_autres[$DB_ROW['eleve_id']]);
      $tab_demandes[] = $DB_ROW['demande_id'];
      $ids = $DB_ROW['demande_id'].'x'.$DB_ROW['eleve_id'].'x'.$DB_ROW['item_id'];
      $score  = ($DB_ROW['demande_score']!==NULL) ? $DB_ROW['demande_score'] : FALSE ;
      $date   = To::date_sql_to_french($DB_ROW['demande_date']);
      $dest   = ($DB_ROW['prof_id']==$_SESSION['USER_ID']) ? 'vous seul' : ( ($DB_ROW['prof_id']) ? html($DB_ROW['user_nom'].' '.$DB_ROW['user_prenom']) : 'collègues concernés' ) ;
      $input_type = ($prof_id) ? 'checkbox' : 'hidden' ;
      $item_ref = ($DB_ROW['ref_perso']) ? $DB_ROW['ref_perso'] : $DB_ROW['ref_auto'] ;
      $matiere_nom = ($selection_matiere) ? $matiere_nom : $DB_ROW['matiere_nom'] ;
      $commentaire = ($DB_ROW['demande_messages']) ? 'oui '.infobulle($DB_ROW['demande_messages'],TRUE) : 'non' ;
      $document    = ($DB_ROW['demande_doc'])      ? '<a href="'.FileSystem::verif_lien_safe($DB_ROW['demande_doc']).'" target="_blank" rel="noopener noreferrer">oui</a>' : 'non' ;
      $q_saisir = ( $prof_id && ($DB_ROW['demande_score']!==NULL) ) ? '<q class="saisir"'.infobulle('Voir la / les notes pour cet item et éventuellement les modifier.').'></q>' : '' ;
      $messages_html .= '<tr><td>'.html($matiere_nom).'<br>'.html($item_ref).'</td><td>'.html($tab_groupes[$DB_ROW['eleve_id']]).'<br>'.html($tab_eleves[$DB_ROW['eleve_id']]).'</td><td>'.convertCRtoBR(html($DB_ROW['demande_messages'])).'</td></tr>';
      $csv->add( array(
        $matiere_nom,
        $item_ref,
        $DB_ROW['item_nom'],
        $tab_groupes[$DB_ROW['eleve_id']],
        $tab_eleves[$DB_ROW['eleve_id']],
        $score,
        $date,
        $DB_ROW['demande_messages'],
      ) , 1 );
      // Afficher une ligne du tableau 
      $retour .=
        '<tr id="tr_'.$ids.'" data-debut_date="'.$DB_ROW['periode_debut_date'].'">'
      .   '<td class="nu"><input type="'.$input_type.'" name="f_ids" value="'.$ids.'"></td>'
      .   '<td class="label">'.html($matiere_nom).'</td>'
      .   '<td class="label">'.html($item_ref).' '.infobulle($DB_ROW['item_nom'],TRUE).'</td>'
      .   '<td class="label">$'.$DB_ROW['item_id'].'$</td>'
      .   '<td class="label">'.html($tab_groupes[$DB_ROW['eleve_id']]).'</td>'
      .   '<td class="label">'.html($tab_eleves[$DB_ROW['eleve_id']]).'</td>'
      .   str_replace( $tab_td_score_bad , $tab_td_score_bon , Html::td_score( $score , 'score' /*methode_tri*/ , '' /*pourcent*/ ) )
      .   '<td class="label">'.$date.'</td>'
      .   '<td class="label">'.$dest.'</td>'
      .   '<td class="label '.$tab_statut[$DB_ROW['demande_statut']][0].'">'.$tab_statut[$DB_ROW['demande_statut']][1].'</td>'
      .   '<td class="label">'.$commentaire.'</td>'
      .   '<td class="label">'.$document.'</td>'
      .   '<td class="nu">'.$q_saisir.'</td>'
      . '</tr>';
    }
    $messages_html .= '</tbody></table>';
    // Calculer pour chaque item sa popularité (le nb de demandes pour les élèves affichés)
    $listing_demande_id = implode(',', $tab_demandes );
    $DB_TAB = DB_STRUCTURE_DEMANDE::DB_recuperer_item_popularite($listing_demande_id,$listing_user_id);
    $tab_bad = array();
    $tab_bon = array();
    foreach($DB_TAB as $DB_ROW)
    {
      $s = ($DB_ROW['popularite']>1) ? 's' : '' ;
      $tab_bad[] = '<td class="label">$'.$DB_ROW['item_id'].'$</td>';
      $tab_bon[] = '<td class="label" data-text="'.sprintf("%03u",$DB_ROW['popularite']).'">'.$DB_ROW['popularite'].' demande'.$s.'</td>';
    }
    // Enregistrer le csv des demandes
    FileSystem::ecrire_objet_csv( CHEMIN_DOSSIER_EXPORT.$fnom_export.'.csv' , $csv );
    // Inclure dans le retour la liste des élèves sans demandes et le tableau des commentaires
    $chaine_autres = ( $selection_matiere && $selection_groupe ) ? implode('<br>',$tab_autres) : 'sur choix d’une matière et d’un regroupement' ;
    Json::add_tab( array(
      'file' => './force_download.php?fichier='.$fnom_export.'.csv' ,
      'msg'  => $messages_html ,
      'td'   => '<td>'.$chaine_autres.'</td>' ,
      'tr'   => str_replace($tab_bad,$tab_bon,$retour) ,
    ) );
  }
  // CAS DES DEMANDES ARCHIVÉES
  else
  {
    $tab_retour = array();
    $tab_count_demandes = array();
    $tab_count_items    = array();
    foreach($DB_TAB as $DB_ROW)
    {
      unset($tab_autres[$DB_ROW['eleve_id']]);
      $tab_count_demandes[$DB_ROW['matiere_id']][$DB_ROW['eleve_id']][$DB_ROW['demande_id']] = TRUE;
      $tab_count_items[$DB_ROW['matiere_id']][$DB_ROW['eleve_id']][$DB_ROW['item_id']] = TRUE;
      $ids = $DB_ROW['matiere_id'].'x'.$DB_ROW['eleve_id'];
      if(!isset($tab_retour[$ids]))
      {
        $matiere_nom = ($selection_matiere) ? $matiere_nom : $DB_ROW['matiere_nom'] ;
        // Préparer une ligne du tableau 
        $tab_retour[$ids] =
          '<tr>'
        .   '<td class="label">'.html($matiere_nom).'</td>'
        .   '<td class="label">'.html($tab_groupes[$DB_ROW['eleve_id']]).'</td>'
        .   '<td class="label">'.html($tab_eleves[$DB_ROW['eleve_id']]).'</td>'
        .   '<td class="label hc">$count_demandes$</td>'
        .   '<td class="label hc">$count_items$</td>'
        . '</tr>';
      }
    }
    // Y insérer les calculs effectués
    foreach($tab_count_items as $matiere_id => $tab_count_items_matiere)
    {
      foreach($tab_count_items_matiere as $eleve_id => $item_id)
      {
        $ids = $matiere_id.'x'.$eleve_id;
        $count_demandes = array_sum($tab_count_demandes[$matiere_id][$eleve_id]);
        $count_items    = array_sum($tab_count_items[$matiere_id][$eleve_id]);
        $tab_retour[$ids] = str_replace('$count_demandes$',$count_demandes,$tab_retour[$ids]);
        $tab_retour[$ids] = str_replace('$count_items$'   ,$count_items   ,$tab_retour[$ids]);
      }
    }
    // Inclure dans le retour la liste des élèves sans demandes
    $chaine_autres = ( $selection_matiere && $selection_groupe ) ? implode('<br>',$tab_autres) : 'sur choix d’une matière et d’un regroupement' ;
    Json::add_tab( array(
      'td'   => '<td>'.$chaine_autres.'</td>' ,
      'tr'   => implode('',$tab_retour) ,
    ) );
  }
  Json::end( TRUE );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Créer une nouvelle évaluation
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if( ($action=='creer') && in_array($qui,$tab_qui) && ( ($qui=='select') || ( (isset($tab_types[$groupe_type])) && $groupe_id ) ) && $date_devoir && $choix_devoir_visible && $date_devoir_visible && $choix_saisie_visible && $date_saisie_visible && $date_autoeval && $description && in_array($suite,$tab_suite) && $nb_demandes && $nb_users && $nb_items )
{
  $date_devoir_sql         = To::date_french_to_sql($date_devoir);
  $date_devoir_visible_sql = To::date_french_to_sql($date_devoir_visible);
  $date_saisie_visible_sql = To::date_french_to_sql($date_saisie_visible);
  $date_autoeval_sql       = To::date_french_to_sql($date_autoeval);
  // Tester les dates
  $jour_debut_annee_scolaire = To::jour_debut_annee_scolaire('sql');
  $jour_fin_annee_scolaire   = To::jour_fin_annee_scolaire('sql');
  $date_devoir_stamp         = strtotime($date_devoir_sql);
  $date_devoir_visible_stamp = strtotime( !is_null($date_devoir_visible_sql)  ? $date_devoir_visible_sql  : '' );
  $date_saisie_visible_stamp = strtotime( !is_null($date_saisie_visible_sql)  ? $date_saisie_visible_sql  : '' );
  $date_autoeval_stamp       = strtotime( !is_null($date_autoeval_sql) ? $date_autoeval_sql : '' );
  $mini_stamp         = strtotime("-5 month");
  $maxi_stamp         = strtotime("+5 month");
  $maxi_visible_stamp = strtotime("+10 month");
  if( ($date_devoir_sql<$jour_debut_annee_scolaire) || ($date_devoir_sql>$jour_fin_annee_scolaire) )
  {
    Json::end( FALSE , 'Date devoir hors année scolaire ('.To::jour_debut_annee_scolaire('fr').' - '.To::jour_fin_annee_scolaire('fr').') !' );
  }
  if( !is_null($date_saisie_visible_sql) && ( $date_saisie_visible_sql < $date_devoir_sql ) )
  {
    // On autorise une date de visibilité des saisies avant la date du devoir.
    // Par exemple un devoir volontairement daté en fin de période avec des saisies au fur et à mesure.
  }
  if( !is_null($date_saisie_visible_sql) && !is_null($date_devoir_visible_sql) && ( $date_saisie_visible_sql < $date_devoir_visible_sql ) )
  {
    Json::end( FALSE , 'Date visibilité saisies avant date visibilité devoir !' );
  }
  if( ($date_devoir_stamp<$mini_stamp) || ($date_devoir_stamp>$maxi_stamp) )
  {
    Json::end( FALSE , 'Date devoir trop éloignée !' );
  }
  if( !is_null($date_devoir_visible_sql) && ( ($date_devoir_visible_stamp<$mini_stamp) || ($date_devoir_visible_stamp>$maxi_visible_stamp) ) )
  {
    Json::end( FALSE , 'Date visibilité devoir trop éloignée !' );
  }
  if( !is_null($date_saisie_visible_sql) && ( ($date_saisie_visible_stamp<$mini_stamp) || ($date_saisie_visible_stamp>$maxi_visible_stamp) ) )
  {
    Json::end( FALSE , 'Date visibilité saisies trop éloignée !' );
  }
  if( !is_null($date_autoeval_sql) && ( ($date_autoeval_stamp<$mini_stamp) || ($date_autoeval_stamp>$maxi_stamp) ) )
  {
    Json::end( FALSE , 'Date fin auto-évaluation trop éloignée !' );
  }
  if( !is_null($date_autoeval_sql) && !is_null($date_devoir_visible_sql) && (TODAY_SQL<$date_devoir_visible_sql) )
  {
    Json::end( FALSE , 'Auto-évaluation impossible sans visibilité du devoir !' );
  }
  if( !is_null($date_autoeval_sql) && !is_null($date_saisie_visible_sql) && (TODAY_SQL<$date_saisie_visible_sql) )
  {
    Json::end( FALSE , 'Auto-évaluation impossible sans visibilité des saisies !' );
  }
  // Dans le cas d’une évaluation sur une liste d’élèves sélectionnés,
  if($qui=='select')
  {
    // Commencer par créer un nouveau groupe de type "eval", utilisé uniquement pour cette évaluation (c'est transparent pour le professeur) ; y associe automatiquement le prof, en responsable du groupe
    $groupe_id = DB_STRUCTURE_REGROUPEMENT::DB_ajouter_groupe_par_prof( $_SESSION['USER_ID'] , 'eval' /*groupe_type*/ , '' /*groupe_nom*/ , 0 /*niveau_id*/ );
  }
  // Insérer l’enregistrement de l’évaluation
  $doc_sujet   = '';
  $doc_corrige = '';
  $devoir_id = DB_STRUCTURE_PROFESSEUR::DB_ajouter_devoir( $_SESSION['USER_ID'] , $groupe_id , $date_devoir_sql , $description , $date_devoir_visible_sql ,$date_saisie_visible_sql , $date_autoeval_sql , $doc_sujet , $doc_corrige , 0 /*voir_repartition*/ , 0 /*diagnostic*/ , 0 /*pluriannuel*/ , 'nom' /*eleves_ordre*/ , 0 /*$equipe*/ );
  // Affecter tous les élèves choisis (dans le cas d’une évaluation sur une liste d’élèves sélectionnés)
  if($qui=='select')
  {
    DB_STRUCTURE_PROFESSEUR::DB_modifier_liaison_devoir_eleve( $_SESSION['USER_ID'] , $devoir_id , $groupe_id , $tab_user_id , 'creer' );
  }
  // Affecter tous les profs choisis
  if($nb_profs)
  {
    DB_STRUCTURE_PROFESSEUR::DB_modifier_liaison_devoir_prof( $devoir_id , $tab_profs , 'creer' );
  }
  // Insérer les enregistrements des items de l’évaluation
  DB_STRUCTURE_PROFESSEUR::DB_modifier_liaison_devoir_item($devoir_id,$tab_item_id,'creer');
  // Insérer les marqueurs d’évaluation (paniers) pour indiquer au prof les demandes dans le tableau de saisie
  $date_saisie_visible_sql = ( TODAY_SQL < $date_saisie_visible_sql ) ? $date_saisie_visible_sql : NULL ;
  $tab_item_for_user = array();
  $info = 'À saisir ('.To::texte_genre_identite($_SESSION['USER_NOM'],FALSE,$_SESSION['USER_PRENOM'],TRUE).')';
  foreach($tab_user_item as $key)
  {
    list($eleve_id,$item_id) = explode('x',$key);
    DB_STRUCTURE_PROFESSEUR::DB_ajouter_saisie( $_SESSION['USER_ID'] , $eleve_id , $devoir_id , $item_id , $date_devoir_sql , 'PA' , $info , $date_saisie_visible_sql );
    $tab_item_for_user[$eleve_id][] = $item_id;
  }
  // Pour terminer on change le statut des demandes
  // $suite = 'changer_aggree' || 'changer_ready' || 'changer_done'
  $listing_demande_id = implode(',',$tab_demande_id);
  $demande_statut = substr($suite,8);
  DB_STRUCTURE_DEMANDE::DB_modifier_demandes_statut( $listing_demande_id , $demande_statut , $message );
  // Notifications (rendues visibles ultérieurement à cause de la potentielle date de visibilité future du devoir)
  $listing_abonnes = DB_STRUCTURE_NOTIFICATION::DB_lister_destinataires_listing_id( $abonnement_ref , implode(',',$tab_user_id) );
  if($listing_abonnes)
  {
    $notification_date = ( TODAY_SQL < $date_devoir_visible_sql ) ? $date_devoir_visible_sql : NULL ;
    $notification_contenu = 'acceptée.'."\r\n\r\n";
    $notification_contenu.= 'Évaluation "'.$description.'" prévue le '.$date_devoir.' par '.To::texte_genre_identite($_SESSION['USER_NOM'],FALSE,$_SESSION['USER_PRENOM'],TRUE,$_SESSION['USER_GENRE']).'.'."\r\n\r\n";
    $notification_contenu.= ($message) ? 'Commentaire :'."\r\n".$message."\r\n\r\n" : 'Pas de commentaire saisi.'."\r\n\r\n" ;
    $notification_contenu.= 'Y accéder :'."\r\n".Sesamail::adresse_lien_profond('page=evaluation&section=voir&devoir_id='.$devoir_id);
    ajouter_notifications( $listing_abonnes , $tab_item_for_user , $devoir_id , $notification_date , $notification_contenu );
  }
  // Retour
  $groupe_type_initiale = ($qui=='select') ? 'E' : $groupe_type[0] ;
  Json::add_tab( array(
    'devoir_id'   => $devoir_id ,
    'groupe_type' => $groupe_type_initiale ,
    'groupe_id'   => $groupe_id ,
  ) );
  Json::end( TRUE );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Compléter une évaluation existante
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if( ($action=='completer') && in_array($qui,$tab_qui) && ( ($qui=='select') || (isset($tab_types[$groupe_type])) ) && $devoir_id && $devoir_groupe_id && in_array($suite,$tab_suite) && $nb_demandes && $nb_users && $nb_items && $date_devoir && $choix_devoir_visible && $date_devoir_visible && $choix_saisie_visible && $date_saisie_visible && $description )
{
  $date_devoir_sql         = To::date_french_to_sql($date_devoir);
  $date_devoir_visible_sql = To::date_french_to_sql($date_devoir_visible);
  $date_saisie_visible_sql = To::date_french_to_sql($date_saisie_visible);
  // Dans le cas d’une évaluation sur une liste d’élèves sélectionnés
  if($qui=='select')
  {
    // Il faut ajouter tous les élèves choisis
    DB_STRUCTURE_PROFESSEUR::DB_modifier_liaison_devoir_eleve( $_SESSION['USER_ID'] , $devoir_id , $devoir_groupe_id , $tab_user_id , 'ajouter' ); // ($devoir_groupe_id et non $groupe_id qui correspond à la classe d’origine des élèves...)
  }
  // Maintenant on peut modifier les items de l’évaluation
  DB_STRUCTURE_PROFESSEUR::DB_modifier_liaison_devoir_item( $devoir_id , $tab_item_id , 'ajouter' );
  // Insérer les marqueurs d’évaluation (paniers) pour indiquer au prof les demandes dans le tableau de saisie
  $date_saisie_visible_sql = ( TODAY_SQL < $date_saisie_visible_sql ) ? $date_saisie_visible_sql : NULL ;
  $tab_item_for_user = array();
  $info = 'À saisir ('.To::texte_genre_identite($_SESSION['USER_NOM'],FALSE,$_SESSION['USER_PRENOM'],TRUE).')';
  foreach($tab_user_item as $key)
  {
    list($eleve_id,$item_id) = explode('x',$key);
    DB_STRUCTURE_PROFESSEUR::DB_ajouter_saisie( $_SESSION['USER_ID'] , $eleve_id , $devoir_id , $item_id , $date_devoir_sql , 'PA' , $info , $date_saisie_visible_sql );
    $tab_item_for_user[$eleve_id][] = $item_id;
  }
  // Pour terminer on change le statut des demandes
  // $suite = 'changer_aggree' || 'changer_ready' || 'changer_done'
  $listing_demande_id = implode(',',$tab_demande_id);
  $demande_statut = substr($suite,8);
  DB_STRUCTURE_DEMANDE::DB_modifier_demandes_statut( $listing_demande_id , $demande_statut , $message );
  // Notifications (rendues visibles ultérieurement à cause de la potentielle date de visibilité future du devoir)
  $listing_abonnes = DB_STRUCTURE_NOTIFICATION::DB_lister_destinataires_listing_id( $abonnement_ref , implode(',',$tab_user_id) );
  if($listing_abonnes)
  {
    $notification_date = ( TODAY_SQL < $date_devoir_visible_sql ) ? $date_devoir_visible_sql : NULL ;
    $notification_contenu = 'acceptée.'."\r\n\r\n";
    $notification_contenu.= 'Évaluation "'.$description.'" prévue le '.$date_devoir.' par '.To::texte_genre_identite($_SESSION['USER_NOM'],FALSE,$_SESSION['USER_PRENOM'],TRUE,$_SESSION['USER_GENRE']).'.'."\r\n\r\n";
    $notification_contenu.= ($message) ? 'Commentaire :'."\r\n".$message."\r\n\r\n" : 'Pas de commentaire saisi.'."\r\n\r\n" ;
    $notification_contenu.= 'Y accéder :'."\r\n".Sesamail::adresse_lien_profond('page=evaluation&section=voir&devoir_id='.$devoir_id);
    ajouter_notifications( $listing_abonnes , $tab_item_for_user , $devoir_id , $notification_date , $notification_contenu );
  }
  // Retour
  $groupe_type_initiale = ($qui=='select') ? 'E' : $groupe_type[0] ;
  Json::add_tab( array(
    'devoir_id'   => $devoir_id ,
    'groupe_type' => $groupe_type_initiale ,
    'groupe_id'   => $devoir_groupe_id ,
  ) );
  Json::end( TRUE );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Modifier une note saisie
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if( ($action=='modifier_saisie') && $devoir_id && in_array($note_val,$tab_notes) && ($nb_demandes==1) && ($nb_users==1) && ($nb_items==1) && $description )
{
  $eleve_id = $tab_user_id[0];
  $item_id  = $tab_item_id[0];
  $recup_note = DB_STRUCTURE_PROFESSEUR::DB_tester_note_modifiable( $eleve_id , $devoir_id , $item_id );
  if(!$recup_note)
  {
    Json::end( FALSE , 'Note non modifiable (pas de vous ou hors année scolaire) !' );
  }
  if( $recup_note == $note_val )
  {
    Json::end( FALSE , 'Note identique !' );
  }
  $info = $description; // Comporte déjà le nom de l’évaluateur
  $is_modif = DB_STRUCTURE_PROFESSEUR::DB_modifier_saisie( $_SESSION['USER_ID'] , $eleve_id , $devoir_id , $item_id , $note_val , $info );
  if( !$is_modif )
  {
    // normalement on ne peut plus passer ici depuis l’ajout de la vérification précédente
    Json::end( FALSE , 'Note introuvable ou identique !' );
  }
  // Pour terminer on change le statut des demandes
  $listing_demande_id = implode(',',$tab_demande_id);
  $demande_statut = 'done';
  DB_STRUCTURE_DEMANDE::DB_modifier_demandes_statut( $listing_demande_id , $demande_statut , $message );
  // Notifications (rendues visibles ultérieurement à cause de la potentielle date de visibilité future du devoir)
  $listing_abonnes = DB_STRUCTURE_NOTIFICATION::DB_lister_destinataires_listing_id( $abonnement_ref , $eleve_id );
  if($listing_abonnes)
  {
    $tab_item_for_user = array();
    $tab_item_for_user[$eleve_id][] = $item_id;
    $notification_contenu = 'évaluée directement par '.To::texte_genre_identite($_SESSION['USER_NOM'],FALSE,$_SESSION['USER_PRENOM'],TRUE,$_SESSION['USER_GENRE']).'.'."\r\n\r\n";
    $notification_contenu.= 'Y accéder :'."\r\n".Sesamail::adresse_lien_profond('page=evaluation&section=voir&devoir_id='.$devoir_id);
    ajouter_notifications( $listing_abonnes , $tab_item_for_user , $devoir_id , $notification_date , $notification_contenu );
  }
  // Retour
  Json::end( TRUE );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Supprimer de la liste des demandes
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if( ($action=='supprimer') && $nb_demandes )
{
  $listing_demande_id = implode(',',$tab_demande_id);
  DB_STRUCTURE_DEMANDE::DB_supprimer_demandes_devoir($listing_demande_id);
  // Notifications (rendues visibles ultérieurement à cause de la potentielle date de visibilité future du devoir)
  $listing_abonnes = DB_STRUCTURE_NOTIFICATION::DB_lister_destinataires_listing_id( $abonnement_ref , implode(',',$tab_user_id) );
  if($listing_abonnes)
  {
    $tab_item_for_user = array();
    foreach($tab_user_item as $key)
    {
      list($eleve_id,$item_id) = explode('x',$key);
      $tab_item_for_user[$eleve_id][] = $item_id;
    }
    $notification_contenu = 'retirée par '.To::texte_genre_identite($_SESSION['USER_NOM'],FALSE,$_SESSION['USER_PRENOM'],TRUE,$_SESSION['USER_GENRE']).'.'."\r\n\r\n";
    $notification_contenu.= ($message) ? 'Commentaire :'."\r\n".$message."\r\n\r\n" : 'Pas de commentaire saisi.'."\r\n\r\n" ;
    ajouter_notifications( $listing_abonnes , $tab_item_for_user , 0 , NULL , $notification_contenu );
  }
  // Retour
  Json::end( TRUE );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Changer le statut
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if( ( ($action=='changer_request') || ($action=='changer_aggree') || ($action=='changer_ready') || ($action=='changer_done') ) && $nb_demandes )
{
  $listing_demande_id = implode(',',$tab_demande_id);
  $demande_statut = substr($action,8);
  DB_STRUCTURE_DEMANDE::DB_modifier_demandes_statut( $listing_demande_id , $demande_statut , $message );
  // Retour
  Json::end( TRUE );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Actualiser un score
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if( ($action=='actualiser_score') && ($nb_demandes==1) && ($nb_users==1) && ($nb_items==1) && !is_null($score) )
{
  $tab_devoirs = array();
  $DB_TAB = DB_STRUCTURE_DEMANDE::DB_lister_result_eleve_item( $tab_user_id[0] , $tab_item_id[0] , $debut_date , FALSE /*with_saisie_info*/ );
  foreach($DB_TAB as $DB_ROW)
  {
    $tab_devoirs[] = array( 'note'=>$DB_ROW['note'] , 'date'=>$DB_ROW['date'] );
  }
  $score_new = (count($tab_devoirs)) ? OutilBilan::calculer_score( $tab_devoirs , $DB_ROW['calcul_methode'] , $DB_ROW['calcul_limite'] , $debut_date ) : FALSE ;
  if( ( ($score==-1) && ($score_new!==FALSE) ) || ( ($score>=0) && ($score_new!==$score) ) )
  {
    // maj score
    $score_new_bdd = ($score_new!==FALSE) ? $score_new : NULL ;
    DB_STRUCTURE_DEMANDE::DB_modifier_demande_score( $tab_demande_id[0] , $score_new_bdd );
  }
  $score_retour = str_replace( $tab_td_score_bad , $tab_td_score_bon , Html::td_score( $score_new , 'score' /*methode_tri*/ , '' /*pourcent*/ ) );
  Json::end( TRUE , $score_retour );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Voir les évaluations d’un item
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if( ($action=='voir_evaluations') && ($nb_demandes==1) && ($nb_users==1) && ($nb_items==1) )
{
  $DB_TAB = DB_STRUCTURE_DEMANDE::DB_lister_result_eleve_item( $tab_user_id[0] , $tab_item_id[0] , $debut_date , TRUE /*with_saisie_info*/ );
  foreach($DB_TAB as $DB_ROW)
  {
    // On ne permet de modifier une note que si on est l’auteur de la saisie et que c’est au cours de l’année scolaire actuelle.
    $input = ( ( $DB_ROW['date'] < To::jour_debut_annee_scolaire('sql') ) || ( $DB_ROW['prof_id'] != $_SESSION['USER_ID'] ) ) ? '' : '<input type="radio" id="devoir_'.$DB_ROW['devoir_id'].'" name="devoir" value="'.$DB_ROW['devoir_id'].'">' ;
    Json::add_str(
      '<tr>'.
        '<td class="nu">'.$input.'</td>'.
        '<td class="label hc">'.Html::note_image($DB_ROW['note'],'','',FALSE).'</td>'.
        '<td class="label">'.To::date_sql_to_french($DB_ROW['date']).'</td>'.
        '<td class="label">'.html($DB_ROW['saisie_info']).'</td>'.
      '</tr>'
    );
  }
  Json::end( TRUE );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Générer des énoncés (module externe)
// ////////////////////////////////////////////////////////////////////////////////////////////////////

if( ($action=='generer_enonces') && $nb_demandes && $nb_users && $nb_items )
{
  if(empty($_SESSION['MODULE']['GENERER_ENONCE']))
  {
    Json::end( FALSE , 'Pas de module externe enregistré pour traiter cette demande !' );
  }
  $structure_uai = ($_SESSION['WEBMESTRE_UAI']) ? $_SESSION['WEBMESTRE_UAI'] : $_SESSION['SESAMATH_UAI'] ;
  $structure_id  = ($_SESSION['SESAMATH_ID'])   ? $_SESSION['SESAMATH_ID']   : $_SESSION['BASE'] ;
  $structure_nom = ($_SESSION['ETABLISSEMENT']['DENOMINATION']) ? $_SESSION['ETABLISSEMENT']['DENOMINATION'] : ( ($_SESSION['SESAMATH_TYPE_NOM']) ? $_SESSION['SESAMATH_TYPE_NOM'] : $_SESSION['WEBMESTRE_DENOMINATION'] ) ;
  $tab_module = array(
    'structure' => array(
      'uai' => $structure_uai,
      'id'  => $structure_id,
      'nom' => $structure_nom,
    ),
    'devoir' => array(
      'id'       => NULL,
      'groupe'   => NULL,
      'intitule' => NULL,
      'date'     => TODAY_FR,
    ),
    'prof' => array(
      'id'     => $_SESSION['USER_ID'],
      'nom'    => $_SESSION['USER_NOM'],
      'prenom' => $_SESSION['USER_PRENOM'],
    ),
    'item'   => array(),
    'eleve'  => array(),
    'panier' => array(),
  );
  $listing_demande_id = implode(',',$tab_demande_id);
  $DB_TAB = DB_STRUCTURE_DEMANDE::DB_recuperer_demandes_informations( $listing_demande_id );
  foreach($DB_TAB as $DB_ROW)
  {
    $item_ref = ($DB_ROW['item_module']) ? $DB_ROW['item_module'] : ( ($DB_ROW['ref_perso']) ? $DB_ROW['matiere_ref'].'.'.$DB_ROW['ref_perso'] : $DB_ROW['matiere_ref'].'.'.$DB_ROW['ref_auto'] ) ;
    $item_id = (int)$DB_ROW['item_id'];
    $user_id = (int)$DB_ROW['user_id'];
    $tab_module['item'][$item_id] = array(
      'id'  => $item_id,
      'ref' => $item_ref,
      'nom' => $DB_ROW['item_nom'],
    );
    $tab_module['eleve'][$user_id] = array(
      'id'     => $user_id,
      'nom'    => $DB_ROW['user_nom'],
      'prenom' => $DB_ROW['user_prenom'],
    );
    $tab_module['panier'][$user_id][$item_id] = TRUE;
  }
  // enregistrer le fichier
  $fnom_export = $_SESSION['BASE'].'_demandes-evaluations_'.FileSystem::generer_fin_nom_fichier__date_et_alea();
  $fichier_contenu = json_encode($tab_module);
  $fichier_nom = 'export_module_'.$fnom_export.'.json';
  FileSystem::ecrire_fichier( CHEMIN_DOSSIER_EXPORT.$fichier_nom , $fichier_contenu );
  // Retour du lien
  Json::end( TRUE , $_SESSION['MODULE']['GENERER_ENONCE'].'?json='.urlencode(URL_DIR_EXPORT.$fichier_nom) );
}

// ////////////////////////////////////////////////////////////////////////////////////////////////////
// On ne devrait pas en arriver là...
// ////////////////////////////////////////////////////////////////////////////////////////////////////

Json::end( FALSE , 'Erreur avec les données transmises !<br>'.pathinfo(__FILE__,PATHINFO_FILENAME).':'.__LINE__ );

?>
