<?php
//$Id: dossier_message.class.php 4685 2015-04-30 12:30:55Z nmeucci $ 
//gen openMairie le 15/11/2012 18:30

require_once ("../gen/obj/dossier_message.class.php");

class dossier_message extends dossier_message_gen {

    /** @var boolean Les nouvelles actions sont activées sur cet objet */
    var $activate_class_action;

    /**
     * Instance de om_utilisateur
     *
     * @var null
     */
    var $inst_om_utilisateur = null;

    /**
     * Instance de dossier
     *
     * @var null
     */
    var $inst_dossier = null;

    function __construct($id, &$dnu1 = null, $dnu2 = null) {
        // On active les nouvelles actions
        $this->activate_class_action = true;
        //
        $this->constructeur($id);
    }// fin constructeur

    /**
     * Définition des actions disponibles sur la classe.
     *
     * @return void
     */
    function init_class_actions() {
        parent::init_class_actions();

        // ACTION - 000 - ajouter
        // 
        $this->class_actions[0]["condition"] = "is_ajoutable";
        
        // ACTION - 001 - modifier
        // 
        $this->class_actions[1]["condition"] = "is_modifiable";
        
        // ACTION - 002 - supprimer
        //
        $this->class_actions[2]["condition"] = "is_supprimable";

        // ACTION - 010 - marquer comme lu
        //
        $this->class_actions[10] = array(
            "identifier" => "marquer_comme_lu",
            "portlet" => array(
                "type" => "action-direct",
                "libelle" => _("Marquer comme lu"),
                "order" => 30,
                "class" => "lu-16",
            ),
            "view" => "formulaire",
            "method" => "marquer_comme_lu",
            "permission_suffix" => "modifier_lu",
            "condition" => "is_marquable_comme_lu",
        );

        // ACTION - 020 - marquer comme non lu
        //
        $this->class_actions[20] = array(
            "identifier" => "marquer_comme_non_lu",
            "portlet" => array(
                "type" => "action-direct",
                "libelle" => _("Marquer comme non lu"),
                "order" => 30,
                "class" => "nonlu-16",
            ),
            "view" => "formulaire",
            "method" => "marquer_comme_non_lu",
            "permission_suffix" => "modifier_lu",
            "condition" => "is_marquable_comme_non_lu",
        );
    }


    /**
     * CONDITION - is_marquable_comme_lu.
     *
     * Condition pour afficher le bouton marquer comme lu
     *
     * @return boolean
     */
    public function is_marquable_comme_lu() {
        // Si déjà lu
        if ($this->getVal("lu") == "t") {
            return false;
        }
        // Si l'utilisateur est un intructeur qui ne correspond pas à la
        // division du dossier et qu'il n'a pas de bypass
        if (!$this->f->isAccredited("dossier_message_modifier_lu_bypass")
            && $this->f->isUserInstructeur()
            && isset($this->f->om_utilisateur["division"])
            && $this->f->om_utilisateur["division"] != $this->getDivisionFromDossier()) {
            return false;
        }
        // Récupération de l'ID et et de la classe du dossier lié
        $idxformulaire = $this->getParameter("idxformulaire");
        $retourformulaire = $this->getParameter("retourformulaire");
        // Si le dossier d'instruction auquel est rattaché le message
        // est cloturé
        if ($this->is_in_context_of_foreign_key("dossier", $retourformulaire)) {
            // On récupère le statut du dossier d'instruction
            $statut = $this->f->getStatutDossier($idxformulaire);
            if ($this->f->isUserInstructeur() && $statut == "cloture" ){
                return false;
            }
        }
        return true;
    }


    /**
     * CONDITION - is_marquable_comme_non_lu.
     *
     * Condition pour afficher le bouton marquer comme non lu
     *
     * @return boolean
     */
    public function is_marquable_comme_non_lu() {
        // Si déjà non lu
        if ($this->getVal("lu") == "f") {
            return false;
        }
        // Si l'utilisateur est un intructeur qui ne correspond pas à la
        // division du dossier et qu'il n'a pas de bypass
        if (!$this->f->isAccredited("dossier_message_modifier_lu_bypass")
            && $this->f->isUserInstructeur()
            && isset($this->f->om_utilisateur["division"])
            && $this->f->om_utilisateur["division"] != $this->getDivisionFromDossier()) {
            return false;
        }
        // Récupération de l'ID et et de la classe du dossier lié
        $idxformulaire = $this->getParameter("idxformulaire");
        $retourformulaire = $this->getParameter("retourformulaire");
        // Si le dossier d'instruction auquel est rattaché le message
        // est cloturé
        if ($this->is_in_context_of_foreign_key("dossier", $retourformulaire)) {
            // On récupère le statut du dossier d'instruction
            $statut = $this->f->getStatutDossier($idxformulaire);
            if ($this->f->isUserInstructeur() && $statut == "cloture" ){
                return false;
            }
        }
        return true;
    }


