<?php
/**
 * specific :
 * - cle secondaire
 *   destruction autorisée que pour le dernier evenement
 *     [delete the last event ]
 * - variable globale [global variables]
 *     var $retourformulaire;
 *     var $idxformulaire;
 * - modification des données dans dossier trigger avant
 * [modify dossier data with trigger function]
 * - function mois_date : pour ajouter des mois a une date
 *   [add months (delay) and calculation final date]
 * - voir script_lang.js : bible ...
 * 
 * @package openfoncier
 * @version SVN : $Id: instruction.class.php 6178 2016-03-15 10:56:43Z nmeucci $
 */

//
require_once "../gen/obj/instruction.class.php";

//
require_once "../services/outgoing/messageenqueuer.php";

//
class instruction extends instruction_gen {
    
    // Champs contenant les UID des fichiers
    var $abstract_type = array(
        "om_fichier_instruction" => "file",
    );
    
    var $retourformulaire;   // specific
    var $idxformulaire;      // specific
    var $valEvenement;
    var $restriction_valid = null;
    // Tableau contenant une partie des métadonnées arrêtés
    var $metadonneesArrete;

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

    var $metadata = array(
        "om_fichier_instruction" => array(
            "dossier" => "getDossier",
            "dossier_version" => "getDossierVersion",
            "numDemandeAutor" => "getNumDemandeAutor",
            "anneemoisDemandeAutor" => "getAnneemoisDemandeAutor",
            "typeInstruction" => "getTypeInstruction",
            "statutAutorisation" => "getStatutAutorisation",
            "typeAutorisation" => "getTypeAutorisation",
            "dateEvenementDocument" => "getDateEvenementDocument",
            "groupeInstruction" => 'getGroupeInstruction',
            "title" => 'getTitle',
        ),
        "arrete" => array(
            "numArrete" => "getNumArrete",
            "ReglementaireArrete" => "getReglementaireArrete",
            "NotificationArrete" => "getNotificationArrete",
            "dateNotificationArrete" => "getDateNotificationArrete",
            "controleLegalite" => "getControleLegalite",
            "dateSignature" => "getDateSignature",
            "nomSignataire" => "getNomSignataire",
            "qualiteSignataire" => "getQualiteSignataire",
            "ap_numRue" => "getAp_numRue",
            "ap_nomDeLaVoie" => "getAp_nomDeLaVoie",
            "ap_codePostal" => "getAp_codePostal",
            "ap_ville" => "getAp_ville",
            "activite" => "getActivite",
            "dateControleLegalite" => "getDateControleLegalite",
        ),
    );
    /** @var boolean Les nouvelles actions sont activées sur cet objet */
    var $activate_class_action;

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

    // {{{ Gestion de la confidentialité des données spécifiques
    
    /**
     * Définition des actions disponibles sur la classe.
     *
     * @return void
     */
    function init_class_actions() {

        parent::init_class_actions();

        // ACTION - 000 - ajouter
        // Modifie la condition d'affichage du bouton ajouter
        $this->class_actions[0]["condition"] = "is_addable_editable_and_deletable";

        // ACTION - 001 - modifier
        // Modifie la condition et le libellé du bouton modifier
        $this->class_actions[1]["condition"] = array("is_editable", "is_finalizable_without_bypass");
        $this->class_actions[1]["portlet"]["libelle"] = _("Modifier");
        
        // ACTION - 002 - supprimer
        // Modifie la condition et le libellé du bouton supprimer
        $this->class_actions[2]["condition"] = array("is_deletable", "is_finalizable_without_bypass");
        $this->class_actions[2]["portlet"]["libelle"] = _("Supprimer");

        // ACTION - 100 - finaliser
        // Finalise l'enregistrement
        $this->class_actions[100] = array(
            "identifier" => "finaliser",
            "portlet" => array(
                "type" => "action-direct",
                "libelle" => _("Finaliser le document"),
                "order" => 110,
                "class" => "finalise",
            ),
            "view" => "formulaire",
            "method" => "finalize",
            "button" => "finaliser",
            "permission_suffix" => "finaliser",
            "condition" => array("is_finalizable", "is_finalizable_without_bypass", "has_an_edition"),
        );

        // ACTION - 110 - definaliser
        // Finalise l'enregistrement
        $this->class_actions[110] = array(
            "identifier" => "definaliser",
            "portlet" => array(
                "type" => "action-direct",
                "libelle" => _("Reprendre la redaction du document"),
                "order" => 110,
                "class" => "definalise",
            ),
            "view" => "formulaire",
            "method" => "unfinalize",
            "button" => "definaliser",
            "permission_suffix" => "definaliser",
            "condition" => array("is_unfinalizable", "is_unfinalizable_without_bypass"),
        );

        // ACTION - 120 - edition
        // Affiche l'édition
        $this->class_actions[120] = array(
            "identifier" => "edition",
            "portlet" => array(
                "type" => "action-blank",
                "libelle" => _("Edition"),
                "order" => 100,
                "class" => "pdf-16",
            ),
            "view" => "view_edition",
            "condition" => "has_an_edition",
            "permission_suffix" => "om_fichier_instruction_telecharger",
        );

        // ACTION - 125 - modifier_suivi
        // Suivi des dates
        $this->class_actions[125] = array(
            "identifier" => "modifier_suivi",
            "portlet" => array(
                "type" => "action-self",
                "libelle" => _("Suivi des dates"),
                "order" => 125,
                "class" => "suivi-dates-16",
            ),
            "crud" => "update",
            "condition" => array("is_unfinalizable", "is_unfinalizable_without_bypass"),
            "permission_suffix" => "modification_dates",
        );

        // ACTION - 130 - bible
        // Affiche la bible
        $this->class_actions[130] = array(
            "identifier" => "bible",
            "view" => "view_bible",
            "permission_suffix" => "modifier",
        );

        // ACTION - 140 - bible_auto
        // Active la bible automatique
        $this->class_actions[140] = array(
            "identifier" => "bible_auto",
            "view" => "view_bible_auto",
            "permission_suffix" => "modifier",
        );

        // ACTION - 150 - suivi_bordereaux
        // Imprimer un bordereau d'envoi
        $this->class_actions[150] = array(
            "identifier" => "suivi_bordereaux",
            "view" => "view_suivi_bordereaux",
            "permission_suffix" => "consulter",
        );

        // ACTION - 160 - suivi_envoi_lettre_rar
        // Imprimer un bordereau d'envoi
        $this->class_actions[160] = array(
            "identifier" => "suivi_envoi_lettre_rar",
            "view" => "view_suivi_envoi_lettre_rar",
            "permission_suffix" => "consulter",
        );

        // ACTION - 170 - suivi_mise_a_jour_des_dates
        // Mettre à jour les dates de l'instruction
        $this->class_actions[170] = array(
            "identifier" => "suivi_mise_a_jour_des_dates",
            "view" => "view_suivi_mise_a_jour_des_dates",
            "permission_suffix" => "consulter",
        );

        // ACTION - 180 - pdf_lettre_rar
        // Génère PDF sur bordereaux de lettres RAR
        $this->class_actions[180] = array(
            "identifier" => "pdf_lettre_rar",
            "view" => "view_pdf_lettre_rar",
            "permission_suffix" => "consulter",
        );

        // ACTION - 190 - bordereau_envoi_maire
        // Formulaire pour générer le bordereau d'envoi au maire
        // Met à jour la date d'envoi à signature du maire
        $this->class_actions[190] = array(
            "identifier" => "bordereau_envoi_maire",
            "view" => "view_bordereau_envoi_maire",
            "permission_suffix" => "bordereau_envoi_maire",
        );

        // ACTION - 200 - generate_bordereau_envoi_maire
        // Génère PDF bordereau d'envoi au maire
        $this->class_actions[200] = array(
            "identifier" => "generate_bordereau_envoi_maire",
            "view" => "view_generate_bordereau_envoi_maire",
            "permission_suffix" => "bordereau_envoi_maire",
        );

        // ACTION - 210 - notifier_commune
        // Notifie la commune par mail d'un évément d'instruction finalisé
        $this->class_actions[210] = array(
            "identifier" => "notifier_commune",
            "portlet" => array(
                "type" => "action-direct-with-confirmation",
                "libelle" => _("Notifier la commune par courriel"),
                "order" => 210,
                "class" => "notifier_commune-16",
            ),
            "view" => "formulaire",
            "method" => "notifier_commune",
            "permission_suffix" => "notifier_commune",
            "condition" => "is_notifiable",
        );

        // ACTION - 220 - generate_suivi_bordereaux 
        // GÃ©nÃšre PDF bordereaux  
        $this->class_actions[220] = array( 
            "identifier" => "generate_suivi_bordereaux", 
            "view" => "view_generate_suivi_bordereaux", 
            "permission_suffix" => "consulter", 
        ); 
    }

    /**
     * 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->getParameter("retourformulaire") == "dossier"
                || $this->getParameter("retourformulaire") == "dossier_instruction"
                || $this->getParameter("retourformulaire") == "dossier_instruction_mes_encours"
                || $this->getParameter("retourformulaire") == "dossier_instruction_tous_encours"
                || $this->getParameter("retourformulaire") == "dossier_instruction_mes_clotures"
                || $this->getParameter("retourformulaire") == "dossier_instruction_tous_clotures")) {
            // 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;

    }

    /**
     * Cette méthode permet de récupérer le dossier d'autorisation d'un dossier
     */
    function getNumDemandeAutorFromDossier($id) {
        //
        if (!isset($id)) {
            return NULL;
        }
        //
        $sql = "select dossier_autorisation from ".DB_PREFIXE."dossier ";
        $sql .= " where dossier='".$id."'";
        //
        $dossier_autorisation = $this->db->getOne($sql);
        $this->addToLog("getNumDemandeAutorFromDossier(): db->getone(\"".$sql."\")", VERBOSE_MODE);
        database::isError($dossier_autorisation);
        //
        return $dossier_autorisation;
    }

    // }}}

    function setType(&$form, $maj) {
        //
        parent::setType($form, $maj);
        // On cache tous les champs
        // XXX
        $form->setType('complement5_om_html', 'hidden');
        $form->setType('bible5', 'hidden');
        $form->setType('complement6_om_html', 'hidden');
        $form->setType('bible6', 'hidden');
        $form->setType('complement7_om_html', 'hidden');
        $form->setType('bible7', 'hidden');
        $form->setType('complement8_om_html', 'hidden');
        $form->setType('bible8', 'hidden');
        $form->setType('complement9_om_html', 'hidden');
        $form->setType('bible9', 'hidden');
        $form->setType('complement10_om_html', 'hidden');
        $form->setType('bible10', 'hidden');
        $form->setType('complement11_om_html', 'hidden');
        $form->setType('bible11', 'hidden');
        $form->setType('complement12_om_html', 'hidden');
        $form->setType('bible12', 'hidden');
        $form->setType('complement13_om_html', 'hidden');
        $form->setType('bible13', 'hidden');
        $form->setType('complement14_om_html', 'hidden');
        $form->setType('bible14', 'hidden');
        $form->setType('complement15_om_html', 'hidden');
        $form->setType('bible15', 'hidden');
        //
        $form->setType('delai', 'hidden');
        $form->setType('etat', 'hidden');
        $form->setType('accord_tacite', 'hidden');
        $form->setType('action', 'hidden');
        $form->setType('delai_notification', 'hidden');
        $form->setType('avis_decision', 'hidden');
        $form->setType('autorite_competente', 'hidden');
        //
        $form->setType('archive_delai', 'hidden');
        $form->setType('archive_etat', 'hidden');
        $form->setType('archive_accord_tacite', 'hidden');
        $form->setType('archive_avis', 'hidden');
        $form->setType('archive_date_complet', 'hiddendate');
        $form->setType('archive_date_dernier_depot', 'hiddendate');
        $form->setType('archive_date_rejet', 'hiddendate');
        $form->setType('archive_date_limite', 'hiddendate');
        $form->setType('archive_date_notification_delai', 'hiddendate');
        $form->setType('archive_date_decision', 'hiddendate');
        $form->setType('archive_date_validite', 'hiddendate');
        $form->setType('archive_date_achevement', 'hiddendate');
        $form->setType('archive_date_conformite', 'hiddendate');
        $form->setType('archive_date_chantier', 'hiddendate');
        $form->setType('archive_autorite_competente','hidden');
        $form->setType('date_depot','hidden');
        //
        $form->setType('numero_arrete', 'hidden');
        //
        $form->setType('code_barres', 'hidden');
        
        //
        $form->setType('archive_incompletude','hidden');
        $form->setType('archive_incomplet_notifie','hidden');
        $form->setType('archive_evenement_suivant_tacite','hidden');
        $form->setType('archive_evenement_suivant_tacite_incompletude','hidden');
        $form->setType('archive_etat_pendant_incompletude','hidden');
        $form->setType('archive_date_limite_incompletude','hiddendate');
        $form->setType('archive_delai_incompletude','hidden');

        //
        $form->setType('duree_validite','hidden');
        $form->setType('duree_validite_parametrage','hidden');

        //
        $form->setType('created_by_commune','hidden');
        //
        // gestion du champ "finalisé par"
        if ($this->getVal("om_final_instruction") == 't') {
            $form->setType('om_final_instruction_utilisateur', 'static');
        } else {
            $form->setType('om_final_instruction_utilisateur', 'hidden');
        }
        //
        if ($maj < 2 || $maj == 125) { //ajouter, modifier et suivi des dates
            $form->setType('destinataire', 'hidden');
            $form->setType('lettretype', 'hiddenstatic');
            $form->setType('complement_om_html', 'html');
            $form->setType('complement2_om_html', 'html');
            $form->setType('complement3_om_html', 'html');
            $form->setType('complement4_om_html', 'html');
            $form->setType('bible_auto', 'httpclick');
            $form->setType('bible', 'httpclick');
            $form->setType('bible2', 'httpclick');
            $form->setType('bible3', 'httpclick');
            $form->setType('bible4', 'httpclick');
            $form->setType('dossier', 'hidden');   
            $form->setType('libelle', 'hiddenstatic');
            $form->setType('signataire_arrete','select');
            $form->setType('date_envoi_signature','datedisabled');
            $form->setType('date_retour_signature','datedisabled');
            $form->setType('date_envoi_rar','datedisabled');
            $form->setType('date_retour_rar','datedisabled');
            $form->setType('date_envoi_controle_legalite','datedisabled');
            $form->setType('date_retour_controle_legalite','datedisabled');
            $form->setType('date_finalisation_courrier','datedisabled');

            if($maj==0){ // ajouter
                $form->setType('instruction', 'hidden');
                $form->setType('lettretype', 'hidden');
                $form->setType('evenement', 'select');
                $form->setType('date_evenement', 'date2');
            }else{ // modifier et suivi des dates
                $form->setType('instruction', 'hiddenstatic');
                $form->setType('evenement', 'selecthiddenstatic');
                //$form->setType('date_evenement', 'hiddenstaticdate');
                $form->setType('date_evenement', 'date2');
                // necessaire pour calcul de date en modification
                //$form->setType('delai', 'hiddenstatic');
                // les administrateurs technique et fonctionnel peuvent
                // modifier tous les champs de date
                // si l'instruction a déjà été finalisée au moins une fois
                if ($this->f->isAccredited("instruction_modification_dates")
                    && $this->getVal("date_finalisation_courrier") != '') {
                    $form->setType('date_envoi_signature', 'date');
                    $form->setType('date_retour_signature', 'date');
                    $form->setType('date_envoi_rar', 'date');
                    $form->setType('date_retour_rar', 'date');
                    $form->setType('date_envoi_controle_legalite', 'date');
                    $form->setType('date_retour_controle_legalite', 'date');
                    $form->setType('date_finalisation_courrier', 'date');
                    // suivi des dates
                    if ($maj == 125) {
                        $form->setType('date_evenement', 'hiddenstaticdate');
                        $form->setType('complement_om_html', 'hiddenstatic');
                        $form->setType('complement2_om_html', 'hiddenstatic');
                        $form->setType('complement3_om_html', 'hiddenstatic');
                        $form->setType('complement4_om_html', 'hiddenstatic');
                        $form->setType('bible_auto', 'hidden');
                        $form->setType('bible', 'hidden');
                        $form->setType('bible2', 'hidden');
                        $form->setType('bible3', 'hidden');
                        $form->setType('bible4', 'hidden');
                        $form->setType('signataire_arrete','selecthiddenstatic');
                        $form->setType('om_final_instruction_utilisateur', 'hiddenstatic');
                    }
                }
            }
        } elseif($maj==2){
            $form->setType('dossier', 'hidden');
            $form->setType('bible_auto', 'hidden');
            $form->setType('bible', 'hidden');
            $form->setType('bible2', 'hidden');
            $form->setType('bible3', 'hidden');
            $form->setType('bible4', 'hidden');
        }else {
            $form->setType('destinataire', 'hidden');
            $form->setType('dossier', 'hidden');
            $form->setType('bible_auto', 'hidden');
            $form->setType('bible', 'hidden');
            $form->setType('bible2', 'hidden');
            $form->setType('bible3', 'hidden');
            $form->setType('bible4', 'hidden');
        }

        //Cache les champs pour la finalisation
        $form->setType('om_fichier_instruction', 'hidden');
        $form->setType('om_final_instruction', 'hidden');
        // Cache le document arrêté
        $form->setType('document_numerise', 'hidden');
        
        //Masquer les champs date_envoi_controle_legalite et 
        //date_retour_controle_legalite si ce n'est pas un arrêté et si ce n'est
        //pas un utilisateur ayant le droit spécifique
        if ( !is_numeric($this->getVal("avis_decision"))&&
            !$this->f->isAccredited("instruction_modification_dates")){
            
            $form->setType("date_envoi_controle_legalite", "hiddendate");
            $form->setType("date_retour_controle_legalite", "hiddendate");
        }

        // Pour les actions finalize, unfinalize et notifier_commune
        if($maj == 100 || $maj == 110 || $maj == 210) {
            //
            foreach ($this->champs as $value) {
                // Cache tous les champs
                $form->setType($value, 'hidden');
            }
        }
    }

    function setSelect(&$form, $maj,&$db,$debug) {
        /**
         * On ne surcharge pas la méthode parent car une requête sur la table
         * dossier est mauvaise pour les performances, car la requête qui
         * concerne evenement est plus complexe que celle générée et car les
         * champs action, avis_decision et etat ne sont pas utilisés comme des
         * select
         */
        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");

        //// action
        //$this->init_select($form, $db, $maj, $debug, "action",
        //                   $sql_action, $sql_action_by_id, false);

        //// avis_decision
        //$this->init_select($form, $db, $maj, $debug, "avis_decision",
        //                   $sql_avis_decision, $sql_avis_decision_by_id, false);

        //// dossier
        //$this->init_select($form, $db, $maj, $debug, "dossier",
        //                   $sql_dossier, $sql_dossier_by_id, false);

        //// etat
        //$this->init_select($form, $db, $maj, $debug, "etat",
        //                   $sql_etat, $sql_etat_by_id, false);

        //// evenement
        //$this->init_select($form, $db, $maj, $debug, "evenement",
        //                   $sql_evenement, $sql_evenement_by_id, false);

        // signataire_arrete
        // si contexte DI
        if ($this->getParameter("retourformulaire") == "dossier"
                || $this->getParameter("retourformulaire") == "dossier_instruction"
                || $this->getParameter("retourformulaire") == "dossier_instruction_mes_encours"
                || $this->getParameter("retourformulaire") == "dossier_instruction_tous_encours"
                || $this->getParameter("retourformulaire") == "dossier_instruction_mes_clotures"
                || $this->getParameter("retourformulaire") == "dossier_instruction_tous_clotures") {
            // on recupère les signataires de la multicollectivité et de celle du DI
            require_once "../obj/dossier_instruction.class.php";
            $di = new dossier_instruction($this->getParameter('idxformulaire'), $db, $debug);
            $sql_signataire_arrete_by_di = str_replace('<collectivite_di>', $di->getVal("om_collectivite"), $sql_signataire_arrete_by_di);
            $this->init_select($form, $db, $maj, $debug, "signataire_arrete",
                $sql_signataire_arrete_by_di, $sql_signataire_arrete_by_id, true);
        } else {
            $this->init_select($form, $db, $maj, $debug, "signataire_arrete",
                $sql_signataire_arrete, $sql_signataire_arrete_by_id, true);
        }

        /**
         * Gestion du filtre sur les événements de workflow disponibles
         * On récupère ici en fonction de l'état du dossier d'instruction en
         * cours et du type du dossier d'instruction en cours la liste
         * événements disponibles.
         */
        if ($maj == 0) {
            // Récupération des événements par une jointure entre la table dossier
            // et la table transition et la table evenement et la table
            // lien_dossier_instruction_type_evenement en fonction de l'identifiant
            // du dossier d'instruction en cours
            $sql = "SELECT
            evenement.evenement,
            evenement.libelle as lib
            FROM ".DB_PREFIXE."dossier
            INNER JOIN ".DB_PREFIXE."lien_dossier_instruction_type_evenement
                ON dossier.dossier_instruction_type=lien_dossier_instruction_type_evenement.dossier_instruction_type
            INNER JOIN ".DB_PREFIXE."evenement
                ON evenement.evenement=lien_dossier_instruction_type_evenement.evenement
            INNER JOIN ".DB_PREFIXE."transition
                ON evenement.evenement = transition.evenement
                AND dossier.etat=transition.etat
            WHERE dossier.dossier='".$this->idxformulaire."' ";

            // Si changement de décision par instructeur commune
            if($this->f->isUserInstructeur() === true
                && $this->f->getDivisionFromDossier($this->idxformulaire) != $_SESSION["division"]
                && $this->f->isInstrCanChangeDecision($this->idxformulaire) === true) {
                $sql .= "AND evenement.type IN ('arrete', 'changement_decision') ";
            }
            $sql .= "ORDER BY evenement.libelle, evenement.action";
            $res = $db->query($sql);
            $this->addToLog("setSelect(): db->query(\"".$sql."\");", VERBOSE_MODE);
            if (database::isError($res)) {
                die($res->getMessage());
            }
            // Remplissage du tableau du select 
            $contenu = array(
                0 => array("",),
                1 => array(_('choisir')." "._('evenement'),)
            );
            while ($row=& $res->fetchRow()) {
                $contenu[0][] = $row[0];
                $contenu[1][] = $row[1];
            }
            $form->setSelect("evenement", $contenu);
        } else {
            $sql = "SELECT
            evenement.libelle as lib
            FROM ".DB_PREFIXE."evenement
            WHERE evenement.evenement=".$this->getVal("evenement")."";
            $res = $db->getone($sql);
            $this->addToLog("setSelect(): db->getone(\"".$sql."\");", VERBOSE_MODE);
            if (database::isError($res)) {
                die($res->getMessage());
            }
            //
            $contenu = array(
                0 => array($this->getVal("evenement"),),
                1 => array($res,)
            );
            $form->setSelect("evenement", $contenu);
        }

        /**
         * Gesion des liens vers la bible
         */
        // lien bible_auto
        $contenu = array(_("automatique"));
        $form->setSelect("bible_auto",$contenu);
        // lien bible1
        $contenu = array(_("bible"));
        $form->setSelect("bible",$contenu);
        // lien bible2
        $contenu = array(_("bible"));
        $form->setSelect("bible2",$contenu);
        // lien bible3
        $contenu = array(_("bible"));
        $form->setSelect("bible3",$contenu);
        // lien bible4
        $contenu = array(_("bible"));
        $form->setSelect("bible4",$contenu);
    }

    function cleSecondaire($id, &$db, $val, $DEBUG) {
        //
        parent::cleSecondaire($id, $db, $val, $DEBUG);
        
        $id = $this->getVal($this->clePrimaire);

        
        //Requête de vérification que cet événement d'instruction n'est pas lié 
        //à la création d'un dossier d'instruction
        $sql = "SELECT demande_type.dossier_instruction_type 
            FROM ".DB_PREFIXE."demande_type
            LEFT JOIN ".DB_PREFIXE."demande
            ON demande.demande_type = demande_type.demande_type
            WHERE demande.instruction_recepisse = ".$id;
        $res = $this->db->getOne($sql);
        $this->addToLog("cleSecondaire(): db->getone(\"".$sql."\");", VERBOSE_MODE);
        if (database::isError($res)) {
            die($res->getMessage());
        }

        // Aucune clé secondaire n'a été trouvée ou c'est un événement sans 
        //création de dossier d'instruction, l'événement d'instruction peut être 
        //supprimé
        if ( $this->correct !== false || $res == null || $res == ""){

            // Requête de vérification que cet événement d'instruction est lié
            // à une demande
            $sql = "SELECT demande
                FROM ".DB_PREFIXE."demande
                WHERE instruction_recepisse = ".$id;
            $res = $this->db->getOne($sql);
            $this->addToLog("cleSecondaire(): db->getone(\"".$sql."\");", VERBOSE_MODE);
            if (database::isError($res)) {
                die($res->getMessage());
            }

            //Si c'est un événement d'instruction lié à une demande
            if ($res != null || $res != ""){
                
                require_once "../obj/demande.class.php";
                $demande = new demande($res, $this->db, DEBUG);

                //On met à jour la demande en supprimant la liaison vers 
                //l'événement d'instruction
                $demande->setParameter("maj", 1);
                $valF = array();
                foreach($demande->champs as $identifiant => $champ) {
                    $valF[$champ] = $demande->val[$identifiant];
                }
                $valF['date_demande']=$demande->dateDBToForm($valF['date_demande']);
                $valF['instruction_recepisse']=NULL;
                $ret = $demande->modifier($valF, $this->db, DEBUG);
            }
                 
            /**
             * Vérification que l'élément supprimé est le dernier pour pouvoir
             * remodifier les données de manière itérative.
             */
            // Initialisation
            $dernierevenement = "";
            // Récupération du dernier élément de la table d'instruction qui
            // concerne le dossier en cours
            $sql = "SELECT max(instruction)
            FROM ".DB_PREFIXE."instruction
            WHERE dossier ='".$this->idxformulaire."'";
            $dernierevenement = $db->getOne($sql);
            $this->addToLog("setSelect(): db->getone(\"".$sql."\");", VERBOSE_MODE);
            if (database::isError($dernierevenement)) {
                die($dernierevenement->getMessage());
            }
            // Si on se trouve effectivement sur le dernier evenement d'instruction
            if ($dernierevenement == $id) {
                // Alors on valide la suppression
                $this->correct = true;
                $this->addToMessage(_('Destruction_chronologique'));
            } else {
                // Alors on annule la suppression
                $this->correct = false;
                $this->addToMessage(_("Seul le dernier evenement d'instruction peut etre supprime."));
            }
        }
    }

    /**
     * Vérification de la possibilité ou non de modifier des dates de suivi
     * @param  string $champ champ date à vérifier
     */
    function updateDate($champ) {
        
        //Si le retourformulaire est "dossier_instruction"
        if ($this->getParameter("retourformulaire") == "dossier"
                || $this->getParameter("retourformulaire") == "dossier_instruction"
                || $this->getParameter("retourformulaire") == "dossier_instruction_mes_encours"
                || $this->getParameter("retourformulaire") == "dossier_instruction_tous_encours"
                || $this->getParameter("retourformulaire") == "dossier_instruction_mes_clotures"
                || $this->getParameter("retourformulaire") == "dossier_instruction_tous_clotures") {

            // Vérification de la possibilité de modifier les dates si déjà éditées
            if($this->valF[$champ] != "" AND !$this->f->user_is_admin) {
                // si l'utilisateur n'est pas un admin
                if($this->getVal($champ) != "" AND $this->getVal($champ) != $this->valF[$champ]) {
                    $this->correct = false;
                    $this->addToMessage(_("Les dates de suivis ne peuvent etre modifiees"));
                }
            }
        }
        
        //
        return true;
    }

    /*Met des valeurs par défaut dans certains des sous-formulaire*/
    function setValsousformulaire(&$form,$maj,$validation,$idxformulaire,$retourformulaire,$typeformulaire){

        //
        $this->retourformulaire=$retourformulaire;
        $this->idxformulaire=$idxformulaire;
        // Ajout
        if ($maj == 0) {
            $form->setVal("destinataire", $idxformulaire);
            $form->setVal("dossier", $idxformulaire);
        }
        //
        $this->set_form_default_values($form, $maj, $validation);
    }

    /**
     *  Permet de pré-remplir les valeurs des formulaires.
     *  
     * @param [object]   $form        formulaire
     * @param [integer]  $maj         mode
     * @param [integer]  $validation  validation
     */
    function set_form_default_values(&$form, $maj, $validation) {

        // Ajout
        if ($maj == 0) {
            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");
            // si contexte DI
            if ($this->getParameter("retourformulaire") == "dossier"
                || $this->getParameter("retourformulaire") == "dossier_instruction"
                || $this->getParameter("retourformulaire") == "dossier_instruction_mes_encours"
                || $this->getParameter("retourformulaire") == "dossier_instruction_tous_encours"
                || $this->getParameter("retourformulaire") == "dossier_instruction_mes_clotures"
                || $this->getParameter("retourformulaire") == "dossier_instruction_tous_clotures") {
                // on recupère les signataires de la multicollectivité et de celle du DI
                require_once "../obj/dossier_instruction.class.php";
                $di = new dossier_instruction($this->getParameter('idxformulaire'), $db, DEBUG);
                $sql = str_replace('<collectivite_di>', $di->getVal("om_collectivite"), $sql_signataire_arrete_defaut_by_di);
            } else {
                $sql = $sql_signataire_arrete_defaut;
            }
            // Date du jour
            $form->setVal("date_evenement", date('Y-m-d'));

            // Exécution de la requête 
            $res = $this->f->db->query($sql);
            $this->f->addToLog("setVal(): db->query(\"".$sql."\");", VERBOSE_MODE);
            if ( database::isError($res)){
                die();
            }
        
            $row = $res->fetchrow(DB_FETCHMODE_ASSOC);
            
            if (isset($row['signataire_arrete']) && is_numeric($row['signataire_arrete'])){
                $form->setVal("signataire_arrete",$row['signataire_arrete']);
            }
        }

        // Ajout et modification
        if ($maj == 0 || $maj == 1 || $maj == 125) {
            $form->setVal("bible_auto","bible_auto()");
            $form->setVal("bible","bible(1)");
            $form->setVal("bible2","bible(2)");
            $form->setVal("bible3","bible(3)");
            $form->setVal("bible4","bible(4)");
        }
    }


    function setLayout(&$form, $maj){
        if ( $maj < 2 OR $maj == 3 OR $maj == 125 ) {
                        /*Champ sur lequel s'ouvre le bloc 1 */
            $form->setBloc('evenement','D',"","col_12");

            $form->setFieldset('evenement','D',_('Evenement'));
            $form->setFieldset('om_final_instruction_utilisateur','F','');
            
            $form->setBloc('om_final_instruction_utilisateur','F');

            $form->setBloc('date_finalisation_courrier','D',"","col_12");

            $form->setFieldset('date_finalisation_courrier','D',_('Dates'));
            $form->setBloc('date_finalisation_courrier','D',"","col_6");
            $form->setBloc('date_envoi_controle_legalite','F');

            $form->setBloc('signataire_arrete','D',"","col_6");
            $form->setBloc('date_retour_controle_legalite','F');
            $form->setFieldset('date_retour_controle_legalite','F','');
            
            $form->setBloc('date_retour_controle_legalite','F');

            $form->setBloc('complement_om_html','D',"","col_12");
            $form->setFieldset('complement_om_html','D',_('Complement'));
            $form->setFieldset('bible','F','');
            $form->setBloc('bible','F');

            $form->setBloc('complement2_om_html','D',"","col_12");
            $form->setFieldset('complement2_om_html','D',_('Complement 2'));
            $form->setFieldset('bible2','F','');
            $form->setBloc('bible2','F');
            
            $form->setBloc('complement3_om_html','D',"","col_12");
            $form->setFieldset('complement3_om_html','D',_('Complement 3'));
            $form->setFieldset('bible3','F','');
            $form->setBloc('bible3','F');
            
            $form->setBloc('complement4_om_html','D',"","col_12");
            $form->setFieldset('complement4_om_html','D',_('Complement 4'));
            $form->setFieldset('bible4','F','');
            $form->setBloc('bible4','F');
        }
    }
    
    function setLib(&$form, $maj) {
        //
        parent::setLib($form, $maj);
        //
        $form->setLib('bible_auto', "");
        $form->setLib('bible', "");
        $form->setLib('bible2', "");
        $form->setLib('bible3', "");
        $form->setLib('bible4', "");
        $form->setLib('om_final_instruction_utilisateur', _("finalise par"));
    }

    function triggerajouter($id, &$db, $val, $DEBUG) {
        /**
         * Le code suivant permet de récupérer des valeurs des tables evenement
         * et dossier pour les stocker dans l'instruction :
         * DEPUIS L'EVENEMENT
         * - action
         * - delai
         * - accord_tacite
         * - etat
         * - avis_decision
         * - delai_notification
         * - lettretype
         * - autorite_competente
         * DEPUIS LE DOSSIER D'INSTRUCTION
         * - archive_delai
         * - archive_accord_tacite
         * - archive_etat
         * - archive_avis
         * - date_complet
         * - date_rejet
         * - date_limite
         * - date_notification_delai
         * - date_decision
         * - date_validite
         * - date_achevement
         * - date_chantier
         * - date_conformite
         * - avis_decision
         */
        // Récupération de tous les paramètres de l'événement sélectionné
        $sql = "SELECT * FROM ".DB_PREFIXE."evenement
        WHERE evenement=".$this->valF['evenement'];
        $res = $db->query($sql);
        $this->addToLog("triggerajouter(): db->query(\"".$sql."\");", VERBOSE_MODE);
        if (database::isError($res)) {
            die($res->getMessage());
        }
        while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
            // Récupération de l'identifiant de l'action
            // si une action est paramétrée dans l'événement
            $this->valF['action'] = NULL;
            if (isset($row['action']) and !empty($row['action'])) {
                $this->valF['action']=$row['action'];
            }
            // Récupération de la valeur du délai
            $this->valF['delai'] = $row['delai'];
            // Récupération de l'identifiant de l'état
            // si un état est paramétré dans l'événement 
            $this->valF['etat']=NULL;
            if (isset($row['etat']) and !empty($row['etat'])) {
                $this->valF['etat']=$row['etat'];
            }
            // Récupération de la valeur d'accord tacite
            $this->valF['accord_tacite']=$row['accord_tacite'];
            // Récupération de la valeur du délai de notification
            $this->valF['delai_notification']=$row['delai_notification'];
            // Récupération de l'identifiant de l'avis
            // si un avis est paramétré dans l'événement 
            $this->valF['avis_decision'] = NULL;
            if(isset($row['avis_decision']) and !empty($row['avis_decision'])) {
                $this->valF['avis_decision']=$row['avis_decision'];
            }
            // Récupération de la valeur de l'autorité compétente
            // si l'autorité compétente est paramétré dans l'événement 
            $this->valF['autorite_competente'] = NULL;
            if(isset($row['autorite_competente']) and !empty($row['autorite_competente'])) {
                $this->valF['autorite_competente']=$row['autorite_competente'];
            }
            // Récupération de la valeur de la lettre type
            $this->valF['lettretype']=$row['lettretype'];
        }
        // Récupération de toutes les valeurs du dossier d'instruction en cours
        $sql = "SELECT * FROM ".DB_PREFIXE."dossier
        WHERE dossier='".$this->valF['dossier']."'";
        $res = $db->query($sql);
        $this->addToLog("triggerajouter(): db->query(\"".$sql."\");", VERBOSE_MODE);
        if (database::isError($res)) {
            die($res->getMessage());
        }
        $row=& $res->fetchRow(DB_FETCHMODE_ASSOC);
        $this->updateArchiveData($row);
                
        // Récupération de la duree de validite du dossier d'autorisation
        $sql = "SELECT duree_validite_parametrage
                FROM ".DB_PREFIXE."dossier_autorisation_type_detaille
                LEFT JOIN ".DB_PREFIXE."dossier_autorisation
                    ON dossier_autorisation.dossier_autorisation_type_detaille = dossier_autorisation_type_detaille.dossier_autorisation_type_detaille
                LEFT JOIN ".DB_PREFIXE."dossier
                    ON dossier.dossier_autorisation = dossier_autorisation.dossier_autorisation
        WHERE dossier.dossier='".$this->valF['dossier']."'";
        $duree_validite_parametrage = $db->getOne($sql);
        $this->addToLog("triggerajouter(): db->getOne(\"".$sql."\");", VERBOSE_MODE);
        database::isError($duree_validite_parametrage);
        if ($duree_validite_parametrage != '') {
            $this->valF['duree_validite_parametrage']= $duree_validite_parametrage;
        }