    /**
     * TREATMENT - marquer_comme_lu.
     * 
     * Cette methode permet de passer la message en "lu"
     *
     * @return boolean true si maj effectué false sinon
     */
    public function marquer_comme_lu() {
        // Cette méthode permet d'exécuter une routine en début des méthodes
        // dites de TREATMENT.
        $this->begin_treatment(__METHOD__);

        if($this->getVal("lu") == 'f') {
            $this->correct = true;
            $this->valF["lu"] = true;
        
            $res = $this->f->db->autoExecute(
                        DB_PREFIXE.$this->table, 
                        $this->valF, 
                        DB_AUTOQUERY_UPDATE,
                        $this->clePrimaire."=".$this->getVal($this->clePrimaire)
                    );
            if ($this->f->isDatabaseError($res, true)) {
                // Appel de la methode de recuperation des erreurs
                $this->erreur_db($res->getDebugInfo(), $res->getMessage(), '');
                $this->correct = false;
                // Termine le traitement
                return $this->end_treatment(__METHOD__, false);
            } else {
                $this->addToMessage(_("Le message a été marqué comme lu."));
                return $this->end_treatment(__METHOD__, true);
            }

        } else {
            $this->addToMessage(_("Le message est déjà marqué comme lu."));
        }

        // Termine le traitement
        return $this->end_treatment(__METHOD__, false);
    }


    /**
     * TREATMENT - marquer_comme_non_lu.
     * 
     * Cette methode permet de passer la message en "non lu"
     *
     * @return boolean true si maj effectué false sinon
     */
    public function marquer_comme_non_lu() {
        // Cette méthode permet d'exécuter une routine en début des méthodes
        // dites de TREATMENT.
        $this->begin_treatment(__METHOD__);

        if($this->getVal("lu") == 't') {
            $this->correct = true;
            $this->valF["lu"] = false;
        
            $res = $this->f->db->autoExecute(
                        DB_PREFIXE.$this->table, 
                        $this->valF, 
                        DB_AUTOQUERY_UPDATE,
                        $this->clePrimaire."=".$this->getVal($this->clePrimaire)
                    );
            if ($this->f->isDatabaseError($res, true)) {
                // Appel de la methode de recuperation des erreurs
                $this->erreur_db($res->getDebugInfo(), $res->getMessage(), '');
                $this->correct = false;
                // Termine le traitement
                return $this->end_treatment(__METHOD__, false);
            } else {
                $this->addToMessage(_("Le message a été marqué comme non lu."));
                return $this->end_treatment(__METHOD__, true);
            }

        } else {
            $this->addToMessage(_("Le message est déjà marqué comme non lu."));
        }

        // Termine le traitement
        return $this->end_treatment(__METHOD__, false);
    }


    /**
     * CONDITION - is_ajoutable.
     *
     * Condition pour pouvoir ajouter
     *
     * @return boolean
     */
    function is_ajoutable() {
        // Impossible d'ajouter un message manuellement
        return false;
    }

    /**
     * CONDITION - is_modifiable.
     *
     * Condition pour afficher le bouton modifier
     *
     * @return boolean
     */
    function is_modifiable() {
        // Test du bypass
        if ($this->f->isAccredited("dossier_message_modifier_bypass")) {
            return true;
        }
        // Test des autres conditions
        return $this->is_ajoutable_or_modifiable_or_supprimable();
    }

    /**
     * CONDITION - is_supprimable.
     *
     * Condition pour afficher le bouton supprimer
     * @return boolean
     */
    function is_supprimable() {
        // Test du bypass
        if ($this->f->isAccredited("dossier_message_supprimer_bypass")) {
            return true;
        }
        // Test des autres conditions
        return $this->is_ajoutable_or_modifiable_or_supprimable();
    }

    /**
     * Conditions pour afficher les boutons modifier et supprimer
     *
     * @return boolean
     */
    function is_ajoutable_or_modifiable_or_supprimable() {
        //
        $dossier = ($this->getParameter("maj")==0)?$this->getParameter("idxformulaire"):$this->getVal("dossier");
        /**
         * Tester si le dossier est cloturé , de la meme division, instructeur, admin (?)
         */
        if($this->f->isUserInstructeur()
            && isset($this->f->om_utilisateur["division"])
            && $this->f->om_utilisateur["division"] != $this->getDivisionFromDossier()){
            return false;
        }
        //
        if ( $this->f->isUserInstructeur() && $this->f->getStatutDossier($dossier) == "cloture" ){
            return false;
        }
        return true;
    }

    /**
     * Cette variable permet de stocker le résultat de la méthode
     * getDivisionFromDossier() afin de ne pas effectuer le recalcul à chacun de
     * ces appels.
     * @var string Code de la division du dossier en cours
     */
    var $_division_from_dossier = NULL;

    /**
     * Cette méthode permet de récupérer le code de division correspondant
     * au dossier sur lequel on se trouve.
     *
     * @return string Code de la division du dossier en cours
     */
    function getDivisionFromDossier() {
        // Cette méthode peut être appelée plusieurs fois lors d'une requête.
        // Pour éviter de refaire le traitement de recherche de la division
        // alors on vérifie si nous ne l'avons pas déjà calculé.
        if ($this->_division_from_dossier != NULL) {
            // Logger
            $this->addToLog("getDivisionFromDossier(): retour de la valeur déjà calculée - '".$this->_division_from_dossier."'", EXTRA_VERBOSE_MODE);
            // On retourne la valeur déjà calculée
            return $this->_division_from_dossier;
        }

        // Par défaut, on définit la valeur du dossier à NULL
        $dossier = NULL;
        // Test sur le mode et le contexte du formulaire
        if ($this->getParameter("maj") == 0
            && $this->is_in_context_of_foreign_key("dossier", $this->getParameter("retourformulaire"))) {
            // Si on se trouve en mode AJOUT (seul mode où l'enregistrement
            // n'existe pas en base de données) ET que nous nous trouvons
            // dans le contexte d'un dossier d'instruction alors on récupère
            // le numéro de dossier depuis le paramètre 'idxformulaire'
            $dossier = $this->getParameter("idxformulaire");
        } else {
            // Sinon on récupère le numéro de dossier dans le champs dossier de
            // l'enregistrement (en base de données)
            $dossier = $this->getVal("dossier");
        }

        // On appelle la méthode de la classe utils qui renvoi le code de la
        // division d'un dossier, on la stocke pour ne pas refaire le calcul au
        // prochain appel de cette méthode
        $this->_division_from_dossier = $this->f->getDivisionFromDossier($dossier);
        // Logger
        $this->addToLog("getDivisionFromDossier(): retour de la valeur nouvellement calculée - '".$this->_division_from_dossier."'", EXTRA_VERBOSE_MODE);
        // On retourne la valeur retournée
        return $this->_division_from_dossier;

    }

    // }}}

    /**
     * Utilise dans la recherche avance pour remplir le select par
     * le type du message
     */
    function setSelect(&$form, $maj, &$db, $debug) {
        //
        if (file_exists("../sql/".OM_DB_PHPTYPE."/".$this->table.".form.inc.php")) {
            include "../sql/".OM_DB_PHPTYPE."/".$this->table.".form.inc.php";
        } elseif (file_exists ("../sql/".OM_DB_PHPTYPE."/".$this->table.".form.inc")) {
            include "../sql/".OM_DB_PHPTYPE."/".$this->table.".form.inc";
        }

        // import depuis de la BD les types des messages disponibles pour
        // le dossier
        $this->init_select($form, $db, $maj, $debug, "type", $sql_messages_type, null, false);
    }

    public function setType(&$form,$maj) {
        //type
        parent::setType($form, $maj);

        // On cache le dossier
        $form->setType('dossier','hidden');

        // seulement la modification du champ lu est possible en modification
        if ($maj==1){ //modifier
            $form->setType('type','hiddenstatic');
            $form->setType('emetteur','hiddenstatic');
            $form->setType('date_emission','hiddenstatic');
            $form->setType('lu','checkbox');
            $form->setType('contenu','textareahiddenstatic');
            $form->setType('categorie','hiddenstatic');
        }// fin modifier

        // Pour les actions marquer_comme_lu, marquer_comme_non_lu
        if($maj == 10 || $maj == 20) {
            //
            foreach ($this->champs as $value) {
                // Cache tous les champs
                $form->setType($value, 'hidden');
            }
        }
    }