        // Identifiant du type de courrier
        $idTypeCourrier = '11';
        $idCourrier = str_pad($this->valF["instruction"], 10, "0", STR_PAD_LEFT);
        // Code barres
        $this->valF["code_barres"] = $idTypeCourrier . $idCourrier;
    }
    
    // Test si une restriction est valide
    // return boolean 
    function restrictionIsValid($restriction){
        if($this->restriction_valid != null) {
            return $this->restriction_valid;
        }
        if(empty($restriction)) {
            $this->restriction_valid = true;
            return $this->restriction_valid;
        }
        // Liste des opérateurs possibles sans espace
        $operateurs = array(">=", "<=", "+", "-", "&&", "||", "==", "!=");
        // Liste identique mais avec le marqueur §
        $mark = "§";
        $operateurs_marked = array();
        foreach ($operateurs as $operateur) {
            $operateurs_marked[] = $mark.$operateur.$mark;
        }

        // Supprime tous les espaces de la chaîne de caractère
        $restriction = preg_replace('/\s+/', '', $restriction);
        
        // Met un marqueur avant et après les opérateurs
        // puis transforme la chaine en un tableau
        $restriction = str_replace($operateurs, $operateurs_marked, 
            $restriction);

        // Pour chaque opérateur logique
        foreach (array('&&', '||') as $operator) {

            // S'il est absent on ne fait aucun traitement
            if (strpos($restriction, $mark.$operator.$mark) === false) {
                continue;
            }
            // Sinon on vérifie les deux conditions avec le OU/ET logique
            $restrictions = explode($mark.$operator.$mark, $restriction);
            $restrictions[0] = explode($mark, $restrictions[0]);
            $restrictions[1] = explode($mark, $restrictions[1]);
            $res_bool = false;
            if ($operator == '&&') {
                if ($this->is_restriction_satisfied($restrictions[0], $operateurs)
                    && $this->is_restriction_satisfied($restrictions[1], $operateurs)) {
                    $res_bool = true;
                }
            }
            if ($operator == '||') {
                if ($this->is_restriction_satisfied($restrictions[0], $operateurs)
                    || $this->is_restriction_satisfied($restrictions[1], $operateurs)) {
                    $res_bool = true;
                }
            }
            return $res_bool;
        }
        $tabRestriction = explode($mark, $restriction);
        return $this->is_restriction_satisfied($tabRestriction, $operateurs);

    }

    function is_restriction_satisfied($restriction, $operateurs) {
        // Tableau comprenant les résultat
        $res = array();
        // Compteur pour les résultat
        // commence à 1 car le 0 doit rester inchangé tout au long du traitement
        $j = 1;
        // Comparateur du calcul
        $comparateur = '';
        // Booléen retourné
        $res_bool = true;

        // S'il y a un comparateur
        if (in_array(">=", $restriction)
            || in_array("<=", $restriction)
            || in_array("==", $restriction)
            || in_array("!=", $restriction)) {

            // Si le tableau n'est pas vide
            if (count($restriction) > 0) {

                // Boucle dans le tableau pour récupérer seulement les valeurs
                foreach ($restriction as $key => $value) {
                    //
                    if (!in_array($value, $operateurs)) {
                        if ($this->getRestrictionValue($value) != false) {
                            $res[] = $this->getRestrictionValue($value);
                        } else {
                            // Message d'erreur
                            $error_message = sprintf(_("Le champ %s de l'instruction %s est vide"), "<span class='bold'>".$value."</span>", "<span class='bold'>".$this->valF["instruction"]."</span>");
                            $this->addToMessage($error_message);
                            // Arrête le traitement
                            return false;
                        }
                    }
                }

                // Boucle dans le tableau
                // commence à 1 car le 0 doit rester inchangé tout au long du 
                // traitement
                for ($i = 1; $i<count($restriction); $i++) {
                    
                    // Récupère le comparateur
                    if ($restriction[$i] === ">=" 
                        || $restriction[$i] === "<="
                        || $restriction[$i] === "=="
                        || $restriction[$i] === "!=") {
                        $comparateur = $restriction[$i];
                    }

                    // Si l'opérateur qui suit est un "+"
                    if ($restriction[$i] === "+") {
                        $dateDep = $res[$j];
                        unset($res[$j]);$j++;
                        $duree = $res[$j];
                        unset($res[$j]);
                        $res[$j] = $this->f->mois_date($dateDep, $duree, "+");
                    }

                    // Si l'opérateur qui suit est un "-"
                    if ($restriction[$i] === "-") {
                        $dateDep = $res[$j];
                        unset($res[$j]);$j++;
                        $duree = $res[$j];
                        unset($res[$j]);
                        $res[$j] = $this->f->mois_date($dateDep, $duree, "-");
                    }
                }
                
            }

            // Si les tableau des résultats n'est pas vide
            if (count($res) > 0) {
                //
                $res_bool = false;
                // Effectue le test
                if ($comparateur === ">=") {
                    //
                    if (strtotime($res[0]) >= strtotime($res[$j])) {
                        $res_bool = true;
                    }
                }
                if ($comparateur === "<=") {
                    //
                    if (strtotime($res[0]) <= strtotime($res[$j])) {
                        $res_bool = true;
                    }
                }
                if ($comparateur === "==") {
                    //
                    if (strtotime($res[0]) == strtotime($res[$j])) {
                        $res_bool = true;
                    }
                }
                if ($comparateur === "!=") {
                    //
                    if (strtotime($res[0]) != strtotime($res[$j])) {
                        $res_bool = true;
                    }
                }
            }
        // Sinon une erreur s'affiche
        } else {

            // Message d'erreur
            $error_message = _("Mauvais parametrage de la restriction.")." ".
                _("Contactez votre administrateur");
            $this->addToMessage($error_message);
            // Arrête le traitement
            return false;
        }
        
        return $res_bool;

    }

    /**
     * Permet de définir si l'événement passé en paramètre est un événement retour.
     * @param integer $evenement événement à tester
     * 
     * @return boolean retourne true si événement retour sinon false
     */
    function is_evenement_retour($evenement) {
        if(empty($evenement) || !is_numeric($evenement)) {
            return "";
        }
        $sql = "SELECT retour 
            FROM ".DB_PREFIXE."evenement 
            WHERE evenement = ".$evenement;
        $retour = $this->db->getOne($sql);
        $this->addToLog("verifier(): db->query(\"".$sql."\");", VERBOSE_MODE);
        if (database::isError($retour)) {
            die($retour->getMessage());
        }
        if ($retour == 't') {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Retourne le champ restriction de l'événement passé en paramètre.
     * 
     * @param integer $evenement id de l'événement sur lequel récupérer la restriction
     * 
     * @return string             contenu du champ restriction
     */
    function get_restriction($evenement) {
        if(empty($evenement) || !is_numeric($evenement)) {
            return "";
        }
        //Récupère la restriction
        $sql= "SELECT 
                  restriction 
              FROM 
                  ".DB_PREFIXE."evenement 
              WHERE 
                  evenement =".$evenement;

        $restriction = $this->db->getOne($sql);
        $this->addToLog("verifier(): db->query(\"".$sql."\");", VERBOSE_MODE);
        if (database::isError($restriction)) {
            die($restriction->getMessage());
        }        
        return $restriction;
    }

    /**
     * Récupère la valeur du champ dans la restriction
     * @param  string   $restrictionValue   Nom du champ
     * @return mixed                        Valeur du champ
     */
    function getRestrictionValue($restrictionValue){

        // Initialisation de la valeur de retour
        $return = false;

        // Récupére les valeurs du dossier
        $value_dossier = $this->get_dossier_actual();

        // 
        if (is_numeric($restrictionValue)) {
            $return = $restrictionValue;
        }elseif (isset($value_dossier[$restrictionValue])) {
            $return = $value_dossier[$restrictionValue];
        }elseif (isset($this->valF[$restrictionValue])) {
            $return = $this->valF[$restrictionValue];
        }

        // Retourne la valeur du champ
        return $return;
    }

    /**
     * Calcul des règle d'action.
     * @param string $rule      Règle d'action
     * @param string $rule_name Nom de la règle
     * @param string $type      Type de la règle
     * 
     * @return mixed            Résultat de la règle
     */
    function regle($rule, $rule_name, $type = null) {

        // Supprime tous les espaces de la chaîne de caractère
        $rule = str_replace(' ', '', $rule);
        // Coupe la chaîne au niveau de l'opérateur
        $operands = explode ("+", $rule);
        // Nombre d'opérande
        $nb_operands = count($operands);

        // Règle à null
        if ($rule == "null") {
            return null;
        }

        // Si c'est une règle spécifique
        if ($rule_name == "regle_autorite_competente"
            || $rule_name == "regle_etat"
            || $rule_name == "regle_accord_tacite"
            || $rule_name == "regle_avis") {
            //
            return $this->valF[$rule];
        }

        // Tableau des champs de type date
        $rule_type_date = array(
            "regle_date_limite",
            "regle_date_notification_delai",
            "regle_date_complet",
            "regle_date_validite",
            "regle_date_decision",
            "regle_date_chantier",
            "regle_date_achevement",
            "regle_date_conformite",
            "regle_date_rejet",
            "regle_date_dernier_depot",
            "regle_date_limite_incompletude",
        );
        // Tableau des champs de type numérique
        $rule_type_numeric = array(
            "regle_delai",
            "regle_delai_incompletude",
        );

        // Définit le type du champ
        if (in_array($rule_name, $rule_type_date) == true) {
            $type = "date";
        }
        if (in_array($rule_name, $rule_type_numeric) == true) {
            $type = "numeric";
        }

        // Initialisation des variables
        $key_date = 0;
        $total_numeric = 0;

        // Pour chaque opérande
        foreach ($operands as $key => $operand) {

            // Si c'est une règle de type date
            if ($type == 'date') {
                // Vérifie si au moins une des opérandes est une date
                if (!is_numeric($operand)
                    && isset($this->valF[$operand])
                    && $this->f->check_date($this->valF[$operand]) == true) {
                    // Récupère la position de la date
                    $key_date = $key;
                }
                // Les autres opérandes doivent être que des numériques
                if (is_numeric($operand) == true) {
                    // Ajoute l'opérande au total
                    $total_numeric += $operand;
                }
                if (!is_numeric($operand)
                    && isset($this->valF[$operand])
                    && is_numeric($this->valF[$operand]) == true) {
                    // Ajoute l'opérande au total
                    $total_numeric += $this->valF[$operand];
                }
            }

            // Si c'est une règle de type numérique
            if ($type == 'numeric') {
                // Les opérandes doivent être que des numériques
                if (is_numeric($operand) == true) {
                    // Ajoute l'opérande au total
                    $total_numeric += $operand;
                }
                if (!is_numeric($operand)
                    && isset($this->valF[$operand])
                    && is_numeric($this->valF[$operand]) == true) {
                    // Ajoute l'opérande au total
                    $total_numeric += $this->valF[$operand];
                }
            }
        }

        // Résultat pour une règle de type date
        if ($type == 'date') {
            // Retourne le calcul de la date
            return $this->f->mois_date($this->valF[$operands[$key_date]], 
                $total_numeric, "+");
        }

        // Résultat pour une règle de type numérique
        if ($type == 'numeric') {
            // Retourne le calcul 
            return $total_numeric;
        }
        
    }

    function triggerajouterapres($id,&$db,$val,$DEBUG) {
        /**
         * Mise à jour des valeurs du dossier en fonction des valeurs calculées
         * par l'action
         */
        $this->getValEvenement();
        // Initialisation
        $valF = "";
        // état de complétude actuel du dossier
        $incompletude =  $this->dossierIncomplet();

        if($incompletude === FALSE) {
            // Si l'événement d'instruction est de type incompletude
            if($this->valEvenement['type'] == "incompletude") {
                // On marque le dossier en incomplétude pour application des actions
                $incompletude = TRUE;
                // Set du flag incomplétude de la table dossier
                $valF['incompletude'] = TRUE;
                // Enregistrement de l'état dans la variable provisoire
                $valF['etat_pendant_incompletude'] = $this->valF['archive_etat'];
            }
        } else {
            // Si l'evenement d'instruction est de type retour ou contient une
            // decision, on sort d'incomplétude
            if($this->valEvenement['type'] == "retour" OR
               $this->valEvenement['avis_decision'] != NULL) {
                // On enlève la marque d'incomplétude pour application des actions
                $incompletude = FALSE;
                // On enlève le flag d'incomplétude sur l'enregistrement de la table dossier
                $valF['incompletude'] = FALSE;
                $valF['incomplet_notifie'] = FALSE;
                 // Restauration de l'état depuis l'état provisoire
                $valF['etat'] = $this->valF['archive_etat_pendant_incompletude'];
                // On vide la variable provisoire ainsi que le délai de complétude
                // et la date limite de complétude
                $valF['etat_pendant_incompletude'] = NULL;
                $valF['delai_incompletude'] = NULL;
                $valF['date_limite_incompletude'] = NULL;
                $valF['evenement_suivant_tacite_incompletude'] = NULL;
            }
        }
        // Récupération des paramètres de l'action
        $sql = "SELECT * FROM ".DB_PREFIXE."action
        WHERE action='".$this->valF['action']."'";
        $res = $db->query($sql);
        $this->addToLog("triggerajouterapres(): db->query(\"".$sql."\");", VERBOSE_MODE);
        if (database::isError($res)) {
            die($res->getMessage());
        }
        while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {

            // pour chacune des regles, on applique la regle
            if($row['regle_delai']!=''){
                $valF['delai'] = $this->regle($row['regle_delai'], 'regle_delai');
            }
            if($row['regle_accord_tacite']!=''){
                $valF['accord_tacite'] = $this->regle($row['regle_accord_tacite'], 'regle_accord_tacite');
            }
            if($row['regle_avis']!=''){
                $valF['avis_decision'] = $this->regle($row['regle_avis'], 'regle_avis');
            }
            if($row['regle_date_limite']!=''){
                $valF['date_limite']= $this->regle($row['regle_date_limite'], 'regle_date_limite');
            }
            if($row['regle_date_complet']!=''){
                $valF['date_complet']= $this->regle($row['regle_date_complet'], 'regle_date_complet');
            }
            if($row['regle_date_dernier_depot']!=''){
                $valF['date_dernier_depot']= $this->regle($row['regle_date_dernier_depot'], 'regle_date_dernier_depot');
            }
            if($row['regle_date_notification_delai']!=''){
                $valF['date_notification_delai']= $this->regle($row['regle_date_notification_delai'], 'regle_date_notification_delai');
            }
            if($row['regle_date_decision']!=''){
                $valF['date_decision']= $this->regle($row['regle_date_decision'], 'regle_date_decision');
            }
            if($row['regle_date_rejet']!=''){
                $valF['date_rejet']= $this->regle($row['regle_date_rejet'], 'regle_date_rejet');
            }
            if($row['regle_date_validite']!=''){
                $valF['date_validite']= $this->regle($row['regle_date_validite'], 'regle_date_validite');
            }
            if($row['regle_date_chantier']!=''){
                $valF['date_chantier']= $this->regle($row['regle_date_chantier'], 'regle_date_chantier');
            }
            if($row['regle_date_achevement']!=''){
                $valF['date_achevement']= $this->regle($row['regle_date_achevement'], 'regle_date_achevement');
            }
            if($row['regle_date_conformite']!=''){
                $valF['date_conformite']= $this->regle($row['regle_date_conformite'], 'regle_date_conformite');
            }
            if($row['regle_date_limite_incompletude']!=''){
                $valF['date_limite_incompletude']= $this->regle($row['regle_date_limite_incompletude'], 'regle_date_limite_incompletude');
            }
            if($row['regle_delai_incompletude']!=''){
                $valF['delai_incompletude']= $this->regle($row['regle_delai_incompletude'], 'regle_delai_incompletude');
            }
            if($row['regle_autorite_competente']!=''){
                $valF['autorite_competente']= $this->regle($row['regle_autorite_competente'], 'regle_autorite_competente');
            }
            if($row['regle_etat']!=''){
                // Si on est dans le cas général ou qu'on est en incomplétude et
                // qu'on a un événement de type incomplétude alors : on stocke
                // l'état dans la variable courante
                if ($incompletude == FALSE OR $this->valEvenement['type'] == "incompletude") {
                    $valF['etat'] = $this->regle($row['regle_etat'], 'regle_etat');
                } else {
                    $valF['etat_pendant_incompletude'] = $this->regle($row['regle_etat'], 'regle_etat');
                }
            }
        }
        if($this->valEvenement['evenement_suivant_tacite'] != '') {
    	    // Si on est pas en incomplétude on stocke l'événement tacite
        	//de l'événement dans la variable courante
        	
        	if ($incompletude == FALSE OR $this->valEvenement['type'] != "incompletude") {
        	    $valF['evenement_suivant_tacite'] = $this->valEvenement['evenement_suivant_tacite'];
        	} else {
        	    $valF['evenement_suivant_tacite_incompletude'] = $this->valEvenement['evenement_suivant_tacite'];
        	}
        }
        // Si des valeurs ont été calculées alors on met à jour l'enregistrement
        if ($valF != "") {
            // On met à jour le dossier
            $cle = " dossier='".$this->valF['dossier']."'";
            $res1 = $db->autoExecute(DB_PREFIXE.'dossier', $valF, DB_AUTOQUERY_UPDATE, $cle);
            $this->addToLog("triggerajouterapres(): db->autoexecute(\"".DB_PREFIXE."dossier\", ".print_r($valF, true).", DB_AUTOQUERY_UPDATE, \"".$cle."\");", VERBOSE_MODE);
            if (database::isError($res1)) {
                die($res->getMessage());
            }
            // Affichage d'informations à l'utilisateur
            $this->addToMessage(_('enregistrement')." ".$this->valF['dossier']." "._('table')." dossier [".$db->affectedRows()." "._('enregistrement')." "._('mis_a_jour')."]");
        }

        /**
         * REFERENTIEL ERP
         */
        // verification si envoi vers ERP est active
        if ($this->f->getParameter('option_erp') === 'true') {
            // la nature du dossier
            $nature_dossier = substr($this->idxformulaire,0,2);
            //
            $sql = "SELECT erp
            FROM ".DB_PREFIXE."dossier
            WHERE dossier='".$this->valF['dossier']."'";
            $dossier_erp = $this->db->getone($sql);
            $this->addToLog("triggerajouterapres(): db->getone(\"".$sql."\");", VERBOSE_MODE);
            if (database::isError($res)) {
                die($res->getMessage());
            }
            //
            $sql = "SELECT libelle
            FROM ".DB_PREFIXE."evenement
            WHERE evenement='".$this->valF['evenement']."'";
            $evenement_libelle = $this->db->getone($sql);
            $this->addToLog("triggerajouterapres(): db->getone(\"".$sql."\");", VERBOSE_MODE);
            if (database::isError($res)) {
                die($res->getMessage());
            }
            //
            if ($dossier_erp == 't') {
                // envoi du message en cas d'un PC qui est ERP et sur lequel un evenement
                // d'acceptation etait fait
                if ($nature_dossier ==
                        $this->f->getParameter('erp_evenement_accepter_dossier_PC')
                    && $this->valF['evenement'] ==
                        $this->f->getParameter('erp_evenement_accepter_sans_reserve')) {
                    $msgenque = new MessageEnqueuer();
                    $msgenque->setDossierInstructionIdentifier($this->valF['dossier']);
                    $msgenque->setDecision($evenement_libelle);
                    $return = $msgenque->enqueueMessage($msgenque::$ERP_ARRETE_PC_EFFECTUE);
                    //Si une erreur s'est produite on arrête le traitement et on 
                    //retourne une erreur
                    if ($return !== 0){
                        
                        $this->addToMessage(_("Une erreur s'est produite lors de ".
                            "l'envoi du message au referentiel ERP. Merci de ".
                            "contacter votre administrateur"));
                        //On ne valide pas le formulaire
                        $this->addToMessage("<br/>"._("SAISIE NON ENREGISTREE")."<br/>");
                        $this->correct = false;
                        return false;
                    }
                    else {
                        $this->addToMessage(_("Le message a ete transmis au ".
                            "referentiel ERP."));
                    }
                }
                if ($this->valF['evenement'] ==
                        $this->f->getParameter('erp_evenement_refuser_dossier')) {
                    $msgenque = new MessageEnqueuer();
                    $msgenque->setDossierInstructionIdentifier($this->valF['dossier']);
                    $return = $msgenque->enqueueMessage($msgenque::$ERP_DECISION_CONFORMITE_EFFECTUE);
                    //Si une erreur s'est produite on arrête le traitement et on 
                    //retourne une erreur
                    if ($return !== 0){
                        
                        $this->addToMessage(_("Une erreur s'est produite lors de ".
                            "l'envoi du message au referentiel ERP. Merci de ".
                            "contacter votre administrateur"));
                        //On ne valide pas le formulaire
                        $this->addToMessage("<br/>"._("SAISIE NON ENREGISTREE")."<br/>");
                        $this->correct = false;
                        return false;
                    }
                    else {
                        $this->addToMessage(_("Le message a ete transmis au ".
                            "referentiel ERP."));
                    }                
                }
            }
        } // fin de if ($this->f->getParameter('option_erp') === 'true')

        // Mise à jour des données du dossier d'autorisation
        require_once "../obj/dossier_autorisation.class.php";
        $da = new dossier_autorisation($this->getNumDemandeAutorFromDossier($this->valF['dossier']), $this->db, DEBUG);
        if($da->majDossierAutorisation() === false) {
            $this->addToMessage(_("Erreur lors de la mise a jour des donnees du dossier d'autorisation. Contactez votre administrateur."));
            $this->correct = false;
            return false;
        }
        return $this->add_log_to_dossier($id, array_merge($val, $this->valF));
    }

    function triggermodifierapres($id,&$db,$val,$DEBUG) {
        /**
         * L'objectif ici est d'effectuer les recalculs de date dans le dossier
         * si la date de l'evenement est modifiee
         */ 
        // Initialisation
        $valF = "";
        // Initialisation du type d'événement
        $type_evmt = "";
        // Récupération de l'action correspondante à l'événement
        $sql = "SELECT action
        FROM ".DB_PREFIXE."evenement
        WHERE evenement=".$this->valF['evenement'];
        $action = $db->getOne($sql);
        $this->addToLog("triggermodifierapres(): db->getone(\"".$sql."\");", VERBOSE_MODE);
        if (database::isError($action)) {
            die($action->getMessage());
        }

        // Récupération des paramètres de l'action
        $sql = "SELECT * FROM ".DB_PREFIXE."action
        WHERE action='".$action."'";
        $res = $db->query($sql);
        $this->addToLog("triggermodifierapres(): db->query(\"".$sql."\");", VERBOSE_MODE);
        if (database::isError($res)) {
            die($res->getMessage());
        }
        while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)){
            // application des regles sur le courrier + delai
            if(preg_match("/date_evenement/",$row['regle_date_limite'])){
                $valF['date_limite']= $this->regle($row['regle_date_limite'], 'regle_date_limite');
            }
            if(preg_match("/date_evenement/",$row['regle_date_complet'])){
                $valF['date_complet']= $this->regle($row['regle_date_complet'], 'regle_date_complet');
            }
            if(preg_match("/date_evenement/",$row['regle_date_dernier_depot'])){
                $valF['date_dernier_depot']= $this->regle($row['regle_date_dernier_depot'], 'regle_date_dernier_depot');
            }
            if(preg_match("/date_evenement/",$row['regle_date_notification_delai'])){
                $valF['date_notification_delai']= $this->regle($row['regle_date_notification_delai'], 'regle_date_notification_delai');
            }
            if(preg_match("/date_evenement/",$row['regle_date_decision'])){
                $valF['date_decision']= $this->regle($row['regle_date_decision'], 'regle_date_decision');
            }
            if(preg_match("/date_evenement/",$row['regle_date_rejet'])){
                $valF['date_rejet']= $this->regle($row['regle_date_rejet'], 'regle_date_rejet');
            }
            if(preg_match("/date_evenement/",$row['regle_date_validite'])){
                $valF['date_validite']= $this->regle($row['regle_date_validite'], 'regle_date_validite');
            }
            if(preg_match("/date_evenement/",$row['regle_date_chantier'])){
                $valF['date_chantier']= $this->regle($row['regle_date_chantier'], 'regle_date_chantier');
            }
            if(preg_match("/date_evenement/",$row['regle_date_achevement'])){
                $valF['date_achevement']= $this->regle($row['regle_date_achevement'], 'regle_date_achevement');
            }
            if(preg_match("/date_evenement/",$row['regle_date_conformite'])){
                $valF['date_conformite']= $this->regle($row['regle_date_conformite'], 'regle_date_conformite');
            }
        }
        // Si des valeurs ont été calculées alors on met à jour l'enregistrement
        if ($valF != "") {
            // On met à jour le dossier
            $cle = " dossier='".$this->valF['dossier']."'";
            $res1 = $db->autoExecute(DB_PREFIXE.'dossier', $valF, DB_AUTOQUERY_UPDATE, $cle);
            $this->addToLog("triggermodifierapres(): db->autoexecute(\"".DB_PREFIXE."dossier\", ".print_r($valF, true).", DB_AUTOQUERY_UPDATE, \"".$cle."\");", VERBOSE_MODE);
            if (database::isError($res1)) {
                die($res->getMessage());
            }
            // Affichage d'informations à l'utilisateur
            $this->addToMessage(_('enregistrement')." ".$this->valF['dossier']." "._('table')." dossier [".$db->affectedRows()." "._('enregistrement')." "._('mis_a_jour')."]");
        }

        $restriction = $this->get_restriction($val['evenement']);
        $this->restriction_valid = $this->restrictionIsValid($restriction);

        if($restriction == "" || $this->restriction_valid ){
            // Récupération de tous les paramètres de l'événement sélectionné
            $sql = "SELECT * FROM ".DB_PREFIXE."evenement
            WHERE evenement=".$this->valF['evenement'];
            $res = $db->query($sql);
            $this->addToLog("triggermodifierapres(): db->query(\"".$sql."\");", VERBOSE_MODE);
            if (database::isError($res)) {
                die($res->getMessage());
            }
            $current_id = $this->getVal($this->clePrimaire);
            while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
                // Si la date de retour signature est éditée on vérifie si il existe un événement automatique
                if ($this->getVal('date_retour_signature') == "" AND 
                    $this->valF['date_retour_signature'] != "" AND
                    $row['evenement_retour_signature'] != "") {
                    $new_instruction = new instruction("]", $db, $DEBUG);
                    // Création d'un tableau avec la liste des champs de l'instruction
                    foreach($new_instruction->champs as $champ) {
                        $valNewInstr[$champ] = ""; 
                    }
                    // Définition des valeurs de la nouvelle instruction
                    $valNewInstr["evenement"] = $row['evenement_retour_signature'];
                    $valNewInstr["destinataire"] = $this->valF['destinataire'];
                    $valNewInstr["dossier"] = $this->valF['dossier'];
                    $valNewInstr["date_evenement"] = $this->f->formatDate($this->valF['date_retour_signature']);
                    $valNewInstr["date_envoi_signature"] = $this->f->formatDate($this->valF['date_envoi_signature']);
                    $valNewInstr["date_retour_signature"] = $this->f->formatDate($this->valF['date_retour_signature']);
                    $valNewInstr["date_envoi_rar"] = $this->f->formatDate($this->valF['date_envoi_rar']);
                    $valNewInstr["date_retour_rar"] = $this->f->formatDate($this->valF['date_retour_rar']);
                    $valNewInstr["date_envoi_controle_legalite"] = $this->f->formatDate($this->valF['date_envoi_controle_legalite']);
                    $valNewInstr["date_retour_controle_legalite"] = $this->f->formatDate($this->valF['date_retour_controle_legalite']);
                    $new_instruction->setParameter("maj", 0);
                    $new_instruction->class_actions[0]["identifier"] = 
                        "retour signature de l'instruction $current_id";
                    $retour = $new_instruction->ajouter($valNewInstr,$db, $DEBUG);
                    
                    //Si une erreur s'est produite et qu'il s'agit d'un problème
                    //de restriction
                    if ($retour == false && !$new_instruction->restriction_valid){
                        $error_message = $this->get_restriction_error_message($restriction);
                        $this->f->displayMessage("error", $error_message);
                        $this->addToLog("triggermodifierapres() : evenement retour ".
                            "instruction ".$this->valF[$this->clePrimaire]." : ".
                            $new_instruction->msg);
                    }
                    //Si une erreur s'est produite après le test de la restriction
                    elseif ($retour == false && $new_instruction->restriction_valid){
                        $this->correct = false ;
                        $this->msg .= $new_instruction->msg;
                        return false;
                    }
                }
                // Si la date de retour AR est éditée on vérifie si il existe un événement automatique
                if ($this->getVal('date_retour_rar') == "" AND 
                    $this->valF['date_retour_rar'] != "") {
                    
                    if($row['evenement_retour_ar'] != "") {
                        $new_instruction = new instruction("]", $db, $DEBUG);
                        // Création d'un tableau avec la liste des champs de l'instruction
                        foreach($new_instruction->champs as $champ) {
                            $valNewInstr[$champ] = ""; 
                        }
                        // Définition des valeurs de la nouvelle instruction
                        $valNewInstr["evenement"] = $row['evenement_retour_ar'];
                        $valNewInstr["destinataire"] = $this->valF['destinataire'];
                        $valNewInstr["dossier"] = $this->valF['dossier'];
                        $valNewInstr["date_evenement"] = $this->f->formatDate($this->valF['date_retour_rar']);
                        $valNewInstr["date_envoi_signature"] = $this->f->formatDate($this->valF['date_envoi_signature']);
                        $valNewInstr["date_retour_signature"] = $this->f->formatDate($this->valF['date_retour_signature']);
                        $valNewInstr["date_envoi_rar"] = $this->f->formatDate($this->valF['date_envoi_rar']);
                        $valNewInstr["date_retour_rar"] = $this->f->formatDate($this->valF['date_retour_rar']);
                        $valNewInstr["date_envoi_controle_legalite"] = $this->f->formatDate($this->valF['date_envoi_controle_legalite']);
                        $valNewInstr["date_retour_controle_legalite"] = $this->f->formatDate($this->valF['date_retour_controle_legalite']);
                        $new_instruction->setParameter("maj", 0);
                        $new_instruction->class_actions[0]["identifier"] = 
                            "retour RAR de l'instruction $current_id";
                        $retour = $new_instruction->ajouter($valNewInstr,$db, $DEBUG);

                        //Si une erreur s'est produite et qu'il s'agit d'un problème
                        //de restriction
                        if ($retour == false && !$new_instruction->restriction_valid) {
                            $error_message = $this->get_restriction_error_message($restriction);
                            $this->f->displayMessage("error", $error_message);
                            $this->addToLog(
                                "triggermodifierapres() : evenement retour instruction ".
                                $this->valF[$this->clePrimaire]." : ".
                                $new_instruction->msg
                            );
                        }
                        //Si une erreur s'est produite après le test de la restriction
                        elseif ($retour == false && $new_instruction->restriction_valid){
                            $this->correct = false ;
                            $this->msg .= $new_instruction->msg;
                            return false;
                        }
                    }
                    // Mise à jour du flag incomplet_notifie dans dossier si la 
                    // date limite d'instruction n'est pas dépassée
                    if($row['type']=='incompletude' && 
                        ($this->valF['archive_date_notification_delai'] >= $this->valF['date_retour_rar'] || 
                        $this->valF['archive_date_notification_delai'] == "")) {
                        $valFIncomp['incomplet_notifie'] = true;
                        $cle = " dossier='".$val['dossier']."'";
                        $resIncomp = $db->autoExecute(
                            DB_PREFIXE.'dossier',
                            $valFIncomp,
                            DB_AUTOQUERY_UPDATE,
                            $cle
                        );
                        $this->addToLog(
                            "triggersupprimer(): db->autoexecute(\"".
                                DB_PREFIXE."dossier\", ".print_r($valFIncomp, true).
                                ", DB_AUTOQUERY_UPDATE, \"".$cle."\");",
                            VERBOSE_MODE
                        );
                        if (database::isError($resIncomp)) {
                            die($resIncomp->getMessage());
                        }
                    }
                }
            }
        }

        // Mise à jour des données du dossier d'autorisation
        require_once "../obj/dossier_autorisation.class.php";
        $da = new dossier_autorisation($this->getNumDemandeAutorFromDossier($this->valF['dossier']), $this->db, DEBUG);
        if($da->majDossierAutorisation() === false) {
            $this->addToMessage(_("Erreur lors de la mise a jour des donnees du dossier d'autorisation. Contactez votre administrateur."));
            $this->correct = false;
            return false;
        }
        return $this->add_log_to_dossier($id, $val);
    } 

    function triggersupprimer($id,&$db,$val,$DEBUG) {
        /**
         * L'objectif ici est de repositionner les valeurs récupérées en
         * archive dans le dossier d'instruction avant de supprimer l'événement
         * d'instruction
         */
         
            // Mise à jour des 4 valeurs modifiées par l'action
            $valF['delai'] = $val['archive_delai'];
            $valF['accord_tacite'] = $val['archive_accord_tacite'];
            $valF['etat'] = $val['archive_etat'];
            if ($val['archive_avis'] != '') {
                $valF['avis_decision'] = $val['archive_avis'];
            } else {
                $valF['avis_decision'] = NULL;
            }
            // Mise à jour des 10 dates avec la valeur présente dans le formulaire
            // de suppression. Si la valeur de la date est vide alors on fixe
            // à la valeur NULL
            //
            if ($val['archive_date_complet'] != '') {
                $valF['date_complet'] = $val['archive_date_complet'];
            } else {
                $valF['date_complet'] = NULL;
            }
            if ($val['archive_date_dernier_depot'] != '') {
                $valF['date_dernier_depot'] = $val['archive_date_dernier_depot'];
            } else {
                $valF['date_dernier_depot'] = NULL;
            }
            if ($val['archive_date_rejet'] != '') {
                $valF['date_rejet'] = $val['archive_date_rejet'];
            } else {
                $valF['date_rejet'] = NULL;
            }
            if ($val['archive_date_limite'] != '') {
                $valF['date_limite'] = $val['archive_date_limite'];
            } else {
                $valF['date_limite'] = NULL;
            }
            if ($val['archive_date_notification_delai'] != '') {
                $valF['date_notification_delai'] = $val['archive_date_notification_delai'];
            } else {
                $valF['date_notification_delai'] = NULL;
            }
            if ($val['archive_date_decision'] != '') { 
                $valF['date_decision'] = $val['archive_date_decision'];
            } else {
                $valF['date_decision'] = NULL;
            }
            if ($val['archive_date_validite'] != '') {
                $valF['date_validite'] = $val['archive_date_validite'];
            } else {
                $valF['date_validite'] = NULL;
            }
            if ($val['archive_date_achevement'] != '') {
                $valF['date_achevement'] = $val['archive_date_achevement'];
            } else {
                $valF['date_achevement'] = NULL;
            }
            if ($val['archive_date_chantier'] != '') {
                $valF['date_chantier'] = $val['archive_date_chantier'];
            } else {
                $valF['date_chantier'] = NULL;
            }
            if ($val['archive_date_conformite'] != '') {
                $valF['date_conformite'] = $val['archive_date_conformite'];
            } else {
                $valF['date_conformite'] = NULL;
            }
            if ($val['archive_incompletude'] != '') {
                $valF['incompletude'] = $val['archive_incompletude'];
            } else {
                $valF['incompletude'] = NULL;
            }
            if ($val['archive_incomplet_notifie'] != '') {
                $valF['incomplet_notifie'] = $val['archive_incomplet_notifie'];
            } else {
                $valF['incomplet_notifie'] = NULL;
            }
            if ($val['archive_evenement_suivant_tacite'] != '') {
                $valF['evenement_suivant_tacite'] = $val['archive_evenement_suivant_tacite'];
            } else {
                $valF['evenement_suivant_tacite'] = NULL;
            }
            if ($val['archive_evenement_suivant_tacite_incompletude'] != '') {
                $valF['evenement_suivant_tacite_incompletude'] = $val['archive_evenement_suivant_tacite_incompletude'];
            } else {
                $valF['evenement_suivant_tacite_incompletude'] = NULL;
            }
            if ($val['archive_etat_pendant_incompletude'] != '') {
                $valF['etat_pendant_incompletude'] = $val['archive_etat_pendant_incompletude'];
            } else {
                $valF['etat_pendant_incompletude'] = NULL;
            }
            if ($val['archive_date_limite_incompletude'] != '') {
                $valF['date_limite_incompletude'] = $val['archive_date_limite_incompletude'];
            } else {
                $valF['date_limite_incompletude'] = NULL;
            }
            if ($val['archive_delai_incompletude'] != '') {
                $valF['delai_incompletude'] = $val['archive_delai_incompletude'];
            } else {
                $valF['delai_incompletude'] = NULL;
            }
            if ($val['archive_autorite_competente'] != '') {
                $valF['autorite_competente'] = $val['archive_autorite_competente'];
            } else {
                $valF['autorite_competente'] = NULL;
            }
            // On met à jour le dossier
            $cle = " dossier='".$val['dossier']."'";
            $res = $db->autoExecute(DB_PREFIXE.'dossier', $valF, DB_AUTOQUERY_UPDATE, $cle);
            $this->addToLog("triggersupprimer(): db->autoexecute(\"".DB_PREFIXE."dossier\", ".print_r($valF, true).", DB_AUTOQUERY_UPDATE, \"".$cle."\");", VERBOSE_MODE);
            if (database::isError($res)) {
                die($res->getMessage());
            }
            // Affichage d'informations à l'utilisateur
            $this->addToMessage(_("Suppression de l'instruction")." [".$db->affectedRows()." "._('enregistrement')." "._('mis_a_jour')."]");
    
            // Mise à jour de la demande si un récépissé d'instruction correspond à l'instruction à supprimer
    }

    function triggersupprimerapres($id,&$db,$val,$DEBUG) {

        // Mise à jour des données du dossier d'autorisation
        require_once "../obj/dossier_autorisation.class.php";
        $da = new dossier_autorisation($this->getNumDemandeAutorFromDossier($val["dossier"]), $this->db, DEBUG);
        if($da->majDossierAutorisation() === false) {
            $this->addToMessage(_("Erreur lors de la mise a jour des donnees du dossier d'autorisation. Contactez votre administrateur."));
            $this->correct = false;
            return false;
        }
        $val['evenement'] = $this->getVal('evenement');
        return $this->add_log_to_dossier($id, $val);
    }

    /**
     * Permet de composer un message d'erreur sur restriction non valide en 
     * fonction du contexte.
     *
     * @param string $restriction formule de la restriction
     *
     * @return string message d'erreur
     */
    function get_restriction_error_message($restriction) {
        // Affichage du message si la restriction s'applique
        // Contexte du suivi des dates (message simple)
        $message_restrict = _("Probleme de dates :");
        // Split restriction
        $champs_restrict = preg_split(
                '/(\W+)/',
                $restriction,
                null,
                PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE
            );
        $formated_restrict = "";
        // Ajout des chaînes à traduire
        foreach ($champs_restrict as $value) {
            $formated_restrict .= _($value)." ";
        }
        $formated_restrict = substr($formated_restrict, 0, -1);
        // Message d'erreur dans le contexte du suivi des dates
        if($this->getParameter("maj") == 170) {
            $message_restrict .= " "._("contactez l'instructeur du dossier");
            $message_restrict .= "<br/>(".$formated_restrict.")";
        } else {
            // Affichage du message si la restriction s'applique
            // Contexte instruction
            $message_restrict .= "<br/>".$formated_restrict;
        }

        return $message_restrict;
    }

    /**
     * Vérifie la restriction sur l'événement.
     *
     * @param array    $val   valeurs du formulaire
     * @param database $db    handler database
     * @param boolean  $DEBUG NA
     *
     * @return [type] [description]
     */
    function verifier($val = array(), &$db, $DEBUG) {
        parent::verifier($val, $db, $DEBUG);

        if ( isset($val['evenement']) && is_numeric($val['evenement'])){
            $restriction = $this->get_restriction($val['evenement']);
    
            //Test qu'une restriction est présente
            if ($restriction != "" ){
                
                //Test si la restriction est valide
                $this->restriction_valid = $this->restrictionIsValid($restriction);
                if ( !$this->restriction_valid ){

                    // Affichage du message si la restriction s'applique
                    $this->addToMessage(
                        $this->get_restriction_error_message($restriction)
                    );
                    $this->correct=false;
                    return false;
                }

                // Liste des opérateurs possible
                $operateurs = array(">=", "<=", "+", "-", "&&", "||", "==", "!=");
                // Supprime tous les espaces de la chaîne de caractère
                $restriction = str_replace(' ', '', $restriction);
                
                // Met des espace avant et après les opérateurs puis transforme la 
                // chaine en un tableau 
                $tabRestriction = str_replace($operateurs, " ", $restriction);
                // Tableau des champ
                $tabRestriction = explode(" ", $tabRestriction);
                // Supprime les numériques du tableau
                foreach ($tabRestriction as $key => $value) {
                    if (is_numeric($value)) {
                        unset($tabRestriction[$key]);
                    }
                }

                // Vérifie les champs utilisés pour la restriction
                $check_field_exist = $this->f->check_field_exist($tabRestriction, 'instruction');
                if ($check_field_exist !== true) {

                    // Liste des champs en erreur
                    $string_error_fields = implode(", ", $check_field_exist);

                    // Message d'erreur
                    $error_message = _("Le champ %s n'est pas utilisable pour le champ %s");
                    if (count($check_field_exist) > 1) {
                        $error_message = _("Les champs %s ne sont pas utilisable pour le champ %s");
                    }

                    // Affiche l'erreur
                    $this->correct=false;
                    $this->addToMessage(sprintf($error_message, $string_error_fields, _("restriction")));
                    $this->addToMessage(_("Veuillez contacter votre administrateur."));
                }
            }

        }
        if(!$this->updateDate("date_envoi_signature")) {
            return false;
        }
        if(!$this->updateDate("date_retour_signature")) {
            return false;
        }
        if(!$this->updateDate("date_envoi_rar")) {
            return false;
        }
        if(!$this->updateDate("date_retour_rar")) {
            return false;
        }
        if(!$this->updateDate("date_envoi_controle_legalite")) {
            return false;
        }
        if(!$this->updateDate("date_retour_controle_legalite")) {
            return false;
        }

    }

    /**
     * Méthode permettant de récupérer toutes les valeurs de l'événement
     * sélectionné après validation du formulaire d'instruction
     *
     * @return array() veleurs de l'événement lié
     */

    private function getValEvenement() {
        if(!empty($this->valEvenement)) {
            return $this->valEvenement;
        } else {
            $sql = "SELECT * FROM ".DB_PREFIXE."evenement
                WHERE evenement=".$this->valF['evenement'];
            $res = $this->db->query($sql);
            $this->addToLog("getValEvenement(): db->query(\"".$sql."\");", VERBOSE_MODE);
            if (database::isError($res)) {
                die($res->getMessage());
            }
            $this->valEvenement = $res->fetchRow(DB_FETCHMODE_ASSOC);
            return $this->valEvenement;
        }
    }

    /**
     * Méthode permettant de savoir si le dossier lié à l'instruction à le flag
     * incompletude à true après validation du formulaire d'instruction
     *
     * @return boolean 
     */
    private function dossierIncomplet() {
        $sql = "SELECT incompletude FROM ".DB_PREFIXE."dossier
                WHERE dossier='".$this->valF['dossier']."'";
        $incompletude = $this->db->getOne($sql);
        $this->addToLog("dossierIncomplet(): db->query(\"".$sql."\");", VERBOSE_MODE);
        if (database::isError($incompletude)) {
            die($incompletude->getMessage());
        }
        if ($incompletude == 't') {
            return true;
        } else {
            return false;
        }
    }
    
    /**
     * Finalisation des documents.
     * @param  string $champ    champ du fichier à finaliser
     * @param  booleen $status  permet de définir si on finalise ou définalise
     * @param  string $sousform permet de savoir si se trouve dans un sousformulaire (passé au javascript)
     */
    function manage_finalizing($mode = null, $val = array()) {

        // Si le mode n'existe pas on retourne false
        if ($mode != "finalize" && $mode != "unfinalize") {
            return false;
        }

        // Recuperation de la valeur de la cle primaire de l'objet
        $id = $this->getVal($this->clePrimaire);

        // Si on finalise le document
        if ($mode == "finalize"){

            // Récupère la collectivite du dossier d'instruction
            $dossier_instruction_om_collectivite = $this->get_dossier_instruction_om_collectivite();

            //
            $collectivite = $this->f->getCollectivite($dossier_instruction_om_collectivite);
            
            // Génération du PDF
            $result = $this->compute_pdf_output('lettretype', $this->getVal('lettretype'), $collectivite);
            $pdf_output = $result['pdf_output'];
            
            //Métadonnées du document
            $metadata = array(
                'filename' => 'instruction_'.$id.'.pdf',
                'mimetype' => 'application/pdf',
                'size' => strlen($pdf_output)
            );

            // Récupération des métadonnées calculées après validation
            $spe_metadata = $this->getMetadata("om_fichier_instruction");

            //On vérifie si l'instruction à finaliser a un événement de type arrete
            $sql = "SELECT type
                FROM ".DB_PREFIXE."evenement
                WHERE evenement = ".$this->getVal("evenement");
            $typeEvenement = $this->db->getOne($sql);
            $this->addToLog(__METHOD__."(): db->getOne(\"".$sql."\");", VERBOSE_MODE);
            if (database::isError($typeEvenement, true)) {
                die();
            }

            //Initialisation de la variable
            $arrete_metadata = array();
            // Si l'événement est de type arrete, on ajoute les métadonnées spécifiques
            if ( $typeEvenement === 'arrete' ){
                $arrete_metadata = $this->getMetadata("arrete");
            }

            $metadata = array_merge($metadata, $spe_metadata, $arrete_metadata);

            // Si le document a déjà été finalisé
            // met à jour le document mais pas son uid
            if ($this->getVal("om_fichier_instruction") != ''){

                // Met à jour le document
                $uid = $this->f->storage->update(
                    $this->getVal("om_fichier_instruction"), $pdf_output, $metadata);
            }
            //Sinon, ajoute le document et récupère son uid
            else {

                //Stockage du PDF
                $uid = $this->f->storage->create($pdf_output, $metadata);
            }
        }

        // Si on finalise le document
        if ($mode == "unfinalize") {

            // Récupération de l'uid du document finalisé
            $uid = $this->getVal("om_fichier_instruction");
        }

        //
        if ($uid == '' || $uid == 'OP_FAILURE' ) {
            // Stop le traitement
            return false;

            // Message d'echec (saut d'une ligne supplementaire avant le
            // message pour qu'il soit mis en evidence)
            $this->addToLog(
                _("Finalisation non enregistree")." - ".
                _("id instruction")." = ".$id." - ".
                _("uid fichier")." = ".$uid
            );
        }

        // Logger
        $this->addToLog(__METHOD__."() - begin", EXTRA_VERBOSE_MODE);

        //
        foreach ($this->champs as $key => $champ) {
            //
            $val[$champ] = $this->val[$key];
        }

        //
        $val['date_evenement']=$this->dateDBToForm($val['date_evenement']);
        $val['archive_date_complet']=$this->dateDBToForm($val['archive_date_complet']);
        $val['archive_date_rejet']=$this->dateDBToForm($val['archive_date_rejet']);
        $val['archive_date_limite']=$this->dateDBToForm($val['archive_date_limite']);
        $val['archive_date_notification_delai']=$this->dateDBToForm($val['archive_date_notification_delai']);
        $val['archive_date_decision']=$this->dateDBToForm($val['archive_date_decision']);
        $val['archive_date_validite']=$this->dateDBToForm($val['archive_date_validite']);
        $val['archive_date_achevement']=$this->dateDBToForm($val['archive_date_achevement']);
        $val['archive_date_chantier']=$this->dateDBToForm($val['archive_date_chantier']);
        $val['archive_date_conformite']=$this->dateDBToForm($val['archive_date_conformite']);
        $val['archive_date_dernier_depot']=$this->dateDBToForm($val['archive_date_dernier_depot']);
        $val['archive_date_limite_incompletude']=$this->dateDBToForm($val['archive_date_limite_incompletude']);
        $val['date_finalisation_courrier']=$this->dateDBToForm($val['date_finalisation_courrier']);
        $val['date_envoi_signature']=$this->dateDBToForm($val['date_envoi_signature']);
        $val['date_retour_signature']=$this->dateDBToForm($val['date_retour_signature']);
        $val['date_envoi_rar']=$this->dateDBToForm($val['date_envoi_rar']);
        $val['date_retour_rar']=$this->dateDBToForm($val['date_retour_rar']);
        $val['date_envoi_controle_legalite']=$this->dateDBToForm($val['date_envoi_controle_legalite']);
        $val['date_retour_controle_legalite']=$this->dateDBToForm($val['date_retour_controle_legalite']);
        
        $this->setvalF($val);

        // Verification de la validite des donnees
        $this->verifier($this->val, $this->db, DEBUG);
        // Si les verifications precedentes sont correctes, on procede a
        // la modification, sinon on ne fait rien et on retourne une erreur
        if ($this->correct) {
            // Execution du trigger 'before' specifique au MODE 'update'
            $this->triggermodifier($id, $this->db, $this->val, DEBUG);

            //
            $valF = array(
                "om_fichier_instruction" => $uid,
                "date_finalisation_courrier" => date('Y-m-d')
            );
            //
            if($mode=="finalize") {
                // état finalisé vrai
                $valF["om_final_instruction"] = 't';
                // ajout log utilisateur
                $login = $_SESSION['login'];
                $nom = "";
                $this->f->getUserInfos();
                if (isset($this->f->om_utilisateur["nom"])
                    && !empty($this->f->om_utilisateur["nom"])) {
                    $nom = $this->f->om_utilisateur["nom"];
                }
                $valF["om_final_instruction_utilisateur"] = $_SESSION['login'];
                if ($nom != "") {
                    $valF["om_final_instruction_utilisateur"] .= " (".$nom.")";
                }
            } else {
                // état finalisé faux
                $valF["om_final_instruction"] = 'f';
                // suppression log utilisateur
                $valF["om_final_instruction_utilisateur"] = '';
            }

            // Execution de la requête de modification des donnees de l'attribut
            // valF de l'objet dans l'attribut table de l'objet
            $res = $this->db->autoExecute(DB_PREFIXE.$this->table, $valF, 
                DB_AUTOQUERY_UPDATE, $this->getCle($id));
             $this->addToLog(__METHOD__."() : db->autoExecute(\"".DB_PREFIXE.$this->table."\", ".print_r($valF, true).", DB_AUTOQUERY_UPDATE, \"".$this->getCle($id)."\")", VERBOSE_MODE);
            // Si une erreur survient
            if (database::isError($res, true)) {
                // Appel de la methode de recuperation des erreurs
                $this->erreur_db($res->getDebugInfo(), $res->getMessage(), '');
            } else {
                // Log
                $this->addToLog(_("Requete executee"), VERBOSE_MODE);
                // Log
                $message = _("Enregistrement")."&nbsp;".$id."&nbsp;";
                $message .= _("de la table")."&nbsp;\"".$this->table."\"&nbsp;";
                $message .= "[&nbsp;".$this->db->affectedRows()."&nbsp;";
                $message .= _("enregistrement(s) mis a jour")."&nbsp;]";
                $this->addToLog($message, VERBOSE_MODE);
                // Execution du trigger 'after' specifique au MODE 'update'
                //$this->triggermodifierapres($id, $this->db, $val, DEBUG);

                if($mode == "finalize") {
                    $etat = _('finalisation');
                } else {
                    $etat = _('definalisation');
                }
                $this->msg = "";
                $this->addToMessage(sprintf(_("La %s du document s'est effectuee avec succes."), $etat));

                return $this->add_log_to_dossier($id, $val);
            } 
        } else {
            // Message d'echec (saut d'une ligne supplementaire avant le
            // message pour qu'il soit mis en evidence)
            $this->addToLog(
                _("Finalisation non enregistree")." - ".
                _("id instruction")." = ".$id." - ".
                _("uid fichier")." = ".$uid
            );
            return false;
        }
    }

    /**
     * Récupération du numéro de dossier d'instruction à ajouter aux métadonnées
     * @return string numéro de dossier d'instruction
     */
    protected function getDossier() {
        if(empty($this->specificMetadata)) {
            $this->getSpecificMetadata();
        }
        return $this->specificMetadata->dossier;
    }
    /**
     * Récupération la version du dossier d'instruction à ajouter aux métadonnées
     * @return int Version
     */
    protected function getDossierVersion() {
        if(empty($this->specificMetadata)) {
            $this->getSpecificMetadata();
        }
        return $this->specificMetadata->version;
    }
    /**
     * Récupération du numéro de dossier d'autorisation à ajouter aux métadonnées
     * @return string numéro de dossier d'autorisation
     */
    protected function getNumDemandeAutor() {
        if(empty($this->specificMetadata)) {
            $this->getSpecificMetadata();
        }
        return $this->specificMetadata->dossier_autorisation;
    }
    /**
     * Récupération de la date de demande initiale du dossier à ajouter aux métadonnées
     * @return date de la demande initiale
     */
    protected function getAnneemoisDemandeAutor() {
        if(empty($this->specificMetadata)) {
            $this->getSpecificMetadata();
        }
        return $this->specificMetadata->date_demande_initiale;
    }
    /**
     * Récupération du type de dossier d'instruction à ajouter aux métadonnées
     * @return string type du dossier d'instruction
     */
    protected function getTypeInstruction() {
        if(empty($this->specificMetadata)) {
            $this->getSpecificMetadata();
        }
        return $this->specificMetadata->dossier_instruction_type;
    }
    /**
     * Récupération du statut du dossier d'autorisation à ajouter aux métadonnées
     * @return string avis
     */
    protected function getStatutAutorisation() {
        if(empty($this->specificMetadata)) {
            $this->getSpecificMetadata();
        }
        return $this->specificMetadata->statut;
    }
    /**
     * Récupération du type de dossier d'autorisation à ajouter aux métadonnées
     * @return string type du dossier d'autorisation
     */
    protected function getTypeAutorisation() {
        if(empty($this->specificMetadata)) {
            $this->getSpecificMetadata();
        }
        return $this->specificMetadata->dossier_autorisation_type;
    }
    /**
     * Récupération de la date d'ajout de document à ajouter aux métadonnées
     * @return date de l'évènement
     */
    protected function getDateEvenementDocument() {
        return date("Y-m-d");
    }
    /**
     * Récupération du groupe d'instruction à ajouter aux métadonnées
     * @return string Groupe d'instruction
     */
    protected function getGroupeInstruction() {
        if(empty($this->specificMetadata)) {
            $this->getSpecificMetadata();
        }
        return $this->specificMetadata->groupe_instruction;
    }
    /**
     * Récupération du libellé du type du document à ajouter aux métadonnées
     * @return string Groupe d'instruction
     */
    protected function getTitle() {

        // Récupère le champ événement
        if (isset($this->valF["evenement"]) AND $this->valF["evenement"] != "") {
            $evenement = $this->valF["evenement"];
        } else {
            $evenement = $this->getVal("evenement");
        }

        // Requête sql
        $sql = "SELECT libelle FROM ".DB_PREFIXE."evenement
                WHERE evenement=".$evenement;
        $evenement_libelle = $this->db->getOne($sql);
        $this->addToLog("getTitle(): db->getOne(\"".$sql."\");", VERBOSE_MODE);
        if (database::isError($evenement_libelle)) {
            die();
        }

        // Retourne le libelle de l'événement
        return $evenement_libelle;
    }

    /**
     * Cette méthode permet de stocker en attribut toutes les métadonnées
     * nécessaire à l'ajout d'un document.
     */
    public function getSpecificMetadata() {
        if (isset($this->valF["dossier"]) AND $this->valF["dossier"] != "") {
            $dossier = $this->valF["dossier"];
        } else {
            $dossier = $this->getVal("dossier");
        }
        //Requête pour récupérer les informations essentiels sur le dossier d'instruction
        $sql = "SELECT dossier.dossier as dossier,
                        dossier_autorisation.dossier_autorisation as dossier_autorisation, 
                        to_char(dossier.date_demande, 'YYYY/MM') as date_demande_initiale,
                        dossier_instruction_type.code as dossier_instruction_type, 
                        etat_dossier_autorisation.libelle as statut,
                        dossier_autorisation_type.code as dossier_autorisation_type,
                        groupe.code as groupe_instruction
                FROM ".DB_PREFIXE."dossier 
                    LEFT JOIN ".DB_PREFIXE."dossier_instruction_type  
                        ON dossier.dossier_instruction_type = dossier_instruction_type.dossier_instruction_type
                    LEFT JOIN ".DB_PREFIXE."dossier_autorisation 
                        ON dossier.dossier_autorisation = dossier_autorisation.dossier_autorisation 
                    LEFT JOIN ".DB_PREFIXE."etat_dossier_autorisation
                        ON  dossier_autorisation.etat_dossier_autorisation = etat_dossier_autorisation.etat_dossier_autorisation
                    LEFT JOIN ".DB_PREFIXE."dossier_autorisation_type_detaille
                        ON dossier_autorisation.dossier_autorisation_type_detaille = dossier_autorisation_type_detaille.dossier_autorisation_type_detaille
                    LEFT JOIN ".DB_PREFIXE."dossier_autorisation_type
                        ON dossier_autorisation_type_detaille.dossier_autorisation_type = dossier_autorisation_type.dossier_autorisation_type
                    LEFT JOIN ".DB_PREFIXE."groupe
                        ON dossier_autorisation_type.groupe = groupe.groupe
                WHERE dossier.dossier = '".$dossier."'";
        $res = $this->db->query($sql);
        $this->f->addToLog("getSpecificMetadata() : db->query(".$sql.")", VERBOSE_MODE);
        if ( database::isError($res)){
            die();
        }
        
        //Le résultat est récupéré dans un objet
        $row =& $res->fetchRow(DB_FETCHMODE_OBJECT);

        //Si il y a un résultat
        if ($row !== null) {

            // Instrance de la classe dossier
            $inst_dossier = $this->get_inst_dossier($dossier);

            // Insère l'attribut version à l'objet
            $row->version = $inst_dossier->get_dossier_instruction_version();

            //Alors on créé l'objet dossier_instruction
            $this->specificMetadata = $row;

        }
    }
    
    /**
     * Retourne le statut du dossier d'instruction
     * @param string $idx Identifiant du dossier d'instruction
     * @return string Le statut du dossier d'instruction
     */
    function getStatutAutorisationDossier($idx){
        
        $statut = '';
        
        //Si l'identifiant du dossier d'instruction fourni est correct
        if ( $idx != '' ){
            
            //On récupère le statut de l'état du dossier à partir de l'identifiant du
            //dossier
            $sql = "SELECT etat.statut
                FROM ".DB_PREFIXE."dossier
                LEFT JOIN
                    ".DB_PREFIXE."etat
                    ON
                        dossier.etat = etat.etat
                WHERE dossier ='".$idx."'";
            $statut = $this->db->getOne($sql);
            $this->f->addToLog("getStatutAutorisationDossier() : db->getOne(\"".$sql."\")", VERBOSE_MODE);
            if ( database::isError($statut)){
                die();
            }
        }
        return $statut;
    }

    /**
     * Récupère les données du dossier
     * @return array
     */
    function get_dossier_actual() {

        // Initialisation de la valeur de retour
        $return = array();

        // Récupération de toutes les valeurs du dossier d'instruction en cours
        $sql = "SELECT * FROM ".DB_PREFIXE."dossier
        WHERE dossier='".$this->valF['dossier']."'";
        $res = $this->db->query($sql);
        $this->addToLog("get_dossier_actual(): db->query(\"".$sql."\");", VERBOSE_MODE);
        $this->f->isDatabaseError($res);

        //
        while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {

            // Récupération de la valeur actuelle du délai, de l'accord tacite,
            // de l'état et de l'avis du dossier d'instruction
            $return['archive_delai']=$row['delai'];
            $return['archive_accord_tacite']=$row['accord_tacite'];
            $return['archive_etat']=$row['etat'];
            $return['archive_avis']=$row['avis_decision'];
            // Récupération de la valeur actuelle des 9 dates du dossier
            // d'instruction
            $return['archive_date_complet']=$row['date_complet'];
            $return['archive_date_dernier_depot']=$row['date_dernier_depot'];
            $return['archive_date_rejet']= $row['date_rejet'];
            $return['archive_date_limite']= $row['date_limite'];
            $return['archive_date_notification_delai']= $row['date_notification_delai'];
            $return['archive_date_decision']= $row['date_decision'];
            $return['archive_date_validite']= $row['date_validite'];
            $return['archive_date_achevement']= $row['date_achevement'];
            $return['archive_date_chantier']= $row['date_chantier'];
            $return['archive_date_conformite']= $row['date_conformite'];
            $return['archive_incompletude']= $row['incompletude'];
            $return['archive_incomplet_notifie']= $row['incomplet_notifie'];
            $return['archive_evenement_suivant_tacite']= $row['evenement_suivant_tacite'];
            $return['archive_evenement_suivant_tacite_incompletude']= $row['evenement_suivant_tacite_incompletude'];
            $return['archive_etat_pendant_incompletude']= $row['etat_pendant_incompletude'];
            $return['archive_date_limite_incompletude']= $row['date_limite_incompletude'];
            $return['archive_delai_incompletude']= $row['delai_incompletude'];
            $return['archive_autorite_competente']= $row['autorite_competente'];
            $return['duree_validite']= $row['duree_validite'];
            $return['date_depot']= $row['date_depot'];
        }

        // Retour de la fonction
        return $return;

    }

    /**
     * Permet de vérifier qu'un événement est verrouillable
     * @param  integer $idx     Identifiant de l'instruction
     * @return boolean          
     */
    function checkEvenementNonVerrouillable($idx) {

        // Initialisation du résultat
        $non_verrouillable = false;

        // Si la condition n'est pas vide
        if ($idx != "") {

            // Requête SQL
            $sql = "SELECT evenement.non_verrouillable
                    FROM ".DB_PREFIXE."evenement
                    LEFT JOIN ".DB_PREFIXE."instruction
                        ON instruction.evenement = evenement.evenement
                    WHERE instruction.instruction = $idx";
            $this->f->addToLog("checkEvenementNonVerrouillable() : db->getOne(\"".$sql."\")", VERBOSE_MODE);
            $res = $this->db->getOne($sql);
            $this->f->isDatabaseError($res);

            // Si le retour de la requête est true
            if ($res == 't') {
                // 
                $non_verrouillable = true;
            }
        }

        // Retourne résultat
        return $non_verrouillable;
    }
    
    /**
     * Mise à jour des champs archive_*
     * @param mixed $row La ligne de données
     */
    public function updateArchiveData($row){
        
        // Récupération de la valeur actuelle du délai, de l'accord tacite,
        // de l'état et de l'avis du dossier d'instruction
        $this->valF['archive_delai']=$row['delai'];
        $this->valF['archive_accord_tacite']=$row['accord_tacite'];
        $this->valF['archive_etat']=$row['etat'];
        $this->valF['archive_avis']=$row['avis_decision'];
        // Récupération de la valeur actuelle des 9 dates du dossier
        // d'instruction
        if ($row['date_complet'] != '') {
            $this->valF['archive_date_complet']=$row['date_complet'];
        }
        if ($row['date_dernier_depot'] != '') {
            $this->valF['archive_date_dernier_depot']=$row['date_dernier_depot'];
        }
        if ($row['date_rejet']!='') {
            $this->valF['archive_date_rejet']= $row['date_rejet'];
        }
        if ($row['date_limite']!='') {
            $this->valF['archive_date_limite']= $row['date_limite'];
        }
        if ($row['date_notification_delai']!='') {
            $this->valF['archive_date_notification_delai']= $row['date_notification_delai'];
        }
        if ($row['date_decision']!='') {
            $this->valF['archive_date_decision']= $row['date_decision'];
        }
        if ($row['date_validite']!='') {
            $this->valF['archive_date_validite']= $row['date_validite'];
        }
        if ($row['date_achevement']!='') {
            $this->valF['archive_date_achevement']= $row['date_achevement'];
        }
        if ($row['date_chantier']!='') {
            $this->valF['archive_date_chantier']= $row['date_chantier'];
        }
        if ($row['date_conformite']!='') {
            $this->valF['archive_date_conformite']= $row['date_conformite'];  
        }
        if ($row['incompletude']!='') {
            $this->valF['archive_incompletude']= $row['incompletude'];  
        }
        if ($row['incomplet_notifie']!='') {
            $this->valF['archive_incomplet_notifie']= $row['incomplet_notifie'];  
        }
        if ($row['evenement_suivant_tacite']!='') {
            $this->valF['archive_evenement_suivant_tacite']= $row['evenement_suivant_tacite'];  
        }
        if ($row['evenement_suivant_tacite_incompletude']!='') {
            $this->valF['archive_evenement_suivant_tacite_incompletude']= $row['evenement_suivant_tacite_incompletude'];  
        }
        if ($row['etat_pendant_incompletude']!='') {
            $this->valF['archive_etat_pendant_incompletude']= $row['etat_pendant_incompletude'];  
        }
        if ($row['date_limite_incompletude']!='') {
            $this->valF['archive_date_limite_incompletude']= $row['date_limite_incompletude'];  
        }
        if ($row['delai_incompletude']!='') {
            $this->valF['archive_delai_incompletude']= $row['delai_incompletude'];  
        }
        if ($row['autorite_competente']!='') {
            $this->valF['archive_autorite_competente']= $row['autorite_competente'];  
        }
        if ($row['duree_validite']!='') {
            $this->valF['duree_validite']= $row['duree_validite'];  
        }
        if ($row['date_depot']!='') {
            $this->valF['date_depot']= $row['date_depot'];  
        }
    }

    // {{{
    // Méthodes de récupération des métadonnées arrêté
    /**
     * @return string Retourne le numéro d'arrêté
     */
    function getNumArrete() {
        return $this->getVal("numero_arrete");
    }
    /**
     * @return chaîne vide
     */
    function getReglementaireArrete() {
        return 'true';
    }
    /**
     * @return boolean de notification au pétitionnaire
     */
    function getNotificationArrete() {
        return 'true';
    }
    /**
     * @return date de notification au pétitionnaire
     */
    function getDateNotificationArrete() {
        if (empty($this->metadonneesArrete)) {
            $this->getArreteMetadata();
        }
        return $this->metadonneesArrete["datenotification"];
    }
    /**
     * @return boolean check si le document est passé au contrôle de légalité
     */
    function getControleLegalite() {
        return 'true';
    }
    /**
     * @return date de signature de l'arrêté
     */
    function getDateSignature() {
        if (empty($this->metadonneesArrete)) {
            $this->getArreteMetadata();
        }
        return $this->metadonneesArrete["datesignaturearrete"];
    }
    /**
     * @return string nom du signataire
     */
    function getNomSignataire() {
        if (empty($this->metadonneesArrete)) {
            $this->getArreteMetadata();
        }
        return $this->metadonneesArrete["nomsignataire"];
    }
    /**
     * @return string qualité du signataire
     */
    function getQualiteSignataire() {
        if (empty($this->metadonneesArrete)) {
            $this->getArreteMetadata();
        }
        return $this->metadonneesArrete["qualitesignataire"];
    }
    /**
     * @return string numéro du terrain
     */
    function getAp_numRue() {
        if (empty($this->metadonneesArrete)) {
            $this->getArreteMetadata();
        }
        return $this->metadonneesArrete["ap_numrue"];
    }
    /**
     * @return string nom de la rue du terrain
     */
    function getAp_nomDeLaVoie() {
        if (empty($this->metadonneesArrete)) {
            $this->getArreteMetadata();
        }
        return $this->metadonneesArrete["ap_nomdelavoie"];
    }
    /**
     * @return string code postal du terrain
     */
    function getAp_codePostal() {
        if (empty($this->metadonneesArrete)) {
            $this->getArreteMetadata();
        }
        return $this->metadonneesArrete["ap_codepostal"];
    }
    /**
     * @return string ville du terrain
     */
    function getAp_ville() {
        if (empty($this->metadonneesArrete)) {
            $this->getArreteMetadata();
        }
        return $this->metadonneesArrete["ap_ville"];
    }
    /**
     * @return string activité
     */
    function getActivite() {
        return "Droit du sol";
    }
    /**
     * @return string date du retour de controle légalité
     */
    function getDateControleLegalite() {
        if (empty($this->metadonneesArrete)) {
            $this->getArreteMetadata();
        }
        return $this->metadonneesArrete["datecontrolelegalite"];
    }

    // Fin des méthodes de récupération des métadonnées
    // }}}

    /**
     * Méthode de récupération des métadonnées arrêtés dans la base de données,
     * les données sont stockés dans l'attribut $this->metadonneesArrete
     */
    function getArreteMetadata() {

    //Récupération de la dernière instruction dont l'événement est de type 'arrete'
    $this->metadonneesArrete = array("nomsignataire"=>"", "qualitesignataire"=>"",
        "decisionarrete"=>"", "datenotification"=>"", "datesignaturearrete"=>"",
        "datecontrolelegalite"=>"", "ap_numrue"=>"", "ap_nomdelavoie"=>"",
        "ap_codepostal"=>"", "ap_ville"=>"");

        $sqlArrete = "SELECT    signataire_arrete.nom as \"nomsignataire\",
                signataire_arrete.qualite as \"qualitesignataire\",
                instruction.etat as \"decisionarrete\",
                instruction.date_retour_rar as \"datenotification\",
                instruction.date_retour_signature as \"datesignaturearrete\",
                instruction.date_retour_controle_legalite as \"datecontrolelegalite\",
                dossier.terrain_adresse_voie_numero as \"ap_numrue\",
                dossier.terrain_adresse_voie as \"ap_nomdelavoie\",
                dossier.terrain_adresse_code_postal as \"ap_codepostal\",
                dossier.terrain_adresse_localite as \"ap_ville\"
            FROM ".DB_PREFIXE."instruction
            LEFT JOIN ".DB_PREFIXE."signataire_arrete ON
                instruction.signataire_arrete = signataire_arrete.signataire_arrete
            LEFT JOIN ".DB_PREFIXE."dossier ON
                instruction.dossier = dossier.dossier
            LEFT JOIN ".DB_PREFIXE."donnees_techniques ON
                    donnees_techniques.dossier_instruction = dossier.dossier
            WHERE instruction.instruction = ".$this->getVal("instruction");
        $resArrete = $this->db->query($sqlArrete);
        $this->f->addToLog("getArreteMetadata(): db->query(\"".$sqlArrete."\");", VERBOSE_MODE);
        if ( database::isError($resArrete)){
            die();
        }

        $this->metadonneesArrete = $resArrete->fetchRow(DB_FETCHMODE_ASSOC);
    }

    /**
     * CONDITION - has_an_edition.
     *
     * Condition pour afficher le bouton de visualisation de l'édition.
     *
     * @return boolean
     */
    function has_an_edition() {
        // Récupère la valeur du champ lettretype
        $lettretype = $this->getVal("lettretype");
        // Si le champ est vide
        if (empty($lettretype)) {
            //
            return false;
        }

        //
        return true;
    }

    /**
     * CONDITION - is_editable.
     *
     * Condition pour la modification.
     *
     * @return boolean
     */
    function is_editable() {
        // Contrôle si l'utilisateur possède un bypass
        $bypass = $this->f->isAccredited(get_class()."_modifier_bypass");
        //
        if ($bypass == true) {

            //
            return true;
        }

        // Si l'utilisateur est un intructeur qui ne correspond pas à la
        // division du dossier
        if ($this->f->isUserInstructeur()
            && $this->f->om_utilisateur["division"] != $this->getDivisionFromDossier()
            && $this->f->isAccredited("instruction_changer_decision") === false) {

            //
            return false;
        }

        // si instructeur commune
        if($this->f->isAccredited("instruction_changer_decision") === true
            && $this->f->om_utilisateur["division"] != $this->getDivisionFromDossier()
            && ($this->f->isInstrCanChangeDecision($this->getVal('dossier')) !== true
            || $this->getVal('created_by_commune') !== 't')) {
            return false;
        }
        // Si l'utilisateur est un instructeur, que le dossier est cloturé et
        // que l'événement n'est pas identifié comme non verrouillable
        if ($this->f->isUserInstructeur()
            && $this->getStatutAutorisationDossier($this->getParameter("idxformulaire")) == "cloture"
            && $this->checkEvenementNonVerrouillable($this->getVal("instruction")) === false) {

            //
            return false;
        }

        //
        return true;
    }

    /**
     * CONDITION - is_deletable.
     *
     * Condition pour lma modification.
     *
     * @return boolean
     */
    function is_deletable() {
        // Contrôle si l'utilisateur possède un bypass
        $bypass = $this->f->isAccredited(get_class()."_supprimer_bypass");
        //
        if ($bypass == true) {

            //
            return true;
        }

        // Si l'utilisateur est un intructeur qui ne correspond pas à la
        // division du dossier
        if ($this->f->isUserInstructeur()
            && $this->f->om_utilisateur["division"] != $this->getDivisionFromDossier()) {

            //
            return false;
        }

        //
        return true;
    }

    /**
     * CONDITION - is_addable.
     * 
     * Condition pour afficher les boutons modifier et supprimer.
     *
     * @return boolean
     */
    function is_addable() {
        // Contrôle si l'utilisateur possède un bypass
        $bypass = $this->f->isAccredited(get_class()."_ajouter_bypass");
        //
        if ($bypass == true) {

            //
            return true;
        }

        // Si l'utilisateur est un intructeur qui ne correspond pas à la
        // division du dossier
        if ($this->f->isUserInstructeur()
            && $this->f->om_utilisateur["division"] != $this->getDivisionFromDossier()
            && $this->f->isAccredited("instruction_changer_decision") === false) {

            //
            return false;
        }

        // si instructeur commune
        if($this->f->isAccredited("instruction_changer_decision") === false
            && $this->f->isInstrCanChangeDecision($this->getVal('dossier')) === true) {
            return false;
        }


        //
        return true;
    }

    /**
     * CONDITION - is_finalizable.
     *
     * Condition pour afficher le bouton.
     *
     * @return boolean
     */
    function is_finalizable() {
        // Contrôle si l'utilisateur possède un bypass
        $bypass = $this->f->isAccredited(get_class()."_finaliser_bypass");
        //
        if ($bypass == true) {

            //
            return true;
        }

        // Si l'utilisateur est un intructeur qui ne correspond pas à la
        // division du dossier
        if ($this->f->isUserInstructeur()
            && $this->f->om_utilisateur["division"] != $this->getDivisionFromDossier()
            && $this->f->isAccredited("instruction_changer_decision") === false) {

            //
            return false;
        }

        // si instructeur commune
        if($this->f->isAccredited("instruction_changer_decision") === true
            && $this->f->om_utilisateur["division"] != $this->getDivisionFromDossier()
            && ($this->f->isInstrCanChangeDecision($this->getVal('dossier')) !== true
            || $this->getVal('created_by_commune') !== 't')) {
            return false;
        }

        // Si l'utilisateur est un instructeur, que le dossier est cloturé et
        // que l'événement n'est pas identifié comme non verrouillable
        if ($this->f->isUserInstructeur()
            && $this->getStatutAutorisationDossier($this->getParameter("idxformulaire")) == "cloture"
            && $this->checkEvenementNonVerrouillable($this->getVal("instruction")) === false) {

            //
            return false;
        }

        //
        return true;
    }

    /**
     * CONDITION - is_finalize_without_bypass.
     *
     * Condition pour afficher le bouton sans le bypass.
     *
     * @return boolean [description]
     */
    function is_finalizable_without_bypass() {
        // Récupère la valeur du champ finalisé
        $om_final_instruction = $this->getVal('om_final_instruction');

        // Si le rapport n'est pas finalisé
        if (empty($om_final_instruction)
            || $om_final_instruction == 'f') {
            //
            return true;
        }

        //
        return false;
    }

    /**
     * CONDITION - is_unfinalizable.
     *
     * Condition pour afficher le bouton.
     *
     * @return boolean
     */
    function is_unfinalizable(){
        // Contrôle si l'utilisateur possède un bypass
        $bypass = $this->f->isAccredited(get_class()."_definaliser_bypass");
        //
        if ($bypass == true) {

            //
            return true;
        }

        // Si l'utilisateur est un intructeur qui ne correspond pas à la
        // division du dossier
        if ($this->f->isUserInstructeur()
            && $this->f->om_utilisateur["division"] != $this->getDivisionFromDossier()
            && $this->f->isAccredited("instruction_changer_decision") === false) {

            //
            return false;
        }

        // si instructeur commune
        if($this->f->isAccredited("instruction_changer_decision") === true
            && $this->f->om_utilisateur["division"] != $this->getDivisionFromDossier()
            && ($this->f->isInstrCanChangeDecision($this->getVal('dossier')) !== true
            || $this->getVal('created_by_commune') !== 't')) {
            return false;
        }

        // Si l'utilisateur est un instructeur, que le dossier est cloturé et
        // que l'événement n'est pas identifié comme non verrouillable
        if ($this->f->isUserInstructeur()
            && $this->getStatutAutorisationDossier($this->getParameter("idxformulaire")) == "cloture"
            && $this->checkEvenementNonVerrouillable($this->getVal("instruction")) === false) {

            //
            return false;
        }

        //
        return true;
    }

    /**
     * CONDITION - is_unfinalizable_without_bypass.
     *
     * Condition pour afficher le bouton sans le bypass.
     *
     * @return boolean
     */
    function is_unfinalizable_without_bypass() {
        // Récupère la valeur du champ finalisé
        $om_final_instruction = $this->getVal('om_final_instruction');

        // Si l'instruction est finalisée
        if ($om_final_instruction == 't') {
            //
            return true;
        }

        //
        return false;
    }

    /**
     * TREATMENT - finalize.
     *
     * Permet de finaliser un enregistrement.
     *
     * @param array $val valeurs soumises par le formulaire
     *
     * @return boolean
     */
    function finalize($val = array()) {

        // Cette méthode permet d'exécuter une routine en début des méthodes
        // dites de TREATMENT.
        $this->begin_treatment(__METHOD__);

        // Traitement de la finalisation
        $ret = $this->manage_finalizing("finalize", $val);

        // Si le traitement retourne une erreur
        if ($ret !== true) {

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

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

    /**
     * TREATMENT - unfinalize.
     *
     * Permet de définaliser un enregistrement.
     *
     * @param array $val valeurs soumises par le formulaire
     *
     * @return boolean
     */
    function unfinalize($val = array()) {

        // Cette méthode permet d'exécuter une routine en début des méthodes
        // dites de TREATMENT.
        $this->begin_treatment(__METHOD__);

        // Traitement de la finalisation
        $ret = $this->manage_finalizing("unfinalize", $val);

        // Si le traitement retourne une erreur
        if ($ret !== true) {

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

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

    /**
     * VIEW - view_edition
     * 
     * Edite l'édition de l'instruction ou affiche celle contenue dans le stockage.
     *
     * @return null Si l'action est incorrecte
     */
    function view_edition() {

        // Si l'instruction est finalisée
        if($this->getVal("om_final_instruction") == 't'
            && $this->getVal("om_final_instruction") != null) {

            // Ouvre le document
            $lien = '../spg/file.php?obj='.$this->table.'&'.
                    'champ=om_fichier_instruction&id='.$this->getVal($this->clePrimaire);
            //
            header("Location: ".$lien);
        } else {

            // Récupère la collectivite du dossier d'instruction
            $dossier_instruction_om_collectivite = $this->get_dossier_instruction_om_collectivite();

            //
            $collectivite = $this->f->getCollectivite($dossier_instruction_om_collectivite);

            // Paramètre du PDF
            $params = array(
                "watermark" => true, 
                "specific" => array(
                    "mode" => "previsualisation",
                ),
            );

            // Génération du PDF
            $result = $this->compute_pdf_output('lettretype', $this->getVal("lettretype"), $collectivite, null, $params);
            // Affichage du PDF
            $this->expose_pdf_output(
                $result['pdf_output'], 
                $result['filename']
            );
        }
    }

    /**
     * Récupère la collectivité du dossier d'instruction.
     *
     * @return integer
     */
    function get_dossier_instruction_om_collectivite() {

        //
        require_once "../obj/dossier_instruction.class.php";
        $dossier_instruction = new dossier_instruction($this->getVal('dossier'), $this->f->db, false);

        //
        return $dossier_instruction->getVal('om_collectivite');
    }

    /**
     * VIEW - view_bible
     *
     * Affiche la bible manuelle.
     *
     * @return void
     */
    function view_bible() {
        // Vérification de l'accessibilité sur l'élément
        $this->checkAccessibility();

        // XXX APP

        $f = $this->f;

        /**
         * Affichage de la structure HTML
         */
        //
        if ($f->isAjaxRequest()) {
            //
            header("Content-type: text/html; charset=".HTTPCHARSET."");
        } else {
            //
            $f->setFlag("htmlonly");
            $f->display();
        }
        //
        $f->displayStartContent();
        //
        $f->setTitle(_("Liste des éléments de la bible en lien avec un evenement"));
        $f->displayTitle();

        /**
         *
         */
        //
        ($f->get_submitted_get_value("ev") ? $evenement = $f->get_submitted_get_value("ev") : $evenement = "");
        $evenement = intval($evenement);
        //
        ($f->get_submitted_get_value("idx") ? $idx = $f->get_submitted_get_value("idx") : $idx = "");
        $nature = substr($idx, 0, 2);
        //
        ($f->get_submitted_get_value("complement") ? $complement = $f->get_submitted_get_value("complement") : $complement = "1");

        // Récupération de la collectivité du dossier
        require_once "../obj/dossier.class.php";
        $dossier = new dossier($idx, $f->db, DEBUG);

        /**
         *
         */
        //
        $sql = "SELECT *, bible.libelle as bible_lib
        FROM ".DB_PREFIXE."bible
        LEFT OUTER JOIN ".DB_PREFIXE."dossier_autorisation_type 
            ON bible.dossier_autorisation_type=dossier_autorisation_type.dossier_autorisation_type
        LEFT JOIN ".DB_PREFIXE."om_collectivite
            ON bible.om_collectivite = om_collectivite.om_collectivite
        WHERE evenement=".$evenement."
            AND complement=".$complement."
            AND (bible.dossier_autorisation_type IS NULL
                OR dossier_autorisation_type.code ='".$nature."')
            AND (om_collectivite.niveau = '2'
                OR bible.om_collectivite = ".$dossier->getVal("om_collectivite").")
        ORDER BY bible_lib ASC";
        $res = $f->db->query($sql);
        $f->addToLog(__METHOD__.": db->query(\"".$sql."\");", VERBOSE_MODE);
        $f->isDatabaseError($res);
        //
        echo "<form method=\"post\" name=\"f3\" action=\"#\">\n";
        //
        if ($res->numrows() > 0) {
            //
            echo "\t<table id='tab-bible' width='100%'>\n";
            //
            echo "\t\t<tr class=\"ui-tabs-nav ui-accordion ui-state-default tab-title\">";
            echo "<th>"._("Choisir")."</th>";
            echo "<th>"._("Libelle")."</th>";
            echo "</tr>\n";
            //
            $i = 0;
            //
            while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
                //
                echo "\t\t<tr";
                echo " class=\"".($i % 2 == 0 ? "odd" : "even")."\"";
                echo ">";
                //
                echo "<td class=\"center\"><input type=\"checkbox\" name=\"choix[]\" value=\"".$i."\" id=\"checkbox".$i."\" /></td>";
                // XXX utilisation de l'attribut titre pour afficher une infobulle
                echo "<td><span class=\"content\" title=\"".htmlentities($row['contenu'])."\" id=\"content".$i."\">".$row['bible_lib']."</span></td>";
                //
                echo "</tr>\n";
                //
                $i++;
            }
            echo "\t</table>\n";
            //
            echo "<div class=\"formControls\">\n";
            $f->layout->display_form_button(array(
                "value" => _("Valider"),
                "onclick" => "bible_return('f2', 'complement".($complement == "1" ? "" : $complement)."_om_html'); return false;",
            ));
            $f->displayLinkJsCloseWindow();
            echo "</div>\n";

        } else {
            //
            $message_class = "error";
            $message = _("Aucun element dans la bible pour l'evenement")." : ".$evenement;
            $f->displayMessage($message_class, $message);
            //
            echo "<div class=\"formControls\">\n";
            $f->displayLinkJsCloseWindow();
            echo "</div>\n";
        }
        //
        echo "</form>\n";

        /**
         * Affichage de la structure HTML
         */
        //
        $f->displayEndContent();
    }

    /**
     * VIEW - view_bible
     *
     * Affiche la bible manuelle.
     *
     * @return void
     */
    function view_bible_auto() {
        // Vérification de l'accessibilité sur l'élément
        $this->checkAccessibility();

        // XXX APP

        $f = $this->f;

        //
        $f->disableLog();

        $formatDate="AAAA-MM-JJ";

        // Récupération des paramètres
        $idx = $f->get_submitted_get_value('idx');
        $evenement = $f->get_submitted_get_value('ev');

        // Initialisation de la variable de retour
        $retour['complement_om_html'] = '';
        $retour['complement2_om_html'] = '';
        $retour['complement3_om_html'] = '';
        $retour['complement4_om_html'] = '';
        // Vérification d'une consultation liée à l'événement
        $consultation = $f->db->getOne(
            "select consultation from ".DB_PREFIXE."evenement where evenement=".$evenement
        );
        $f->isDatabaseError($consultation);
        // Si consultation liée, récupération du retour d'avis
        if($consultation=='Oui'){
            $sql="select date_retour,avis_consultation.libelle as avis_consultation,
                  service.libelle as service
                  from ".DB_PREFIXE."consultation inner join ".DB_PREFIXE."service
                  on consultation.service =service.service
                  left join ".DB_PREFIXE."avis_consultation on
                    consultation.avis_consultation = avis_consultation.avis_consultation
                  where dossier ='".$idx."'";
            $res = $f->db->query($sql);
            $f->isDatabaseError($res);
            // Récupération des consultations
            while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)){
                $correct=false;
                // date retour
                if ($row['date_retour']<>""){
                    if ($formatDate=="AAAA-MM-JJ"){
                        $date = explode("-", $row['date_retour']);
                        // controle de date
                        if (count($date) == 3 and
                                checkdate($date[1], $date[2], $date[0])) {
                            $date_retour_f= $date[2]."/".$date[1]."/".$date[0];
                            $correct=true;
                        }else{
                            $msg= $msg."<br>La date ".$row['date_retour']." n'est pas une date.";
                            $correct=false;
                        }
                    }
                }
                // 
                $temp="Vu l'avis ".$row['avis_consultation']." du service ".$row['service'];
                if($correct == true){
                    $temp=$temp." du ".$date_retour_f;
                }
                // Concaténation des retours d'avis de consultation 
                $retour['complement_om_html'] .= $temp;
            } // while
            
        } // consultation
        // Récupération des bibles automatiques pour le champ complement_om_html
        $retour['complement_om_html'] .= $this->getBible($f, $evenement, $idx, '1');
        // Récupération des bibles automatiques pour le champ complement2_om_html
        $retour['complement2_om_html'] .= $this->getBible($f, $evenement, $idx, '2');
        // Récupération des bibles automatiques pour le champ complement3_om_html
        $retour['complement3_om_html'] .= $this->getBible($f, $evenement, $idx, '3');
        // Récupération des bibles automatiques pour le champ complement4_om_html
        $retour['complement4_om_html'] .= $this->getBible($f, $evenement, $idx, '4');



        echo json_encode($retour);
    }

    /**
     * Récupération des éléments de bible.
     *
     * @param utils   $f      handler de om_application
     * @param integer $event  id de l'événement
     * @param string  $idx    id du dossier
     * @param integer $compnb numéro du champ complement
     *
     * @return string   Chaîne de texte à insérer dans le champ complement
     */
    function getBible($f, $event, $idx, $compnb) {
        // Récupération de la collectivité du dossier
        require_once "../obj/dossier.class.php";
        $dossier = new dossier($idx, $f->db, DEBUG);
        //
        $sql = "SELECT * FROM ".DB_PREFIXE."bible
            LEFT OUTER JOIN ".DB_PREFIXE."dossier_autorisation_type 
                ON bible.dossier_autorisation_type=
                    dossier_autorisation_type.dossier_autorisation_type
            LEFT JOIN
                    ".DB_PREFIXE."om_collectivite
                    ON bible.om_collectivite = om_collectivite.om_collectivite
            WHERE evenement =".$event." and
                complement=".$compnb." and
                automatique='Oui' and
                (dossier_autorisation_type.code ='".substr($idx, 0, 2)."' or
                    bible.dossier_autorisation_type IS NULL) and
                (om_collectivite.niveau = '2' OR bible.om_collectivite = ".$dossier->getVal("om_collectivite").")";

        $res = $f->db->query($sql);
        $f->isDatabaseError($res);
        $temp = "";
        while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)){
            // Remplacement des retours à la ligne par des br
            $temp .= preg_replace(
                '#(\\\r|\\\r\\\n|\\\n)#', '<br/>', $row['contenu']
            );
        } // fin while
        return $temp;
    }

    /**
     * VIEW - view_suivi_bordereaux.
     *
     * Formulaire de choix du bordereau de suivi, permettant de générer les 4 bordereaux.
     * Si l'utilisateur est d'une collectivité de niveau 2 il a le choix de la
     * collectivité des dossiers affichés.
     *
     * @return void
     */
    function view_suivi_bordereaux() {
        // Vérification de l'accessibilité sur l'élément
        $this->checkAccessibility();

        // XXX APP

        $f = $this->f;

        /**
         * Validation du formulaire
         */
        // Si le formulaire a été validé
        if ($f->get_submitted_post_value("validation") !== null) {
            // Si un bordereau à été sélectionné
            if ($f->get_submitted_post_value("bordereau") !== null && $f->get_submitted_post_value("bordereau") == "" ) {
                // Si aucun bordereau n'a été sélectionné
                $message_class = "error";
                $message = _("Veuillez selectionner un bordereau.");
            }
            // Sinon si les dates ne sont pas valide 
            elseif (($f->get_submitted_post_value("date_bordereau_debut") !== null
                && $f->get_submitted_post_value("date_bordereau_debut") == "")
                || ($f->get_submitted_post_value("date_bordereau_fin") !== null 
                && $f->get_submitted_post_value("date_bordereau_fin") == "")) {
                // Si aucune date n'a été saisie
                $message_class = "error";
                $message = _("Veuillez saisir une date valide.");
            } 
            // Affiche le message de validation
            else {
                // On récupère le libellé du bordereau pour l'afficher à l'utilisateur
                $sql = "SELECT om_etat.libelle
                FROM ".DB_PREFIXE."om_etat
                WHERE om_etat.id = '".$f->get_submitted_post_value("bordereau")."'";
                $res = $f->db->getone($sql);
                $f->addToLog(__METHOD__.": db->getone(\"".$sql."\")", VERBOSE_MODE);
                $f->isDatabaseError($res);
                //
                $message_class = "valid";
                $message = _("Cliquez sur le lien ci-dessous pour telecharger votre bordereau");
                $message .= " : <br/><br/>";
                $message .= "<a class='om-prev-icon pdf-16'";
                $message .= " title=\""._("Bordereau")."\"";
                $message .= "href='../scr/form.php?obj=instruction";
                $message .= "&action=220";
                $message .= "&idx=0";
                $message .= "&type_bordereau=".$f->get_submitted_post_value("bordereau");
                $message .= "&date_bordereau_debut=".$f->get_submitted_post_value("date_bordereau_debut");
                $message .= "&date_bordereau_fin=".$f->get_submitted_post_value("date_bordereau_fin");
                // Si l'utilisateur est MULTI alors on ajoute le paramètre collectivite
                if ($f->get_submitted_post_value("om_collectivite") !== null) {
                    $message .= "&collectivite=".$f->get_submitted_post_value("om_collectivite");
                }
                $message .= "'"." target='_blank'>";
                $message .= $res." "._("du")." ".$f->get_submitted_post_value("date_bordereau_debut")
                    ." "._("au")." ".$f->get_submitted_post_value("date_bordereau_fin");
                $message .= "</a>";
            }
        }

        /**
         * Affichage des messages et du formulaire
         */
        // Affichage du message de validation ou d'erreur
        if (isset($message) && isset($message_class) && $message != "") {
            $f->displayMessage($message_class, $message);
        }
        // Inclusion de la classe de gestion des formulaires
        require_once "../obj/om_formulaire.class.php";
        // Ouverture du formulaire
        printf("\t<form");
        printf(" method=\"post\"");
        printf(" id=\"suivi_bordereaux_form\"");
        printf(" action=\"\"");
        printf(">\n");
        // Paramétrage des champs du formulaire
        $champs = array("date_bordereau_debut", "date_bordereau_fin", "bordereau");
        // Si l'utilisateur est d'une collectivité de niveau 2 on affiche un select 
        // collectivité dans le formulaire
        if($_SESSION["niveau"] == 2) {
            array_push($champs, "om_collectivite");
        }
        // Création d'un nouvel objet de type formulaire
        $form = new formulaire(NULL, 0, 0, $champs);
        // Paramétrage du champ date_bordereau_debut
        $form->setLib("date_bordereau_debut", _("date_bordereau_debut"));
        $form->setType("date_bordereau_debut", "date");
        $form->setTaille("date_bordereau_debut", 12);
        $form->setMax("date_bordereau_debut", 12);
        $form->setRequired("date_bordereau_debut");
        $form->setOnchange("date_bordereau_debut", "fdate(this)");
        $form->setVal("date_bordereau_debut", date("d/m/Y"));
        // Paramétrage du champ date_bordereau_fin
        $form->setLib("date_bordereau_fin", _("date_bordereau_fin"));
        $form->setType("date_bordereau_fin", "date");
        $form->setTaille("date_bordereau_fin", 12);
        $form->setMax("date_bordereau_fin", 12);
        $form->setRequired("date_bordereau_fin");
        $form->setOnchange("date_bordereau_fin", "fdate(this)");
        $form->setVal("date_bordereau_fin", date("d/m/Y"));
        // Paramétrage du champ bordereau
        $form->setLib("bordereau", _("bordereau"));
        $form->setType("bordereau", "select");
        $form->setRequired("bordereau");
        // Valeurs des champs
        if ($f->get_submitted_post_value("validation") !== null) {
            $form->setVal("date_bordereau_debut", $f->get_submitted_post_value("date_bordereau_debut"));
            $form->setVal("date_bordereau_fin", $f->get_submitted_post_value("date_bordereau_fin"));
            $form->setVal("bordereau", $f->get_submitted_post_value("bordereau"));
            $form->setVal("om_collectivite", $f->get_submitted_post_value("om_collectivite"));
        }
        // Données du select - On récupère ici la liste de tous les états disponibles
        // dans la table om_etat qui ont un id qui commence par la cahine de caractères
        // 'bordereau_'
        $sql = "SELECT om_etat.id, om_etat.libelle
                FROM ".DB_PREFIXE."om_etat
                WHERE om_etat.id LIKE 'bordereau_%'
                ORDER BY om_etat.id";
        $res = $f->db->query($sql);
        $f->addToLog(__METHOD__.": db->query(\"".$sql."\")", VERBOSE_MODE);
        $f->isDatabaseError($res);
        // Données du select
        $contenu = array(
            0 => array("", ),
            1 => array(_("choisir bordereau")),
        );
        while ($row =& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
            $contenu[0][] = $row['id'];
            $contenu[1][] = $row['libelle'];
        }
        $form->setSelect("bordereau", $contenu);
    // 
    if($_SESSION["niveau"] == 2) {
        $form->setLib("om_collectivite", _("collectivite"));
        $form->setType("om_collectivite", "select");

        // Données du select - On récupère ici la liste de tous toutes les collectivités
        // de niveau 1
        $sql = "SELECT om_collectivite, libelle
                FROM ".DB_PREFIXE."om_collectivite
                WHERE niveau = '1' ORDER BY libelle";
        $res = $f->db->query($sql);
        $f->addToLog(__METHOD__.": db->query(\"".$sql."\")", VERBOSE_MODE);
        $f->isDatabaseError($res);
        // La valeur par défaut du select est Toutes 
        $list_collectivites = array(
            0 => array("", ),
            1 => array(_("toutes"))
        );

        $id_colls = "";
        // On stocke dans $id_colls l'id de toutes les collectivités de niveau 1 séparées
        // par des virgules, pour un traitement plus facile dans la requête de sous-état
        while ($row =& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
            if ($id_colls != "") {
                $id_colls .= ",";
            }
            $id_colls .= $row['om_collectivite'];
            $list_collectivites[0][] = $row['om_collectivite'];
            $list_collectivites[1][] = $row['libelle'];
        }
        // On affecte la liste d'identifiants à l'option Toutes
        $list_collectivites[0][0] = $id_colls ;
        $form->setSelect("om_collectivite", $list_collectivites);
    } 

        // Affichage du formulaire
        $form->entete();
        $form->afficher($champs, 0, false, false);
        $form->enpied();
        // Affichage du bouton
        printf("\t<div class=\"formControls\">\n");
        $f->layout->display_form_button(array("value" => _("Valider"), "name" => "validation"));
        printf("\t</div>\n");
        // Fermeture du formulaire
        printf("\t</form>\n");

    }


    /** 
     * VIEW - view_generate_suivi_bordereaux.
     * 
     * Génère et affiche les bordereaux de suivi.
     *   
     * @return [void] 
     */ 
    function view_generate_suivi_bordereaux() {
        // Vérification de l'accessibilité sur l'élément
        $this->checkAccessibility();
        // Récupération du type de bordereau
        $bordereau = $this->f->get_submitted_get_value('type_bordereau');
        // Génération du PDF
        $result = $this->compute_pdf_output('etat', $bordereau, null, $this->getVal($this->clePrimaire));
        // Affichage du PDF
        $this->expose_pdf_output(
            $result['pdf_output'],
            $result['filename']
        );
    }


    /**
     * VIEW - view_suivi_envoi_lettre_rar.
     *
     * Vu pour imprimer les RAR.
     *
     * @return void
     */
    function view_suivi_envoi_lettre_rar() {
        // Vérification de l'accessibilité sur l'élément
        $this->checkAccessibility();

        // XXX APP

        $f = $this->f;

        //
        if ($f->get_submitted_post_value("date") !== null) {
            $date = $f->get_submitted_post_value("date");
        } else {
            $date = "";
        }
        //
        if ($f->get_submitted_post_value("liste_code_barres_instruction") !== null) {
            $liste_code_barres_instruction = $f->get_submitted_post_value("liste_code_barres_instruction");
        } else {
            $liste_code_barres_instruction = "";
        }

        // Compteur du nombre de page générées
        $nbLettres = 0;
        // Liste d'id des instructions
        $id4Gen = array();
        //
        $error = "";

        /**
         * Validation du formulaire
         */
        // Si le formulaire a été validé
        if ($f->get_submitted_post_value('validation') !== null) {
            //
            if (empty($date) || empty($liste_code_barres_instruction)) {
                //
                $message_class = "error";
                $message = _("Tous les champs doivent etre remplis.");
            } else {
                // Création d'un tableau d'instruction
                $liste = explode("\r\n", $f->get_submitted_post_value("liste_code_barres_instruction"));
                //
                foreach ($liste as $code_barres) {
                    // On enlève les éventuels espaces saisis
                    $code_barres = trim($code_barres);
                    // Vérification de l'existence de l'instruction
                    if ($code_barres != "") {
                        // Si la valeur transmise est numérique
                        if (is_numeric($code_barres)) {
                            // 
                            $sql = "SELECT count(*) FROM ".DB_PREFIXE."instruction WHERE code_barres='".$code_barres."'";
                            $nbInstr = $f->db->getone($sql);
                            $f->addToLog(__METHOD__.": db->getone(\"".$sql."\")", VERBOSE_MODE);
                            $f->isDatabaseError($nbInstr);
                            // 
                            if ($nbInstr == "1") {
                                // Récupération de la date d'envoi de l'instruction bippé
                                $sql = "SELECT to_char(date_envoi_rar,'DD/MM/YYYY')  as date_envoi_rar, instruction FROM ".DB_PREFIXE."instruction WHERE code_barres='".$code_barres."'";
                                $res = $f->db->query($sql);
                                $f->addToLog(__METHOD__.": db->query(\"".$sql."\")", VERBOSE_MODE);
                                $f->isDatabaseError($res);
                                $row =& $res->fetchRow(DB_FETCHMODE_ASSOC);
                                // Si pas de date ou correspond à la date du formulaire on 
                                // effectue le traitement
                                if ($row["date_envoi_rar"] == "" || $row["date_envoi_rar"] == $date) {
                                    
                                    require_once '../obj/instruction.class.php';
                        
                                    $instr = new instruction($row['instruction'], $f->db, DEBUG);
                                    $valF = array();
                                    foreach($instr->champs as $id => $champ) {
                                        $valF[$champ] = $instr->val[$id];
                                    }
                                    $valF['date_evenement']=
                                        $instr->dateDBToForm($valF['date_evenement']);
                                    $valF['archive_date_complet']=
                                        $instr->dateDBToForm($valF['archive_date_complet']);
                                    $valF['archive_date_rejet']=
                                        $instr->dateDBToForm($valF['archive_date_rejet']);
                                    $valF['archive_date_limite']=
                                        $instr->dateDBToForm($valF['archive_date_limite']);
                                    $valF['archive_date_notification_delai']=
                                        $instr->dateDBToForm($valF['archive_date_notification_delai']);
                                    $valF['archive_date_decision']=
                                        $instr->dateDBToForm($valF['archive_date_decision']);
                                    $valF['archive_date_validite']=
                                        $instr->dateDBToForm($valF['archive_date_validite']);
                                    $valF['archive_date_achevement']=
                                        $instr->dateDBToForm($valF['archive_date_achevement']);
                                    $valF['archive_date_chantier']=
                                        $instr->dateDBToForm($valF['archive_date_chantier']);
                                    $valF['archive_date_conformite']=
                                        $instr->dateDBToForm($valF['archive_date_conformite']);
                                    $valF['archive_date_dernier_depot']=
                                        $instr->dateDBToForm($valF['archive_date_dernier_depot']);
                                    $valF['archive_date_limite_incompletude']=
                                        $instr->dateDBToForm($valF['archive_date_limite_incompletude']);
                                    $valF['date_finalisation_courrier']=
                                        $instr->dateDBToForm($valF['date_finalisation_courrier']);
                                    $valF['date_envoi_signature']=
                                        $instr->dateDBToForm($valF['date_envoi_signature']);
                                    $valF['date_retour_signature']=
                                        $instr->dateDBToForm($valF['date_retour_signature']);
                                    $valF['date_envoi_rar']=
                                        $instr->dateDBToForm($valF['date_envoi_rar']);
                                    $valF['date_retour_rar']=
                                        $instr->dateDBToForm($valF['date_retour_rar']);
                                    $valF['date_envoi_controle_legalite']=
                                        $instr->dateDBToForm($valF['date_envoi_controle_legalite']);
                                    $valF['date_retour_controle_legalite']=
                                        $instr->dateDBToForm($valF['date_retour_controle_legalite']);

                                    $valF['date_envoi_rar'] = $date;

                                    // Vérification de la finalisation du document
                                    // correspondant au code barres
                                    if($instr->getVal("om_final_instruction") === 't') {
                                        $instr->setParameter('maj', 1);
                                        $instr->class_actions[1]["identifier"] = 
                                            "envoi lettre RAR (depuis le menu suivi des pièces)";
                                        if ($instr->modifier($valF, $f->db, DEBUG) == true) {
                                            $id4Gen[] = $code_barres;
                                            $nbLettres ++;
                                        } else {
                                            //
                                            if ($error != "") {
                                                $error .= "<br/>";
                                            }
                                            $error .= sprintf(_("Une erreur s'est produite lors de la modification de l'instruction %s."),
                                                $code_barres);
                                            $error .= " ";
                                            $error .= _("Veuillez contacter votre administrateur.");
                                        }
                                    } else {
                                        //
                                        if ($error != "") {
                                            $error .= "<br/>";
                                        }
                                        $error .= sprintf(_("Le document correspondant au 
                                            code barres %s n'est pas finalise, 
                                            le bordereau ne sera pas genere."),
                                            $code_barres);
                                    }
                                    
                                } else {
                                    //
                                    if ($error != "") {
                                        $error .= "<br/>";
                                    }
                                    $error .= _("Une lettre correspondante a l'instruction ayant pour code barres")." ".$code_barres." "._("a deja ete envoyee, le bordereau ne sera pas genere.");
                                }
                            } else {
                                //
                                if ($error != "") {
                                    $error .= "<br/>";
                                }
                                $error .= _("Le numero")." ".$code_barres." "._("ne correspond a aucun code barres d'instruction.");
                            }
                        } else {
                            //
                            if ($error != "") {
                                $error .= "<br/>";
                            }
                            $error .= _("Le code barres d'instruction")." ".$code_barres." "._("n'est pas valide.");
                        }
                    }
                }
            }
        }

        /**
         * Affichage des messages et du formulaire
         */
        // Affichage du message de validation ou d'erreur
        if (isset($message) && isset($message_class) && $message != "") {
            $f->displayMessage($message_class, $message);
        }
        // Affichage du message d'erreur
        if(!empty($error)) {
            $f->displayMessage("error", $error);
        }
        // Affichage du message de validation de la saisie
        if ($nbLettres > 0) {
            //
            $message_class = "valid";
            $message = _("Cliquez sur le lien ci-dessous pour telecharger votre document");
            $message .= " : <br/><br/>";
            $message .= "<a class='om-prev-icon pdf-16'";
            $message .= " title=\""._("imprimer les RAR")."\"";
            $message .= " href=\"../scr/form.php?obj=instruction&action=180&idx=0&liste=".implode(",",$id4Gen)."\"";
            $message .= " target='_blank'>";
            $message .= _("Telecharger le document pour")." ".$nbLettres." "._("RAR");
            $message .= "</a>";
            $f->displayMessage($message_class, $message);
        }
        // Inclusion de la classe de gestion des formulaires
        require_once "../obj/om_formulaire.class.php";
        // Ouverture du formulaire
        echo "\t<form";
        echo " method=\"post\"";
        echo " id=\"suivi_envoi_lettre_rar_form\"";
        echo " action=\"\"";
        echo ">\n";
        // Paramétrage des champs du formulaire
        $champs = array("date", "liste_code_barres_instruction");
        // Création d'un nouvel objet de type formulaire
        $form = new formulaire(NULL, 0, 0, $champs);
        // Paramétrage du champ date du formulaire
        $form->setLib("date", _("Date")."* :");
        $form->setType("date", "date");
        $form->setOnchange("date", "fdate(this)");
        $form->setVal("date", ($date == "" ? date("d/m/Y") : $date));
        $form->setTaille("date", 10);
        $form->setMax("date", 10);
        // Paramétrage du champ liste_code_barres_instruction du formulaire
        $form->setLib("liste_code_barres_instruction", _("Liste des codes barres d'instructions scannes")."* :");
        $form->setType("liste_code_barres_instruction", "textarea");
        $form->setVal("liste_code_barres_instruction", $liste_code_barres_instruction);
        $form->setTaille("liste_code_barres_instruction", 20);
        $form->setMax("liste_code_barres_instruction", 20);
        // Affichage du formulaire
        $form->entete();
        $form->afficher($champs, 0, false, false);
        $form->enpied();
        // Affichage du bouton
        echo "\t<div class=\"formControls\">\n";
        $f->layout->display_form_button(array("value" => _("Valider"), "name" => "validation"));
        echo "\t</div>\n";
        // Fermeture du formulaire
        echo "\t</form>\n";
    }

    /**
     * VIEW - view_suivi_mise_a_jour_des_dates.
     *
     * Vu pour mettre à jour les dates de suivi de l'instruction.
     *
     * @return void
     */
    function view_suivi_mise_a_jour_des_dates() {
        // Vérification de l'accessibilité sur l'élément
        $this->checkAccessibility();

        // XXX APP

        $f = $this->f;

        // Récupération des valeur passées en POST ou GET
        if($f->get_submitted_post_value("type_mise_a_jour") !== null) {
            $type_mise_a_jour = $f->get_submitted_post_value("type_mise_a_jour");
        } elseif($f->get_submitted_get_value('type_mise_a_jour') !== null) {
            $type_mise_a_jour = $f->get_submitted_get_value('type_mise_a_jour');
        } else {
            $type_mise_a_jour = "";
        }
        if($f->get_submitted_post_value('date') !== null) {
            $date = $f->get_submitted_post_value('date');
        } elseif($f->get_submitted_get_value('date') !== null) {
            $date = $f->get_submitted_get_value('date');
        } else {
            $date = "";
        }
        if($f->get_submitted_post_value('code_barres') !== null) {
            $code_barres = $f->get_submitted_post_value('code_barres');
        } elseif($f->get_submitted_get_value('code_barres') !== null) {
            $code_barres = $f->get_submitted_get_value('code_barres');
        } else {
            $code_barres = "";
        }
        // Booléen permettant de définir si un enregistrement à eu lieu
        $correct = false;
        // Booléen permettant de définir si les dates peuvent êtres enregistrées
        $date_error = false;
        // Champs date à mettre à jour
        $liste_champs=array();

        // Si le formulaire a été validé
        if ($f->get_submitted_post_value('validation') !== null) {
            if(!empty($type_mise_a_jour) and !empty($date) and !empty($code_barres)) {

                //Vérification de l'existance de l'instruction
                $sql = "SELECT instruction FROM ".DB_PREFIXE."instruction WHERE code_barres='".$this->f->db->escapesimple($code_barres)."'";
                $res = $f->db->query($sql);
                $f->addToLog(__METHOD__.": db->query(\"".$sql."\")", VERBOSE_MODE);
                $f->isDatabaseError($res);

                if($res->numrows() == 1) {
                    $liste_champs = explode(";", $type_mise_a_jour);
                    // Mise à jour des dates après l'écran de verification
                    if($f->get_submitted_post_value('is_valid') !== null and $f->get_submitted_post_value('is_valid') == "true") {
                        require_once '../obj/instruction.class.php';
                        $row =& $res->fetchRow(DB_FETCHMODE_ASSOC);
                        $instr = new instruction($row['instruction'], $f->db, DEBUG);
                        $valF = array();
                        foreach($instr->champs as $id => $champ) {
                            $valF[$champ] = $instr->val[$id];
                        }
                        $valF['date_evenement']=$instr->dateDBToForm($valF['date_evenement']);
                        $valF['archive_date_complet']=$instr->dateDBToForm($valF['archive_date_complet']);
                        $valF['archive_date_rejet']=$instr->dateDBToForm($valF['archive_date_rejet']);
                        $valF['archive_date_limite']=$instr->dateDBToForm($valF['archive_date_limite']);
                        $valF['archive_date_notification_delai']=$instr->dateDBToForm($valF['archive_date_notification_delai']);
                        $valF['archive_date_decision']=$instr->dateDBToForm($valF['archive_date_decision']);
                        $valF['archive_date_validite']=$instr->dateDBToForm($valF['archive_date_validite']);
                        $valF['archive_date_achevement']=$instr->dateDBToForm($valF['archive_date_achevement']);
                        $valF['archive_date_chantier']=$instr->dateDBToForm($valF['archive_date_chantier']);
                        $valF['archive_date_conformite']=$instr->dateDBToForm($valF['archive_date_conformite']);
                        $valF['archive_date_dernier_depot']=$instr->dateDBToForm($valF['archive_date_dernier_depot']);
                        $valF['archive_date_limite_incompletude']=$instr->dateDBToForm($valF['archive_date_limite_incompletude']);
                        $valF['date_finalisation_courrier']=$instr->dateDBToForm($valF['date_finalisation_courrier']);
                        $valF['date_envoi_signature']=$instr->dateDBToForm($valF['date_envoi_signature']);
                        $valF['date_retour_signature']=$instr->dateDBToForm($valF['date_retour_signature']);
                        $valF['date_envoi_rar']=$instr->dateDBToForm($valF['date_envoi_rar']);
                        $valF['date_retour_rar']=$instr->dateDBToForm($valF['date_retour_rar']);
                        $valF['date_envoi_controle_legalite']=$instr->dateDBToForm($valF['date_envoi_controle_legalite']);
                        $valF['date_retour_controle_legalite']=$instr->dateDBToForm($valF['date_retour_controle_legalite']);

                        foreach(explode(";", $type_mise_a_jour) as $maj_date) {
                            $valF[$maj_date]=$date;
                        }

                        // Vérification de la finalisation du document
                        // correspondant au code barres
                        if($valF["om_final_instruction"] === 't' or
                            $valF["lettretype"] == '') {
                            $code_barres = "";
                            
                            //Désactivation de l'autocommit
                            $f->db->autoCommit(false);
                            
                            //On modifie les valeurs de l'instruction
                            $instr->setParameter('maj', 170);
                            $instr->class_actions[170]["identifier"] = 
                            "mise à jour des dates (depuis le menu suivi des pièces)";
                            $retour = $instr->modifier($valF, $f->db, DEBUG);
                            
                            //Si une erreur s'est produite, on défait les modifications 
                            //qui ont été faites
                            if (!$retour){
                                $instr->undoValidation();
                            }
                            //Sinon, on valide en base de données les modifications
                            else {
                                $f->db->commit();
                            }
                            
                            // Variable correct retourné depuis la classe instruction
                            $correct = $instr->correct;
                            
                            // Si la modification sur l'instruction a échoué
                            if ($correct === false) {
                                
                                // Message d'erreur de la classe instruction
                                $error = $instr->msg;
                            }
                            
                        } else {
                            // Indique que le traitement est en erreur
                            $correct = false;
                            // Message d'erreur
                            $error = sprintf(_("Le document n'est pas finalise."),
                            "<span class='bold'>".$code_barres."</span>");
                        }
                    } else {
                        // Récupération des infos du dossier
                        $sqlInfo = "SELECT dossier.dossier_libelle,
                                            evenement.libelle as evenement,
                                            autorite_competente.code as autorite_competente_code,
                                            autorite_competente.libelle as autorite_competente,
                                            evenement.type as evenement_type,
                                            to_char(date_envoi_signature,'DD/MM/YYYY')  as date_envoi_signature,
                                            to_char(date_retour_signature,'DD/MM/YYYY')  as date_retour_signature,
                                            to_char(date_envoi_controle_legalite,'DD/MM/YYYY')  as date_envoi_controle_legalite,
                                            to_char(date_retour_controle_legalite,'DD/MM/YYYY')  as date_retour_controle_legalite,
                                            to_char(date_envoi_rar,'DD/MM/YYYY')  as date_envoi_rar,
                                            to_char(date_retour_rar,'DD/MM/YYYY')  as date_retour_rar
                                    FROM ".DB_PREFIXE."instruction
                                    INNER JOIN ".DB_PREFIXE."dossier ON
                                        dossier.dossier=instruction.dossier
                                    LEFT JOIN ".DB_PREFIXE."autorite_competente ON
                                        dossier.autorite_competente=autorite_competente.autorite_competente
                                    INNER JOIN ".DB_PREFIXE."evenement ON
                                        instruction.evenement=evenement.evenement
                                    WHERE code_barres='".$code_barres."'";
                        $resInfo = $f->db->query($sqlInfo);
                        $f->isDatabaseError($resInfo);
                        $infos = $resInfo->fetchRow(DB_FETCHMODE_ASSOC);

                        // Vérification de la non modification des dates de suivi
                        foreach(explode(";", $type_mise_a_jour) as $champ) {
                            if($infos[$champ] != "" AND $infos[$champ] != $date) {
                                $error = _("Les dates de suivis ne peuvent etre modifiees");
                                $date_error = true;
                            }
                        }
                    }
                } else {
                    $error = _("Le numero saisi ne correspond a aucun code barres d'instruction.");
                }

            } else {
                $error = _("Tous les champs doivent etre remplis.");
            }
        }

        /**
         * Affichage des messages et du formulaire
         */
        // Affichage du message de validation ou d'erreur
        if (isset($message) && isset($message_class) && $message != "") {
            $f->displayMessage($message_class, $message);
        }
        // Affichage du message d'erreur
        if(!empty($error)) {
            $f->displayMessage("error", $error);
        }

        // Affichage du message de validation de la saisie
        if($correct === true) {
            $f->displayMessage("ok", _("Saisie enregistree"));
        }
        // Inclusion de la classe de gestion des formulaires
        require_once "../obj/om_formulaire.class.php";
        // Ouverture du formulaire
        echo "\t<form";
        echo " method=\"post\"";
        echo " id=\"suivi_mise_a_jour_des_dates_form\"";
        echo " action=\"\"";
        echo ">\n";
        // Paramétrage des champs du formulaire
        if(isset($infos)) {
            $champs = array("type_mise_a_jour", "date", "code_barres", "dossier_libelle", "evenement"
                            , "autorite_competente", "date_envoi_signature",
                            "date_retour_signature", "date_envoi_controle_legalite",
                            "date_retour_controle_legalite", "date_envoi_rar",
                            "date_retour_rar", "is_valid");
        } else {
            $champs = array("type_mise_a_jour", "date", "code_barres");
        }
        // Création d'un nouvel objet de type formulaire
        $form = new formulaire(NULL, 0, 0, $champs);
        // Paramétrage des champs du formulaire
        // Parametrage du champ type_mise_a_jour
        $form->setLib("type_mise_a_jour", _("Date a mettre a jour")."* :");
        if(isset($infos)) {
            $form->setType("type_mise_a_jour", "selecthiddenstatic");

        } else {
            $form->setType("type_mise_a_jour", "select");

        }
        $form->setVal("type_mise_a_jour", $type_mise_a_jour);
        $contenu = array();

        $contenu[0][0] = "date_envoi_signature";
        $contenu[1][0] = _("date d'envoi pour signature Mairie/Prefet");

        $contenu[0][1] = "date_retour_signature";
        $contenu[1][1] = _("date de retour de signature Mairie/Prefet");

        $contenu[0][2] = "date_retour_signature;date_envoi_controle_legalite";
        $contenu[1][2] = _("date de retour de signature + Envoi controle legalite");

        $contenu[0][3] = "date_envoi_controle_legalite";
        $contenu[1][3] = _("date d'envoi au controle de legalite");

        $contenu[0][4] = "date_retour_controle_legalite";
        $contenu[1][4] = _("date de retour de controle de legalite");

        $contenu[0][5] = "date_retour_rar";
        $contenu[1][5] = _("date de retour de l'AR");

        $form->setSelect("type_mise_a_jour", $contenu);

        // Parametrage du champ date
        $form->setLib("date", _("Date")."* :");
        if(isset($infos)) {
            $form->setType("date", "hiddenstaticdate");

        } else {
            $form->setType("date", "date");
        }
        $form->setVal("date", $date);
        $form->setTaille("date", 10);
        $form->setMax("date", 10);

        // Parametrage du champ code_barres
        $form->setLib("code_barres", _("Code barres d'instruction")."* :");
        if(isset($infos)) {
            $form->setType("code_barres", "hiddenstatic");
        } else {
            $form->setType("code_barres", "text");
        }
        $form->setVal("code_barres", $code_barres);
        $form->setTaille("code_barres", 20);
        $form->setMax("code_barres", 20);

        // Ajout des infos du dossier correspondantes à l'instruction séléctionnée
        if(isset($infos)) {

            // Tous les champs sont défini par defaut à static
            foreach ($infos as $key => $value) {
                $form->setType($key, "static");
                if(in_array($key, $liste_champs)) {
                    $form->setVal($key, $date);
                } else {
                    $form->setVal($key, $value);
                }
            }

            // Les champs dont on viens de définir la valeur sont en gras
            foreach ($liste_champs as $value) {
                $form->setBloc($value,'DF',"",'bold');
            }

            // Parametrage du champ dossier
            $form->setLib("dossier_libelle", _("dossier_libelle")." :");
            $form->setType("dossier_libelle", "static");
            $form->setVal("dossier_libelle", $infos['dossier_libelle']);

            // Parametrage du champ evenement
            $form->setLib("evenement", _("evenement")." :");
            $form->setType("evenement", "static");
            $form->setVal("evenement", $infos['evenement']);

            // Parametrage du champ autorite_competente
            $form->setLib("autorite_competente", _("Autorite competente")." :");
            $form->setType("autorite_competente", "static");
            $form->setVal("autorite_competente", $infos['autorite_competente']);

            // Parametrage des libellés d'envoi avec RAR
            $form->setLib("date_envoi_rar", _("date_envoi_rar")." :");
            $form->setLib("date_retour_rar", _("date_retour_rar")." :");

            $form->setLib("date_envoi_signature", _("date_envoi_signature")." :");
            $form->setLib("date_retour_signature", _("date_retour_signature")." :");
            $form->setLib("date_envoi_controle_legalite", _("date_envoi_controle_legalite")." :");
            $form->setLib("date_retour_controle_legalite", _("date_retour_controle_legalite")." :");
            // Configuration des libellé en fonction de l'autorité compétente
            if($infos['autorite_competente_code'] == 'ETAT') {
                $form->setType("date_envoi_controle_legalite", "hiddendate");
                $form->setType("date_retour_controle_legalite", "hiddendate");
            }

            // Ajout d'un champ hidden permettant de savoir que le formulaire précédant est celui de vérification
            $form->setLib("is_valid", _("Valide")." :");
            $form->setType("is_valid", "hidden");
            $form->setVal("is_valid", 'true');

            $form->setFieldset('dossier_libelle','D',_('Synthese'));
            $form->setFieldset('is_valid','F');
            
        }


        // Création du fieldset regroupant les champs permettant la mise à jour des date
        $form->setFieldset('type_mise_a_jour','D',_('Mise a jour'));
        $form->setFieldset('code_barres','F');
        // Affichage du formulaire
        $form->entete();
        $form->afficher($champs, 0, false, false);
        $form->enpied();
        // Affichage du bouton
        echo "\t<div class=\"formControls\">\n";
        //
        if(!$date_error) {
            $f->layout->display_form_button(array("value" => _("Valider"), "name" => "validation"));
        }
        // Si pas sur l'écran de validation
        if(isset($infos)) {
            echo "<a class=\"retour\" href=\"../scr/form.php?obj=instruction_suivi_mise_a_jour_des_dates&action=170&idx=0";
                echo "&amp;type_mise_a_jour=".$type_mise_a_jour."&amp;date=".$date."&amp;code_barres=".$code_barres;
            echo "\">Retour</a>";
        }
        echo "\t</div>\n";
        // Fermeture du formulaire
        echo "\t</form>\n";
    }

    /**
     * [view_pdf_lettre_rar description]
     *
     * @return [type] [description]
     */
    function view_pdf_lettre_rar() {
        // Vérification de l'accessibilité sur l'élément
        $this->checkAccessibility();

        // XXX APP

        $f = $this->f;

        $f->disableLog();

        if($f->get_submitted_get_value('liste') != null) {
            $listeCodeBarres = explode(',',$f->get_submitted_get_value('liste'));

            // Classe permettant la mise en page de l'édition pdf
            require_once "../obj/pdf_lettre_rar.class.php";
            $pdf_lettre_rar = new pdf_lettre_rar('P', 'mm', 'A4');
            // Initialisation de la mise en page
            $pdf_lettre_rar->init($f);

            foreach ($listeCodeBarres as $code_barres) {

                // Test si l'evenement est de type arrete et si un délégataire a été nommé
                $sql = "SELECT 
                            dossier.dossier_libelle,
                            evenement.type,
                            count(lien_dossier_demandeur) as nbdemandeur,
                            CASE
                                WHEN division.libelle IS NOT NULL AND phase.code IS NOT NULL
                                    THEN CONCAT(phase.code, ' - ', division.libelle)
                                ELSE
                                    phase.code
                            END AS code_phase
                        FROM ".DB_PREFIXE."instruction
                        LEFT JOIN ".DB_PREFIXE."dossier
                            ON instruction.dossier = dossier.dossier
                        LEFT JOIN ".DB_PREFIXE."division
                            ON dossier.division = division.division
                        INNER JOIN ".DB_PREFIXE."evenement ON
                            instruction.evenement=evenement.evenement
                        LEFT JOIN ".DB_PREFIXE."phase
                            ON evenement.phase = phase.phase
                        inner JOIN ".DB_PREFIXE."lien_dossier_demandeur ON
                            instruction.dossier=lien_dossier_demandeur.dossier
                        inner join ".DB_PREFIXE."demandeur on
                            demandeur.demandeur=lien_dossier_demandeur.demandeur
                        WHERE code_barres='".$code_barres."'
                            AND ((lien_dossier_demandeur.petitionnaire_principal IS TRUE AND demandeur.type_demandeur='petitionnaire')
                            OR demandeur.type_demandeur='delegataire')
                        GROUP BY dossier.dossier_libelle, evenement.type, phase.code, division.libelle";

                $res = $f->db->query($sql);
                $f->addToLog(__METHOD__.": db->query(\"".$sql."\")", VERBOSE_MODE);
                $f->isDatabaseError($res);
                $testDemandeur = $res->fetchrow(DB_FETCHMODE_ASSOC);
                

                // Recuperation de l'adresse de destination
                $sqlAdresse = "SELECT 
                    CASE WHEN demandeur.qualite='particulier'
                        THEN TRIM(CONCAT_WS(' ', pc.libelle, demandeur.particulier_nom, demandeur.particulier_prenom))
                        ELSE TRIM(demandeur.personne_morale_denomination)
                    END  as ligne1,
                    CASE WHEN demandeur.qualite='personne_morale'
                        THEN TRIM(demandeur.personne_morale_raison_sociale)
                        ELSE ''
                    END as ligne1_1,
                    CASE WHEN demandeur.qualite='personne_morale' AND (demandeur.personne_morale_nom IS NOT NULL OR demandeur.personne_morale_prenom IS NOT NULL)
                        THEN TRIM(CONCAT_WS(' ', 'rep. par', demandeur.personne_morale_nom, demandeur.personne_morale_prenom))
                        ELSE ''
                    END as ligne1_2,
                    trim(concat(demandeur.numero,' ',demandeur.voie)) as ligne2,
                    CASE demandeur.complement
                    WHEN null THEN ''
                    ELSE trim(demandeur.complement)
                    END as ligne3,
                    CASE demandeur.lieu_dit
                    WHEN null THEN ''
                    ELSE trim(demandeur.lieu_dit)
                    END as ligne4,
                    CONCAT_WS(' ', demandeur.code_postal, demandeur.localite, 
                        (CASE WHEN demandeur.bp IS NOT NULL 
                            THEN CONCAT_WS(' ', 'BP', demandeur.bp)
                            ELSE ''
                        END), 
                        (CASE WHEN demandeur.cedex IS NOT NULL 
                            THEN CONCAT_WS(' ', 'CEDEX', demandeur.cedex)
                            ELSE ''
                        END))
                    as ligne5,
                    code_barres as code_barres
                FROM ".DB_PREFIXE."instruction
                INNER JOIN ".DB_PREFIXE."dossier ON dossier.dossier = instruction.dossier
                INNER JOIN ".DB_PREFIXE."lien_dossier_demandeur ON dossier.dossier = lien_dossier_demandeur.dossier
                INNER JOIN ".DB_PREFIXE."demandeur ON lien_dossier_demandeur.demandeur = demandeur.demandeur
                LEFT OUTER JOIN ".DB_PREFIXE."civilite as pc ON demandeur.particulier_civilite = pc.civilite OR demandeur.personne_morale_civilite = pc.civilite
                WHERE instruction.code_barres ='".$code_barres."'";

                // Envoi pour delegataire ou petitionnaire principal selon le type d'evenement
                if($testDemandeur['type'] != 'arrete' AND $testDemandeur['nbdemandeur'] > 1) {
                    $sqlAdresse .= " AND demandeur.type_demandeur='delegataire'";
                } else {
                    $sqlAdresse .= " AND lien_dossier_demandeur.petitionnaire_principal IS TRUE AND demandeur.type_demandeur='petitionnaire'";
                }

                $resAdresse = $f->db->query($sqlAdresse);
                $adresse_dest = $resAdresse->fetchrow(DB_FETCHMODE_ASSOC);
                $f->addToLog(__METHOD__.": db->query(\"".$sqlAdresse."\")", VERBOSE_MODE);
                $f->isDatabaseError($resAdresse);

                // Création adresse destinataire sans ligne vide
                $adresse_destinataire = array();
                if (!empty($adresse_dest['ligne1'])) {
                    $adresse_destinataire[] = $adresse_dest['ligne1'];
                }
                if (!empty($adresse_dest['ligne1_1'])) {
                    $adresse_destinataire[] = $adresse_dest['ligne1_1'];
                }
                if (!empty($adresse_dest['ligne1_2'])) {
                    $adresse_destinataire[] = $adresse_dest['ligne1_2'];
                }
                $adresse_destinataire[] = $adresse_dest['ligne2'];
                if (!empty($adresse_dest['ligne3'])) {
                    $adresse_destinataire[] = $adresse_dest['ligne3'];
                }
                if (!empty($adresse_dest['ligne4'])) {
                    $adresse_destinataire[] = $adresse_dest['ligne4'];
                }        
                $adresse_destinataire[] = $adresse_dest['ligne5'];

                // Création du champ specifique
                $specifique_content = array();
                $specifique_content[] = $adresse_dest['ligne1'];
                $specifique_content[] = $adresse_dest['ligne1_1'];
                $specifique_content[] = $adresse_dest['ligne1_2'];
                $specifique_content[] = $testDemandeur['dossier_libelle'];
                $specifique_content[] = "|||||".$adresse_dest['code_barres']."|||||";
                unset($adresse_dest['code_barres']);

                // Ajout d'une page aux pdf
                $pdf_lettre_rar->addLetter($adresse_destinataire, $specifique_content, $testDemandeur['code_phase']);

            }
            $pdf_output = $pdf_lettre_rar->output("lettre_rar".date("dmYHis").".pdf","S");
            require_once PATH_OPENMAIRIE."om_edition.class.php";
            $om_edition = new edition();
            $om_edition->expose_pdf_output($pdf_output, "lettre_rar".date("dmYHis").".pdf");
        }
    }

    /**
     * VIEW - view_bordereau_envoi_maire.
     *
     * Formulaire demandant :
     * - le code-barres de l'événement d'instruction
     * - la date d'envoi du courrier pour signature par le maire
     * 
     * Lors de la validation :
     *   => met à jour cette date dans l'événement d'instruction
     *   => crée un lien permettant de générer en PDF le bordereau
     *
     * @return void
     */
    function view_bordereau_envoi_maire() {
        // Vérification de l'accessibilité sur l'élément
        $this->checkAccessibility();

        // Récupération des valeur passées en POST ou GET
        $code_barres = "";
        if($this->f->get_submitted_post_value('code_barres') !== null) {
            $code_barres = $this->f->get_submitted_post_value('code_barres');
        } elseif($this->f->get_submitted_get_value('code_barres')!==null) {
            $code_barres = $this->f->get_submitted_get_value('code_barres');
        }
        $date = "";
        if($this->f->get_submitted_post_value('date') !== null) {
            $date = $this->f->get_submitted_post_value('date');
        } elseif($this->f->get_submitted_get_value('date') !== null) {
            $date = $this->f->get_submitted_get_value('date');
        }
        $validation = 0;
        if($this->f->get_submitted_post_value('validation') !== null) {
            $validation = $this->f->get_submitted_post_value('validation');
        } elseif($this->f->get_submitted_get_value('validation') !== null) {
            $validation = $this->f->get_submitted_get_value('validation');
        }

        // Si le formulaire a été validé
        if ($this->f->get_submitted_post_value('validation') !== null) {
            // Tous les champs doivent obligatoirement être remplis
            if (!empty($date) && !empty($code_barres)) {
                $date_en = $this->dateDB($date);
                // Si date valide
                if ($date_en != "") {
                    $id_instruction = $this->get_instruction_by_barcode($code_barres);
                    // Si un événement d'instruction a été trouvé pour ce code-barres
                    if ($id_instruction !== null) {
                        $ret = $this->update_date_envoi_signature($id_instruction, $date_en);
                        // Si mise à jour réussie de la date d'envoi du courrier
                        // pour signature par l'autorité compétente 
                        if($ret === true) {
                            // Message de validation avec lien PDF
                            $message_class = "valid";
                            $message = '&bullet; '._("Veuillez cliquer sur le lien ci-dessous pour telecharger votre bordereau");
                            $message .= " : <br/><br/>";
                            $message .= "<a class='om-prev-icon pdf-16'";
                            $message .= " id=\"generer_bordereau_envoi_maire\"";
                            $message .= " title=\""._("Bordereau")."\"";
                            $message .= " href='../scr/form.php?obj=instruction";
                            $message .= "&action=200";
                            $message .= "&idx=".$id_instruction."'";
                            $message .= " target='_blank'>";
                            $message .= _("Bordereau d'envoi au maire");
                            $message .= "</a><br/><br/>";
                            $message .= '&bullet; '._("Rappel des informations saisies")." :<br/><br/>";
                            $message .= _("Code du courrier")." : ".$code_barres."<br/>";
                            $message .= _("Date d'envoi du courrier pour signature par le maire")." : ".$date;
                            
                        } else {
                            // Message d'erreur
                            $message_class = "error";
                            $message = sprintf(_("Erreur lors de la mise a jour de l'evenement d'instruction correspondant au code barres %s."),
                                $code_barres);
                        }
                    }
                    else {
                        $message_class = "error";
                        $message = _("Le numero saisi ne correspond a aucun code-barres d'evenement d'instruction.");
                    }
                }
                else {
                    $message_class = "error";
                    $message = _("La date est invalide.");
                }
            } else {
                $message_class = "error";
                $message = _("Tous les champs doivent etre remplis.");
            }
        }

        /**
         * Affichage des messages et du formulaire
         */

        // Affichage du message de validation ou d'erreur
        if (isset($message) && isset($message_class) && $message != "") {
            $this->f->displayMessage($message_class, $message);
        }

        // Inclusion de la classe de gestion des formulaires
        require_once "../obj/om_formulaire.class.php";
        // Ouverture du formulaire
        $datasubmit = $this->getDataSubmit();
        echo "\n<!-- ########## START DBFORM ########## -->\n";
        echo "<form";
        echo " id=\"bordereau_envoi_maire\"";
        echo " method=\"post\"";
        echo " name=\"f1\"";
        echo " action=\"";
        echo $datasubmit;
        echo "\"";
        echo ">\n";

        // Paramétrage des champs du formulaire
        $champs = array("code_barres","date");

        // Création d'un nouvel objet de type formulaire
        $form = new formulaire(NULL, 0, 0, $champs);

        $template_required_label = '%s *';
        // Parametrage du champ code_barres
        $form->setLib("code_barres", sprintf($template_required_label,_("Code du courrier")));
        $form->setType("code_barres", "text");
        $form->setVal("code_barres", $code_barres);
        $form->setTaille("code_barres", 20);
        $form->setMax("code_barres", 20);
        // Parametrage du champ date
        $form->setLib("date", sprintf($template_required_label,_("Date d'envoi du courrier pour signature par le maire")));
        $form->setType("date", "date") ;
        if (empty($date)) {
            $date = date('d/m/Y');
        }
        $form->setVal("date", $date);
        $form->setTaille("date", 10);
        $form->setMax("date", 10);

        // Création du bloc regroupant les champs
        $form->setBloc('code_barres','D');
        $form->setBloc('date','F');
        // Affichage du formulaire
        $form->entete();
        $form->afficher($champs, 0, false, false);
        $form->enpied();
        // Affichage du bouton
        printf("\t<div class=\"formControls\">\n");
        //
        $this->f->layout->display_form_button(array("value" => _("Valider"), "name" => "validation"));
        printf("\t</div>\n");
        // Fermeture du formulaire
        printf("\t</form>\n");
    }

    /**
     * VIEW - view_bordereau_envoi_maire.
     * 
     * PDF de bordereau d'envoi au maire pour l'événement d'instruction instancié
     * 
     * @return [void]
     */
    function view_generate_bordereau_envoi_maire() {
        // Vérification de l'accessibilité sur l'élément
        $this->checkAccessibility();
        // Récupération de la collectivité du dossier d'instruction
        $collectivite_di = $this->get_dossier_instruction_om_collectivite();
        // Récupération de ses paramètres
        $collectivite = $this->f->getCollectivite($collectivite_di);
        // Génération du PDF
        $result = $this->compute_pdf_output('etat', 'communaute_bordereau_envoi_maire', $collectivite, $this->getVal(($this->clePrimaire)));
        // Affichage du PDF
        $this->expose_pdf_output(
            $result['pdf_output'], 
            $result['filename']
        );
    }

    /**
     * Retourne l'événement d'instruction dont on donne le code-barres
     * 
     * @param   [string]  $barcode  numéro du code-barres
     * @return  [mixed]             ID de son instruction ou null si aucun code
     */
    function get_instruction_by_barcode($barcode) {
        // Begin
        $this->begin_treatment(__METHOD__);
        // Vérification de l'existence de l'événement d'instruction
        // pour le code-barres donné
        $sql = "SELECT instruction 
            FROM ".DB_PREFIXE."instruction
            WHERE code_barres = '".$this->f->db->escapesimple($barcode)."'";
        $res = $this->f->db->getOne($sql);
        $this->f->addToLog(__METHOD__." : db->getOne(\"".$sql."\")", VERBOSE_MODE);
        $this->f->isDatabaseError($res);
        // Retourne résultat
        return $this->end_treatment(__METHOD__, $res);
    }

    /**
     * Met à jour le champ date d'envoi signature
     * avec la date fournie et pour l'instruction donnée
     * 
     * @param   [string]   $id    ID de l'événement d'instruction
     * @param   [string]   $date  date au format EN
     * @return  [boolean]         true si mise à jour avec succès
     */
    function update_date_envoi_signature($id, $date) {
        // Préparation du tableau
        $valF = array();
        $valF['date_envoi_signature'] = $date;
        // Begin
        $this->begin_treatment(__METHOD__);
        // Requête
        $res = $this->db->autoExecute(
            DB_PREFIXE.$this->table,
            $valF,
            DB_AUTOQUERY_UPDATE,
            $this->getCle($id)
        );
        // S'il y a eu une erreur
        if (database::isError($res, true)) {
            $this->end_treatment(__METHOD__, false);
        }
        //
        return $this->end_treatment(__METHOD__, true);
    }

    /**
     * Méthode permettant de définir des valeurs à envoyer en base après
     * validation du formulaire d'ajout.
     * @param array $val tableau des valeurs retournées par le formulaire
     */
    function setValFAjout($val) {
        // Mise à jour du flag created_by_commune lors d'un changement de décision
        // par un utilisateur de commune sur un dossier instruit par la comcom
        if($this->f->isInstrCanChangeDecision($this->valF["dossier"])) {
            $this->valF['created_by_commune'] = true;
        }
    }

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


    /**
     * Logue l'action de l'instruction dans son DI.
     *
     * @param string $id  Clé primaire de l'instruction.
     * @param array  $val Valeurs de l'instruction.
     *
     * @return bool Vrai si traitement effectué avec succès
     */
    private function add_log_to_dossier($id, array $val) {
        $maj = $this->getParameter("maj");
        // Action = Trace par défaut
        $action = $this->get_backtrace();
        // Action = Identifant de l'action si contexte connu
        if (empty($maj) === false
            || (empty($maj) === true && $maj === 0)) {
            $action = $this->get_action_param($maj, 'identifier');
            if ($action === 'modifier_suivi') {
                $action = "modifier (via l'action suivi des dates)";
            }
            if ($action === 'notifier_commune'
                && isset($val['mails_destinataires']) === true) {
                $action = "notification de la commune (courriels : ";
                $action .= $val['mails_destinataires'].")";
            }
        }
        // Création du log
        $log = array(
            'date' => date('Y-m-d H:i:s'),
            'user' => $_SESSION['login'],
            'action' => $action,
            'values' => array(
                'date_evenement' => $this->dateDB($val['date_evenement']),
                'date_retour_rar' => $this->dateDB($val['date_retour_rar']),
                'date_retour_signature' => $this->dateDB($val['date_retour_signature']),
                'evenement' => $val['evenement'],
                'action' => $val['action'],
                'instruction' => $id,
                'etat' => $val['etat'],
                ),
        );
        // Ajout du log
        $di = $this->get_inst_dossier($val['dossier']);
        $ret = $di->add_log_instructions($log);
        if ($ret === false) {
            $this->correct = false;
            $this->msg = '';
            $this->addToMessage($di->msg);
        }
        return $ret;
    }


    /**
     * Retourne le contexte de déboguage formaté en HTML.
     * 
     * @return string Une ligne par trace
     */
    private function get_backtrace() {
        $trace = debug_backtrace();
        $backtrace = '';
        $i = 1;
        foreach ($trace as $key => $value) {
            $func = $trace[$key]['function'];
            // On ne s'autolog pas
            if ($func === 'get_backtrace'
                || $func === 'add_log_to_dossier') {
                continue;
            }
            $backtrace .= $i.') ';
            // Si dans une classe
            if (isset($trace[$key]['class']) === true
                && empty($trace[$key]['class']) === false) {
                $backtrace .= $trace[$key]['class'].'->'.$func;
            }
            // Si procédural
            else {
                $file = $trace[$key]['file'];
                $line = $trace[$key]['line'];
                $truncated_file = $this->f->get_relative_path($file);
                if ($truncated_file !== false) {
                    $file = $truncated_file;
                }
                $backtrace .= $func.' IN<br/>&nbsp;&nbsp;&nbsp;&nbsp; '.$file.':'.$line;
            }
            $backtrace .= '<br/>';
            $i++;
        }
        return $backtrace;
    }

    /**
     * CONDITION - is_notifiable.
     *
     * Condition pour afficher l'action notifier_commune.
     *
     * @return boolean
     */
    public function is_notifiable() {
        // L'instruction doit être finalisée, ce qui revient à dire
        // définalisable sans bypass
        if ($this->is_unfinalizable_without_bypass() === false) {
            return false;
        }
        // La collectivité de l'utilisateur doit être de niveau multi
        if ($this->f->has_collectivite_multi() === false) {
            return false;
        }
        // Le paramètre multi de l'objet du courriel doit exister
        if ($this->f->getParameter('param_courriel_de_notification_commune_objet_depuis_instruction') === NULL) {
            return false;
        }
        // Le paramètre multi du modèle du courriel doit exister
        if ($this->f->getParameter('param_courriel_de_notification_commune_modele_depuis_instruction') === NULL) {
            return false;
        }
        // A ce stade toutes les conditions sont satisfaites
        return true;
    }

    /**
     * TREATMENT - notifier_commune.
     *
     * Notifie aux communes et par courriel la finalisation d'une instruction.
     *
     * @return boolean
     */
    public function notifier_commune() {
        // Cette méthode permet d'exécuter une routine en début des méthodes
        // dites de TREATMENT.
        $this->begin_treatment(__METHOD__);
        // Définition des paramètres
        $p_objet = 'param_courriel_de_notification_commune_objet_depuis_instruction';
        $p_modele = 'param_courriel_de_notification_commune_modele_depuis_instruction';
        $p_courriel = 'param_courriel_de_notification_commune';
        // Définition des variables de substitution
        $id_di = $this->getVal('dossier');
        $id_inst = $this->getVal($this->clePrimaire);
        // Instanciation du DI
        $di = $this->get_inst_dossier($id_di);
        // Récupération du paramétrage de la collectivité du dossier
        $collectivite_di = $di->getVal('om_collectivite');
        $params_mono = $this->f->getCollectivite($collectivite_di);
        // Récupération du paramétrage de la collectivité multi
        $collectivite_multi = $this->f->get_idx_collectivite_multi();
        $params_multi = $this->f->getCollectivite($collectivite_multi);
        // Vérification de l'objet (obligatoirement multi)
        $objet = null;
        if (isset($params_multi[$p_objet]) === true
            && $params_multi[$p_objet] !== '') {
            $objet = $params_multi[$p_objet];
        }
        // Vérification du modèle mono en priorité
        $modele = null;
        if (isset($params_mono[$p_modele]) === true
            && $params_mono[$p_modele] !== '') {
            $modele = $params_mono[$p_modele];
            
        }
        // Sinon vérification du modèle multi
        if ($modele === null
            && isset($params_multi[$p_modele]) === true
            && $params_multi[$p_modele] !== '') {
            $modele = $params_multi[$p_modele];
        }
        // Vérification des adresses de courriel mono
        $courriels_valides = array();
        $courriels_invalides = array();
        if (isset($params_mono[$p_courriel]) === true
            && $params_mono[$p_courriel] !== '') {
            // Un mail par ligne
            $adresses = explode("\n", $params_mono[$p_courriel]);
            // Vérification de la validité de chaque mail avec preg_match
            foreach ($adresses as $adresse) {
                $adresse = trim($adresse);
                if ($this->f->checkValidEmailAddress($adresse) === 1) {
                    $courriels_valides[] = $adresse;
                } else {
                    $courriels_invalides[] = $adresse;
                }
            }
        }
        // Vérification du paramétrage global :
        // on stoppe le traitement si au moins un paramètre est incorrect
        if ($objet === null
            || $modele === null 
            || count($courriels_valides) === 0
            || count($courriels_invalides) > 0) {
            // On construit le message d'erreur adéquat
            $this->addToMessage(_('Erreur de paramétrage :'));
            if ($objet === null) {
                $this->addToMessage(_("* l'objet du courriel envoyé aux communes est vide"));
            }
            if ($modele === null) {
                $this->addToMessage(_("* le modèle du courriel envoyé aux communes est vide"));
            }
            if (count($courriels_valides) === 0) {
                $this->addToMessage(_("* aucun courriel valide de destinataire de la commune"));
            }
            if (count($courriels_invalides) > 0) {
                $courriels_invalides = implode(', ', $courriels_invalides);
                $this->addToMessage(_("* un ou plusieurs courriels des destinataires de la commune sont invalides : ").$courriels_invalides);
            }
            $this->addToMessage(_("Veuillez contacter votre administrateur."));
            return $this->end_treatment(__METHOD__, false);
        }
        // Remplacement des variables de substitution
        $objet = str_replace('<DOSSIER_INSTRUCTION>', $id_di, $objet);
        $modele = $this->formater_modele($modele, $id_di, $id_inst);
        // Exécution du traitement d'envoi du/des mail(s)
        $fails = array();
        foreach ($courriels_valides as $email) {
            if ($this->f->sendMail(
                iconv("UTF-8", "CP1252", $objet),
                iconv("UTF-8", "CP1252", $modele),
                iconv("UTF-8", "CP1252", $email)) === false) {
                $fails[] = $email;
            }
        }
        // Si échec message d'erreur et arrêt du traitement
        if (count($fails) > 0) {
            $fails = implode(', ', $fails);
            $this->addToMessage(_("Erreur lors de l'envoi du courriel aux destinataires : ").$fails);
            $this->addToMessage(_("Veuillez contacter votre administrateur."));
            return $this->end_treatment(__METHOD__, false);
        }
        // Ajout du log
        $this->setValFFromVal();
        $val_inst = $this->valF;
        $val_inst['mails_destinataires'] = implode(', ', $courriels_valides);
        if ($this->add_log_to_dossier($id_inst, $val_inst) === false) {
            $this->addToMessage(_("Erreur lors de la notification."));
            $this->addToMessage(_("Veuillez contacter votre administrateur."));
            return $this->end_treatment(__METHOD__, false);
        }
        // Message de validation
        $this->addToMessage(_('La commune a été notifiée.'));
        return $this->end_treatment(__METHOD__, true);
    }

    /**
     * Formatte le corps du courriel notifié aux communes
     * 
     * @param   string  $modele   template du modèle du courriel
     * @param   string  $id_di    clé primaire du DI
     * @param   string  $id_inst  clé primaire de l'instruction
     * @return  string            corps du mail au format HTML
     */
    public function formater_modele($modele, $id_di, $id_inst) {
        // Création du lien d'accès direct à l'instruction
        $url_inst = PATH_BASE_URL.'spg/direct_link.php?obj=dossier_instruction&action=3'.
            '&direct_field=dossier&direct_form=instruction&direct_action=3&direct_idx='.$id_inst;
        $url_inst = '<a href="'.$url_inst.'">'.$url_inst.'</a>';
        // Remplacement des champs de fusion
        $modele = str_replace('<DOSSIER_INSTRUCTION>', $id_di, $modele);
        $modele = str_replace('<URL_INSTRUCTION>', $url_inst, $modele);
        $modele = str_replace('<ID_INSTRUCTION>', $id_inst, $modele);
        // Encodage HTML des sauts de ligne
        $modele = preg_replace("/\r\n|\r|\n/",'<br/>',$modele);
        //
        return $modele;
    }
}// fin classe

?>