    public function setOnchange(&$form, $maj) {
        parent::setOnchange($form, $maj);

        // JS de contrôle de la date
        $form->setOnchange('date_emission','fdate(this)');
    }


    public function setLib(&$form, $maj) {
        parent::setLib($form, $maj);

        //
        $form->setLib('dossier_message',_('message'));
    }


    /**
     * Surcharge du fil d'ariane en contexte sous-formulaire.
     *
     * @param string $subent Chaîne initiale.
     *
     * @return string
     */
    public function getSubFormTitle($subent) {
        //
        $subent = _("dossiers d'instruction")." -> "._("message")." -> ".$this->getVal('dossier_message');
        //
        return $subent;
    }


    /**
     * Ajoute un message de notification.
     *
     * @param array $val Liste des valeurs.
     *
     * @return boolean
     */
    public function add_notification_message(array $val) {

        // Liste des valeurs nécessaires à la création du message
        $dossier = $val['dossier'];
        $type = $val['type'];
        $emetteur = $val['emetteur'];
        $login = $val['login'];
        $date_emission = $val['date_emission'];
        $contenu = $val['contenu'];

        // Récupère l'identifiant instructeur de l'emetteur
        $inst_om_utilisateur = $this->get_inst_om_utilisateur(0);
        $instructeur = $inst_om_utilisateur->get_instructeur_by_om_utilisateur_login($login);

        // Récupère l'instructeur du dossier
        $inst_dossier = $this->get_inst_dossier($dossier);
        $di_instructeur = $inst_dossier->getVal('instructeur');

        // Vérifie si l'instructeur est affecté au dossier
        $transmitter_is_dossier_instructor = false;
        if ($instructeur !== ''
            && $instructeur !== null
            && $instructeur === $di_instructeur) {
            //
            $transmitter_is_dossier_instructor = true;
        }

        // Requête SQL de recherche des messages
        $sql = 'SELECT count(dossier_message)
                FROM '.DB_PREFIXE.'dossier_message
                WHERE dossier = \''.$dossier.'\'
                AND type = \''.$this->f->db->escapeSimple($type).'\'
                -- Permet de récupérer seulement la date sans l\'\'heure, les minutes et les secondes
                AND date_trunc(\'day\', date_emission) = date_trunc(\'day\', timestamp \''.$date_emission.'\')
                AND emetteur = \''.$this->f->db->escapeSimple($emetteur).'\'';
        // Si l'emetteur n'est pas l'instructeur du dossier
        if ($transmitter_is_dossier_instructor == false) {
            // Vérifie que le message ne soit pas lu
            $sql .= 'AND lu IS FALSE';
        }
        // Log
        $this->f->addToLog(__METHOD__."() : db->getOne(\"".$sql."\")", VERBOSE_MODE);
        // Exécute la requête
        $count = $this->db->getOne($sql);
        // Contrôle les erreurs de base de données
        $this->f->isDatabaseError($count);

        // Si au moins un message identique existe
        if ($count !== '0') {
            // Stop le traitement
            return true;
        }

        // Liste des valeurs
        $val = array();
        $val['dossier_message'] = '';
        $val['dossier'] = $dossier;
        $val['type'] = $type;
        $val['emetteur'] = $emetteur;
        $val['date_emission'] = $date_emission;
        $val['lu'] = $transmitter_is_dossier_instructor;
        $val['contenu'] = $contenu;
        $val['categorie'] = 'interne';
        // Ajoute un message
        $add = $this->ajouter($val);
        // Si une erreur se produit pendant l'ajout
        if ($add !== true) {
            //
            return false;
        }

        //
        return true;
    }


    /**
     * Récupère l'instance de om_utilisateur.
     *
     * @param string $om_utilisateur Identifiant de l'utilisateur.
     *
     * @return object
     */
    private function get_inst_om_utilisateur($om_utilisateur = null) {
        //
        return $this->get_inst_common("om_utilisateur", $om_utilisateur);
    }


    /**
     * Récupère l'instance de dossier.
     *
     * @param string $dossier Identifiant du dossier d'instruction.
     *
     * @return object
     */
    private function get_inst_dossier($dossier = null) {
        //
        return $this->get_inst_common("dossier", $dossier);
    }


}// fin classe
?>