<?php
//$Id$ 
//gen openMairie le 10/02/2011 20:39

require_once ("../gen/obj/dossier.class.php");
require_once("../services/outgoing/messageenqueuer.php");

class dossier extends dossier_gen {

    var $maj;
    var $sig;
    // XXX SERVITUDE
    var $servitude="";
    var $auto_pos;
    var $auto_servitude_surfacique;
    var $auto_servitude_ligne;
    var $auto_servitude_point;
    var $auto_parcelle;
    var $auto_parcelle_lot;
    var $aff_depot = "collapsible";
    var $aff_travaux = "collapsible";
    var $aff_instruction = "collapsible";
    var $aff_demandeur = "startClosed";
    var $aff_delegataire = "startClosed";
    var $aff_terrain = "startClosed";
    var $aff_localisation = "collapsible";
    var $aff_description = "startClosed";
    var $aff_amenagement = "startClosed";
    var $dossier_instruction_type;
    var $is_incomplet_notifie = null;
    var $valIdDemandeur = array("petitionnaire_principal" => "",
                                "delegataire" => "",
                                "petitionnaire" => array());
    var $postedIdDemandeur = array("petitionnaire_principal" => "",
                                "delegataire" => "",
                                "petitionnaire" => array());

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

    function dossier($id,&$db,$DEBUG) {
        //On active les nouvelles actions
        $this->activate_class_action = true;
        $this->constructeur($id,$db,$DEBUG);
    } // fin constructeur
    
    /*Mutateur pour ma variable dossier_instruction_type*/
    public function getDossierInstructionType(){
        return $this->dossier_instruction_type;
    }
    public function setDossierInstructionType($dossier_instruction_type){
        $this->dossier_instruction_type = $dossier_instruction_type;
    }

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

        // ACTION - 004 - contrainte
        //
        $this->class_actions[4] = array(
            "identifier" => "contrainte",
            "view" => "view_contrainte",
            "permission_suffix" => "contrainte_tab",
        );

        // ACTION - 005 - view_document_numerise
        // Interface spécifique du tableau des pièces
        $this->class_actions[5] = array(
            "identifier" => "view_document_numerise",
            "view" => "view_document_numerise",
            "permission_suffix" => "document_numerise",
        );
    }

    /**
     * VIEW - view_document_numerise.
     *
     * Vue du tableau des pièces du dossier d'autorisation.
     *
     * Cette vue permet de gérer le contenu de l'onglet "Pièce(s)" sur un 
     * dossier d'autorisation. Cette vue spécifique est nécessaire car
     * l'ergonomie standard du framework ne prend pas en charge ce cas.
     * C'est ici la vue spécifique des pièces liées au dossier qui est
     * affichée directement au clic de l'onglet au lieu du soustab.
     * 
     * L'idée est donc de simuler l'ergonomie standard en créant un container 
     * et d'appeler la méthode javascript 'ajaxit' pour charger le contenu 
     * de la vue visualisation de l'objet lié.
     * 
     * @return void
     */
    function view_document_numerise() {
        // Vérification de l'accessibilité sur l'élément
        $this->checkAccessibility();
        // Récupération des variables GET
        ($this->f->get_submitted_get_value('idxformulaire')!==null ? $idxformulaire = 
            $this->f->get_submitted_get_value('idxformulaire') : $idxformulaire = "");
        ($this->f->get_submitted_get_value('retourformulaire')!==null ? $retourformulaire = 
            $this->f->get_submitted_get_value('retourformulaire') : $retourformulaire = "");
        // Objet à charger
        $obj = "document_numerise";
        // Construction de l'url de sousformulaire à appeler
        $url = "../scr/sousform.php?obj=".$obj;
        $url .= "&idx=".$idxformulaire;
        $url .= "&action=4";
        $url .= "&retourformulaire=".$retourformulaire;
        $url .= "&idxformulaire=".$idxformulaire;
        $url .= "&retour=form";
        // Affichage du container permettant le reffraichissement du contenu
        // dans le cas des action-direct.
        printf('
            <div id="sousform-href" data-href="%s">
            </div>',
            $url
        );
        // Affichage du container permettant de charger le retour de la requête
        // ajax récupérant le sous formulaire.
        printf('
            <div id="sousform-%s">
            </div>
            <script>
            ajaxIt(\'%s\', \'%s\');
            </script>',
            $obj,
            $obj,
            $url
        );
    }

    /**
     * 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;

    }

    // }}}
    /*
     * Ajoute un numéro au dossier
     * 
     */
    function setValFAjout($val = array()) {
        
        //Récupération de la lettre associé au type de dossier d'instruction
        $code = $this->getCode($this->getDossierInstructionType());
        
        //Récupération de la valeur du suffixe ce dossier_instruction_type
        $suffixe = $this->getSuffixe($this->getDossierInstructionType());
        
        //S'il est à TRUE, on récupère le numéro de version du dossier d'autorisation
        $numeroVersion = "";
        $numeroVersionDIT = "";
        if ( $suffixe == 't' ){
            
            //Récupération du numéro de version
            $numeroVersion = $this->getNumeroVersion($val['dossier_autorisation']);
            
            //Incrémentation du numéro de version
            if ( is_numeric($numeroVersion) or $numeroVersion == -1 ){
                
                $this->incrementNumeroVersion($val['dossier_autorisation'], ++$numeroVersion);
            }
            //Récupération du numéro de version en fonction du type de dossier d'instruction
            //Si c'est un modificatif ou un transfert, on utilise un numéro du type 
            // 01 ou 02, etc. sinon on utilise le numéro de version comme auparavant
            $numeroVersionDossierInstructionType = $this->getNumeroVersionDossierInstructionType($val['dossier_autorisation'], $val['dossier_instruction_type'], $numeroVersion);
        }
        
        //Création du numéro de dossier
        $this->valF['dossier'] = $val['dossier_autorisation'].$code.$numeroVersionDossierInstructionType;
        $this->valF['version'] = $numeroVersion;

        // Identifiant du dossier d'instruction lisible
        // Ex : DP 013055 13 00002P0 
        $this->valF['dossier_libelle'] = $this->get_dossier_autorisation_libelle($val['dossier_autorisation']).$code.$numeroVersionDossierInstructionType;
    }

    /*Récupère la valeur du suffixe d'un dossier_instruction_type*/
    function getSuffixe($dossierInstructionType){
        
        $suffixe = "";
        
        $sql = "SELECT 
                    suffixe
                FROM 
                    ".DB_PREFIXE."dossier_instruction_type 
                WHERE 
                    dossier_instruction_type = $dossierInstructionType";
                    
        $this->addToLog("getSuffixe(): db->query(\"".$sql."\")", VERBOSE_MODE);
        $res = $this->db->query($sql);
        if (database :: isError($res))
            die($res->getMessage()."erreur ".$sql);
            
        if ( $res->numRows() > 0 ){
            
            $row = $res->fetchRow(DB_FETCHMODE_ASSOC);
            $suffixe =  $row['suffixe'];
        }
        
        return $suffixe;
    }
    
    /*Récupère dans la table de paramètrage la lettre correspondant 
     * au dossier_instruction_type
     */
    function getCode($dossierInstructionType){
        
        $code = "";
        
        $sql = "SELECT 
                    code 
                FROM 
                    ".DB_PREFIXE."dossier_instruction_type 
                WHERE 
                    dossier_instruction_type = $dossierInstructionType";
                    
        $this->addToLog("getCode(): db->query(\"".$sql."\")", VERBOSE_MODE);
        $res = $this->db->query($sql);
        if (database :: isError($res))
            die($res->getMessage()."erreur ".$sql);
            
        if ( $res->numRows() > 0 ){
            
            $row = $res->fetchRow(DB_FETCHMODE_ASSOC);
            $code =  $row['code'];
        }
        
        return $code;
    }
    
    /*Récupère le numéro de version d'un dossier_autorisation*/
    function getNumeroVersion($dossierAutorisation){
        
        $numeroVersion = "";
        
        $sql = "SELECT 
                    numero_version
                FROM 
                    ".DB_PREFIXE."dossier_autorisation 
                WHERE 
                    dossier_autorisation = '$dossierAutorisation'";
                    
        $this->addToLog("getNumeroVersion(): db->query(\"".$sql."\")", VERBOSE_MODE);
        $res = $this->db->query($sql);
        if (database :: isError($res))
            die($res->getMessage()."erreur ".$sql);
            
        if ( $res->numRows() > 0 ){
            
            $row = $res->fetchRow(DB_FETCHMODE_ASSOC);
            $numeroVersion =  $row['numero_version'];
        }
        
        return $numeroVersion;
    }
    
    /*Incrémente le numéro de version du dossier*/
    function incrementNumeroVersion($dossierAutorisation, $nouveauNumeroVersion) {
        
        $valF = array (
                    "numero_version" => $nouveauNumeroVersion
                );
        
        $res = $this->db->autoExecute(DB_PREFIXE."dossier_autorisation", 
                                    $valF, 
                                    DB_AUTOQUERY_UPDATE, 
                                    "dossier_autorisation = '$dossierAutorisation'");
                                    
        if (database :: isError($res))
            die($res->getMessage()."erreur ".$sql);
            
    }

    /**
     * Retourne un numéro de version en fonction du type de dossier d'instruction
     * @param string $dossier_autorisation
     * @param integer $dossier_instruction_type
     * @return int
     */
    public function getNumeroVersionDossierInstructionType($dossier_autorisation, $dossier_instruction_type, $numero_version, $increment = true){
        
        $numeroVersionDossierInstructionType = $numero_version;
        
        //On récupère le code correspondant au type de dossier d'instruction passé
        //en paramètre
        $sql = "SELECT 
                code
            FROM
                ".DB_PREFIXE."dossier_instruction_type
            WHERE
                dossier_instruction_type = ".$dossier_instruction_type;
        $codeDossierInstructionType = $this->db->getOne($sql);       
        $this->f->addToLog("getNumeroVersionDossierInstructionType(): db->getOne(\"".$sql."\")", VERBOSE_MODE);
        if ( database::isError($codeDossierInstructionType)){
            $this->f->addToError("", $codeDossierInstructionType, $codeDossierInstructionType);
            return false;
        }
        
        
        // Si c'est un dossier d'instruction de type "Initial", code "P", on retourne 0
        if ( strcmp($codeDossierInstructionType, "P") == 0 ){
            return 0;
        }
        //Si c'est un modificatif ou transfert on retourne un nombre correspondant au
        //nombre de dossier d'instruction de ce type, rattaché au dossier 
        //d'autorisation complété par des 0 à gauche si besoin. Format du retour 
        //attendu : 01 ou 02, etc. 
        else {
            
            //On récupère le nombre de dossier d'instruction de ce type rattaché au 
            //dossier d'autorisation
            $sql = "SELECT 
                    count(dossier) 
                FROM 
                    ".DB_PREFIXE."dossier
                LEFT JOIN
                    ".DB_PREFIXE."dossier_autorisation
                    ON
                        dossier_autorisation.dossier_autorisation = dossier.dossier_autorisation
                WHERE
                    dossier_autorisation.dossier_autorisation = '".$dossier_autorisation."'
                    AND
                    dossier.dossier_instruction_type = ".$dossier_instruction_type;
            $numeroVersionDossierInstructionType = $this->db->getOne($sql);
            $this->f->addToLog("getNumeroVersionDossierInstructionType(): db->getOne(\"".$sql."\")", VERBOSE_MODE);
            if ( database::isError($numeroVersionDossierInstructionType)){
                $this->f->addToError("", $numeroVersionDossierInstructionType, $numeroVersionDossierInstructionType);
                return false;
            }
            
            // Requête SQL
            $sql = "SELECT
                        substring(dossier, '.{2}$')::int as last_num_dossier
                    FROM ".DB_PREFIXE."dossier
                    WHERE dossier_instruction_type = ".$dossier_instruction_type."
                    AND dossier_autorisation = '".$dossier_autorisation."'
                    AND version = (
                        SELECT max(version) 
                        FROM ".DB_PREFIXE."dossier 
                        WHERE dossier_instruction_type = ".$dossier_instruction_type."
                        AND dossier_autorisation = '".$dossier_autorisation."' 
                        GROUP BY dossier_instruction_type, dossier_autorisation
                    )";
            $res = $this->db->query($sql);
            $this->f->addToLog(__METHOD__."(): db->query(\"".$sql."\")", VERBOSE_MODE);
            $this->f->isDatabaseError($res);
            $row =& $res->fetchRow(DB_FETCHMODE_ASSOC);

            $num_version_last_dossier = $row['last_num_dossier'];

            if (!empty($num_version_last_dossier)
                && $num_version_last_dossier >= $numeroVersionDossierInstructionType) {
                // Modifie le numéro suivant
                $numeroVersionDossierInstructionType = $num_version_last_dossier;
            }
            //
            if ($increment === true) {
                $numeroVersionDossierInstructionType = ++$numeroVersionDossierInstructionType;
            }
            //On compléte par des 0 à gauche
            $numeroVersionDossierInstructionType = str_pad($numeroVersionDossierInstructionType, 2, "0", STR_PAD_LEFT);
            
            return $numeroVersionDossierInstructionType;
        }
    }
    /**
     * Retourne le libellé du dossier d'autorisation
     * @param  string $dossier_autorisation Identifiant du dossier d'autorisation
     * @return string                       Libellé dossier d'autorisation
     */
    function get_dossier_autorisation_libelle($dossier_autorisation) {

        $dossier_autorisation_libelle = "";

        // Requête SQL
        $sql = "SELECT 
                    dossier_autorisation_libelle
                FROM 
                    ".DB_PREFIXE."dossier_autorisation 
                WHERE 
                    dossier_autorisation = '$dossier_autorisation'";

        $dossier_autorisation_libelle = $this->db->getOne($sql);       
        $this->addToLog("get_dossier_autorisation_libelle(): db->getOne(\"".$sql."\")", VERBOSE_MODE);
        database::isError($dossier_autorisation_libelle);
        
        // Retourne le résultat
        return $dossier_autorisation_libelle;
    }
    
    function setvalF($val){
        parent::setvalF($val);

        // Récupération des id demandeurs postés
        $this->getPostedValues();

        // enlever les valeurs a ne pas saisir -> recherche en trigger ajouter et modifier
        // $sig = 1
        unset ($this->valF['geom']);
        unset ($this->valF['geom1']);
        // valeurs hiddenstatic (calcule)
        if($this->maj==1){
            // par defaut
            unset ($this->valF['etat']);
            unset ($this->valF['delai']);
            unset ($this->valF['accord_tacite']);
        }
        unset ($this->valF['avis_decision']); // avis + libelle avis
        unset ($this->valF['terrain_surface_calcul']);
        unset ($this->valF['shon_calcul']);
        unset ($this->valF['parcelle_archive']);
        unset ($this->valF['parcelle_lot_archive']);
        unset ($this->valF['date_notification_delai']);
        unset ($this->valF['date_decision']);
        unset ($this->valF['date_limite']);
        unset ($this->valF['date_validite']);
        unset ($this->valF['date_chantier']);
        unset ($this->valF['date_achevement']);
        unset ($this->valF['date_conformite']);

        // Durée de validité lors de la création du dossier d'instruction
        $this->valF['duree_validite'] = $this->get_duree_validite($this->valF['dossier_autorisation']);
    }

    /*Vérification des données saisies*/
    function verifier($val,&$db,$DEBUG){
        parent::verifier($val,$db,$DEBUG);
        if(!isset($this->postedIdDemandeur["petitionnaire_principal"]) OR
           empty($this->postedIdDemandeur["petitionnaire_principal"])) {
            $this->correct = false;
            $this->addToMessage(_("La saisie d'un petitionnaire principal est obligatoire."));
        }
        if($val['parcelle']!="" and $val['sig']!='Oui'){
            if  (!preg_match('/^[0-9]{3} [A-Z]{1,3} [0-9]{1,5}$/', $val['parcelle']) && !preg_match('/^[0-9]{3}[A-Z]{1,3}[0-9]{1,5}$/', $val['parcelle'])){ 
                $this->correct=false;
                $this->addToMessage("<br>format parcelle incorrect");
            }
        }
    }//verifier


    function setType(&$form,$maj) {
        parent::setType($form,$maj);
        $form->setType('dossier','hidden');
        $form->setType('amenagement','hidden'); // PC
        $form->setType('parcelle_lot','hidden'); // PC
        $form->setType('parcelle_lot_lotissement','hidden'); // PC
        $form->setType('version','hidden'); // PC
        $form->setType('incompletude','hidden');
        $form->setType('incomplet_notifie','hidden');
        $form->setType('etat_pendant_incompletude','hidden');
        $form->setType('duree_validite','hidden');
        $form->setType('description','hidden');
        $form->setType('quartier', 'hidden');
        // XXX
        $form->setType('servitude', 'hidden');  
        if ($maj < 2) { //ajouter et modifier
            // cache
            if($maj==0) $form->setType('dossier_libelle', 'hidden');
            if($maj==0) $form->setType('dossier_demandeur','hidden');
            if($maj==0) $form->setType('description_projet','hidden');
            $form->setType('description_projet','hiddenstatic');
            $form->setType('annee', 'hidden');
            $form->setType('parcelle_archive','hidden');
            $form->setType('parcelle_lot_archive','hidden'); 
            $form->setType('geom1', 'hidden');
            $form->setType('geom', 'hiddenstatic');
            // $form->setType('servitude', 'hiddenstatic');
            $form->setType('autorite_competente', 'selecthiddenstatic');
            
            // Si l'état du dossier est incomplet
            if ($this->is_incomplet_notifie()) {
                // On cache les dates de complétude et de limite d'instruction
                $form->setType('date_complet', 'hiddendate');
                $form->setType('date_limite', 'hiddendate');
                $form->setType('evenement_suivant_tacite_incompletude','selecthiddenstatic');
                $form->setType('evenement_suivant_tacite','hidden');
                $form->setType('date_limite_incompletude', 'hiddenstaticdate');

            } else {
                // Sinon on cache la date de limite d'incomplétude
                $form->setType('date_limite_incompletude', 'hiddendate');
                $form->setType('evenement_suivant_tacite_incompletude','hidden');
                $form->setType('evenement_suivant_tacite','selecthiddenstatic');
                $form->setType('date_complet', 'hiddenstaticdate');
                $form->setType('date_limite', 'hiddenstaticdate');
            }

            // hiddenstatic
            if($maj==1) $form->setType('dossier_libelle', 'hiddenstatic');
            if($maj==1) $form->setType('dossier_demandeur','hiddenstatic');
            $form->setType('terrain','hiddenstatic');
            $form->setType('etat','hiddenstatic');
            $form->setType('avis_decision','hiddenstatic');
            $form->setType('delai_incompletude','hidden');
            $form->setType('delai','hiddenstatic');
            $form->setType('terrain_surface_calcul','hiddenstatic');
            $form->setType('shon_calcul','hiddenstatic');
            
            $form->setType('accord_tacite','hiddenstatic');

            
            // hiddenstaticdate
            $form->setType('date_notification_delai','hiddenstaticdate');
            $form->setType('date_decision','hiddenstaticdate');
            //$form->setType('date_limite','hiddenstaticdate');
            $form->setType('date_rejet','hiddenstaticdate');
            //$form->setType('date_complet','hiddenstaticdate');
            //$form->setType('date_limite','hiddenstaticdate');
            $form->setType('date_validite','hiddenstaticdate');
            $form->setType('date_chantier','hiddenstaticdate');
            $form->setType('date_achevement','hiddenstaticdate');
            $form->setType('date_conformite','hiddenstaticdate');
            //$form->setType('date_limite_incompletude','hiddenstaticdate');

            $form->setType('date_depot','hiddenstaticdate');
            $form->setType('date_dernier_depot','hiddenstaticdate');

            // checkbox    
            $form->setType('sig','checkbox');        
            
            // zones temp et strategysig
            

            // temp
            if (file_exists ("../dyn/var.inc"))
                include ("../dyn/var.inc");
            if(!isset($auto_pos))
                $auto_pos=0;              
            if($auto_pos==1)
               $form->setType('pos','hiddenstatic');
            else
                $form->setType('pos','select');
            $form->setType('temp1',$temp1_type);
            $form->setType('temp2',$temp2_type);
            $form->setType('temp3',$temp3_type);
            $form->setType('temp4',$temp4_type);
            $form->setType('temp5',$temp5_type);
            $form->setType('a_qualifier', 'checkbox');

            $form->setType('parcelle', 'hidden');
            $form->setType('pos', 'hidden');
            $form->setType('sig', 'hidden');
            $form->setType('batiment_nombre', 'hidden');
            $form->setType('logement_nombre', 'hidden');
            $form->setType('hauteur', 'hidden');
            $form->setType('piece_nombre', 'hidden');
            $form->setType('shon', 'hidden');
            $form->setType('shon_calcul', 'hidden');
            $form->setType('shob', 'hidden');
            $form->setType('lot', 'hidden');
        }
        if ($maj == 1) {
            //
            if ($this->f->isAccredited("dossier_modifier_instructeur")) {
                $form->setType('instructeur', 'select');
            } else {
                $form->setType('instructeur', 'selecthiddenstatic');
            }
            //
            if($this->f->getParameter('option_afficher_division') === 'true') {
                //
                if ($this->f->isAccredited("dossier_modifier_division")) {
                    $form->setType('division', 'select');
                } else {
                    $form->setType('division', 'selecthiddenstatic');
                }
            } else {
                $form->setType('division', 'hidden');
            }
        }
        if($maj == 3) {
            $form->setType('annee', 'hidden');
            $form->setType('temp1','hidden');
            $form->setType('temp2','hidden');
            $form->setType('temp3','hidden');
            $form->setType('temp4','hidden');
            $form->setType('temp5','hidden');
            $form->setType('parcelle_archive','hidden');
            $form->setType('parcelle_lot_archive','hidden');
            $form->setType('geom1','hidden');
            $form->setType('geom','static');
            $form->setType('a_qualifier', 'checkboxstatic');
            $form->setType('terrain_references_cadastrales','referencescadastralesstatic'); // PC
            $form->setType('parcelle', 'hidden');
            $form->setType('pos', 'hidden');
            $form->setType('sig', 'hidden');
            $form->setType('batiment_nombre', 'hidden');
            $form->setType('logement_nombre', 'hidden');
            $form->setType('hauteur', 'hidden');
            $form->setType('piece_nombre', 'hidden');
            $form->setType('shon', 'hidden');
            $form->setType('shon_calcul', 'hidden');
            $form->setType('shob', 'hidden');
            $form->setType('lot', 'hidden');
            $form->setType('delai_incompletude','hidden');
            // Si l'état du dossier est incomplet
            if ($this->is_incomplet_notifie()) {
                // On cache les dates de complétude et de limite d'instruction
                $form->setType('date_complet', 'hiddendate');
                $form->setType('date_limite', 'hiddendate');
                $form->setType('evenement_suivant_tacite_incompletude','selecthiddenstatic');
                $form->setType('evenement_suivant_tacite','hidden');

            } else {
                // Sinon on cache la date de limite d'incomplétude
                $form->setType('date_limite_incompletude', 'hiddendate');
                $form->setType('evenement_suivant_tacite_incompletude','hidden');
                $form->setType('evenement_suivant_tacite','selecthiddenstatic');
            }
        }

        // Le profil Qualificateur ne peut modifier seulement les champs
        // autorite_competente, a_qualifier et erp
        if ($this->f->isUserQualificateur()) {

            // En modification
            if ($maj == 1) {
                
                $form->setType('numero_versement_archive', 'static');
                $form->setType('enjeu_urba', 'checkboxstatic');
                $form->setType('enjeu_erp', 'checkboxstatic');
            }
        }

        //
        if(!$this->f->getParameter('option_afficher_division') === 'true') {
            $form->setType('division', 'hidden');
        }
        $form->setType('dossier_autorisation', 'hidden');
        $form->setType('dossier_autorisation_libelle', 'hidden');
        $form->setType('dossier_instruction_type', 'selecthiddenstatic');
        //
        if ($maj == 0) {
            $form->setType('dossier_autorisation', 'select');
        }

        // En mode modifier, supprimer et consulter
        if ($maj != 0) {
            // Cache la date de la demande
            $form->setType('date_demande', 'hiddendate');
        }

        // XXX Champs cachés
        $form->setType('accord_tacite', 'hidden');
        $form->setType('date_rejet', 'hiddendate');
        $form->setType('date_notification_delai', 'hiddendate');
        $form->setType('date_chantier', 'hiddendate');
        $form->setType('date_achevement', 'hiddendate');
        $form->setType('date_conformite', 'hiddendate');
        
        // On cache les champs geom si aucun SIG n'est configuré
        if($this->f->getParameter('option_sig') == '' 
            || $this->f->getParameter('option_sig') == 'aucun'){
            $form->setType('geom', 'hidden');
            $form->setType('geom1', 'hidden');
        }
    }

    function setVal(&$form,$maj,$validation){
        $this->maj=$maj;

        if($this->getVal('geom') != "" 
            && $this->f->getParameter('option_sig') == 'sig_externe' 
            && $this->f->issetSIGParameter() === true) {
            $form->setVal('geom',
                "<a id='action-form-localiser'".
                " target='_SIG' href='../app/redirect_plan_sig.php?idx=".$this->getVal("dossier")."'>".
                "<span class='om-icon om-icon-16 om-icon-fix sig-16' title='Localiser'>Localiser</span> ".
                $this->getVal('geom').
                " </a>");
        }
        if ($validation==0) {
            if ($maj == 0){
                //$dossier_cp = $this->f->collectivite["cp"];
                //$dossier_ville = $this->f->collectivite["ville"];
              
                $form->setVal('annee', date('y'));
                $form->setVal('date_demande', date('Y-m-d'));
                $form->setVal('date_depot', date('Y-m-d'));
              
                //$form->setVal('demandeur_cp', $dossier_cp);
                //$form->setVal('demandeur_ville', $dossier_ville);
              
                //$form->setVal('delegataire_cp', $dossier_cp);
                //$form->setVal('delegataire_ville', $dossier_ville);
              
                //$form->setVal('terrain_cp', $dossier_cp);
                //$form->setVal('terrain_ville', $dossier_ville);
              
                $form->setVal('accord_tacite', 'Non');
                $form->setVal('etat', 'initialiser');
            }
        }
    }

    function setSelect(&$form, $maj,&$db,$debug) {
        // XXX Commenté pour patcher le problème de montée en charge de la base
        // de données en cas de reprise de données d'un gros volume de dossier
        // d'instruction
        //parent::setSelect($form, $maj, $db, $debug);

        //optimisation sur table importante parcelle -> pas d appel methode parent
        if(file_exists ("../sql/".OM_DB_PHPTYPE."/".$this->table.".form.inc.php"))
                include ("../sql/".OM_DB_PHPTYPE."/".$this->table.".form.inc.php");

        /* 
         *  Pour chaque init_select d'un select non modifiable on teste
         *  si l'on est en mode modifier : si c'est le cas alors on initialise le
         *  select en mode consulter (qui n'affiche rien s'il n'y a aucune valeur).
         */

        // instructeur
        $this->init_select($form, $db, $maj, $debug, "instructeur",
                               $sql_instructeur, $sql_instructeur_by_id, true);

        // etat
        if ($maj == 1) {
            $this->init_select($form, $db, 3, $debug, "etat",
                           $sql_etat, $sql_etat_by_id, false);
        } else {
            $this->init_select($form, $db, $maj, $debug, "etat",
                               $sql_etat, $sql_etat_by_id, false);
        }

        // dossier_instruction_type
        if ($maj == 1) {
            $this->init_select($form, $db, 3, $debug, "dossier_instruction_type",
                           $sql_dossier_instruction_type, $sql_dossier_instruction_type_by_id, false);
        } else {
            $this->init_select($form, $db, $maj, $debug, "dossier_instruction_type",
                               $sql_dossier_instruction_type, $sql_dossier_instruction_type_by_id, false);
        }

        // division
        $this->init_select($form, $db, $maj, $debug, "division",
                               $sql_division, $sql_division_by_id, false);

        // autorite_competente
        if ($maj == 1) {
            $this->init_select($form, $db, 3, $debug, "autorite_competente",
                           $sql_autorite_competente, $sql_autorite_competente_by_id, false);
        } else {
            $this->init_select($form, $db, $maj, $debug, "autorite_competente",
                               $sql_autorite_competente, $sql_autorite_competente_by_id, false);
        }

        // avis_decision
        if ($maj == 1) {
            $this->init_select($form, $db, 3, $debug, "avis_decision",
                           $sql_avis_decision, $sql_avis_decision_by_id, false);
        } else {
            $this->init_select($form, $db, $maj, $debug, "avis_decision",
                               $sql_avis_decision, $sql_avis_decision_by_id, false);
        }

        // evenement_suivant_tacite
        if ($maj == 1) {
            $this->init_select($form, $db, 3, $debug, "evenement_suivant_tacite",
                           $sql_evenement_suivant_tacite, $sql_evenement_suivant_tacite_by_id, false);
        } else {
            $this->init_select($form, $db, $maj, $debug, "evenement_suivant_tacite",
                               $sql_evenement_suivant_tacite, $sql_evenement_suivant_tacite_by_id, false);
        }

        // evenement_suivant_tacite_incompletude
        if ($maj == 1) {
            $this->init_select($form, $db, 3, $debug, "evenement_suivant_tacite_incompletude",
                           $sql_evenement_suivant_tacite_incompletude, $sql_evenement_suivant_tacite_incompletude_by_id, false);
        } else {
            $this->init_select($form, $db, $maj, $debug, "evenement_suivant_tacite_incompletude",
                               $sql_evenement_suivant_tacite_incompletude, $sql_evenement_suivant_tacite_incompletude_by_id, false);
        }

        if($maj<2){
            // parcelle_lot
            $contenu="";
            $contenu[0][0]="parcelle_lot";// table
            $contenu[0][1]="parcelle_lot"; // zone origine
            $contenu[1][0]="lotissement";
            $contenu[1][1]="parcelle_lot_lotissement";
            $form->setSelect("parcelle_lot",$contenu);
            $contenu="";
            $contenu[0][0]="parcelle_lot";// table
            $contenu[0][1]="lotissement"; // zone origine
            $contenu[1][0]="parcelle_lot";
            $contenu[1][1]="parcelle_lot";
            $form->setSelect("parcelle_lot_lotissement",$contenu);
            // accord tacite
            $contenu=array();
            $contenu[0]=array('Non','Oui');
            $contenu[1]=array('Non','Oui');
            $form->setSelect("accord_tacite",$contenu);
            
            // geom *** a voir
            if($maj==1){ //modification
                $contenu=array();
                $contenu[0]=array("dossier",$this->getParameter("idx"));
                $form->setSelect('geom',$contenu);
            }
            // arrondissement recherche anvancée
            $this->init_select($form, $db, $maj, $debug, "arrondissement",
                           $sql_arrondissement, $sql_arrondissement_by_id, false);
            // dossier_autorisation_type_detaille recherche anvancée
            $this->init_select($form, $db, $maj, $debug, "dossier_autorisation_type_detaille",
                           $sql_dossier_autorisation_type_detaille, $sql_dossier_autorisation_type_detaille_by_id, false);
            /*
             * Affichage de données dans le select de la parcelle
             * */
            $contenu=array();
            $sql="select parcelle from ".DB_PREFIXE."parcelle ";
            $res = $db->query($sql);
            if (database::isError($res))
                die($res->getMessage());
            $contenu[0][0]="";
            $contenu[1][0]=_("choisir parcelle");
            $k=1;
            while ($row=& $res->fetchRow()){
                $contenu[0][$k]=$row[0];
                $contenu[1][$k]=$row[0];
                $k++;
            }
            $form->setSelect("parcelle",$contenu);
            
        }
        if($this->f->getParameter('option_afficher_division')==='true') {
            // instructeur
            $this->init_select($form, $db, $maj, $debug, "instructeur",
            $sql_instructeur_div, $sql_instructeur_div_by_id, true);
        }
    }

    function setLib(&$form,$maj) {
        parent::setLib($form,$maj);
        $form->setLib('dossier_autorisation_libelle',_('dossier_autorisation_libelle'));
        $form->setLib('dossier_instruction_type',_('type de dossier'));
        $form->setLib('servitude',_('contraintes'));
        $form->setLib('dossier_demandeur',_('demandeur')); 
        $form->setLib('description_projet',_('description du projet'));        
        $form->setLib('autorite_competente',_('competence'));
        $form->setLib('geom',_('geolocalisaion'));
        $form->setLib('date_limite',_("date limite d'instruction"));
        $form->setLib('delai',_("delai d'instruction"));
        $form->setLib('accord_tacite',_("decision tacite"));
        $form->setLib('enjeu_urba', _("urbanisme"));
        $form->setLib('enjeu_erp', _("ERP"));
        $form->setLib('numero_versement_archive', _("numero"));
        $form->setLib('erp', _("ERP"));
        $form->setLib('date_depot', _("depot"));
        $form->setLib('date_dernier_depot', _("dernier depot"));
        $form->setLib('date_limite', _("limite d'instruction"));
        $form->setLib('delai', _("delai (mois)"));
        $form->setLib('date_complet', _("completude"));
        $form->setLib('date_limite_incompletude', _("limite d'incompletude"));
        $form->setLib('date_decision', _("date de la decision"));
        $form->setLib('date_validite', _("fin de validite le"));
    }    

    function setOnchange(&$form,$maj){
        parent::setOnchange($form,$maj);
        // mise en majuscule
        $form->setOnchange("demandeur_nom","this.value=this.value.toUpperCase()");
        $form->setOnchange("demandeur_societe","this.value=this.value.toUpperCase()");
        $form->setOnchange("delegataire_nom","this.value=this.value.toUpperCase()");
        $form->setOnchange("delegataire_societe","this.value=this.value.toUpperCase()");
        $form->setOnchange("architecte_nom","this.value=this.value.toUpperCase()");
        $form->setOnchange("terrain_adresse","this.value=this.value.toUpperCase()");
        $form->setOnchange('shon','VerifNumdec(this)');
        $form->setOnchange('shob','VerifNumdec(this)');
        $form->setOnchange('hauteur','VerifNumdec(this)');
        $form->setOnchange('terrain_surface','VerifNumdec(this)');
    }

    function setLayout(&$form, $maj) {
        
         // En-tête
        $form->setBloc('dossier_libelle', 'D', '', ($maj == 3 ? 'col_9':'col_12'));

            // Col1 : Fieldset "Dossier d'Instruction"
            $form->setBloc('dossier_libelle', 'D', '', 'col_9');

                $form->setFieldset('dossier_libelle', 'D', _("Dossier d'instruction"));
                $form->setFieldset('geom', 'F');
                

            $form->setBloc('geom', 'F');
        
            // Col2 : 3 fieldsets
            $form->setBloc('enjeu_urba', 'D', '', 'col_3');

                // Fieldset "Enjeu"
                $form->setFieldset('enjeu_urba', 'D', _("Enjeu"));
                $form->setFieldset('enjeu_erp', 'F');
                // Fieldset "Qualification"
                $form->setFieldset('erp', 'D', _("Qualification"));
                $form->setFieldset('a_qualifier', 'F');
                // Fieldset "Archive"
                $form->setFieldset('numero_versement_archive', 'D', _("Archive"));
                $form->setFieldset('date_demande', 'F');

            $form->setBloc('date_demande', 'F');
        $form->setBloc('date_demande', 'F');

        // Fieldset "Instruction"
        $form->setBloc('date_depot', 'D', '', 'col_12');
        $form->setFieldset('date_depot', 'D', _('Instruction'), 'col_12');

        // Fieldset "Suivi"
        $form->setBloc('date_depot', 'D', '', 'col_12');
        
            $form->setFieldset('date_depot', 'D', _('Suivi'), 'col_12');
            // Col 1
            $form->setBloc('date_depot', 'D', '', 'col_6');
                $form->setBloc('date_depot', 'D');
                $form->setBloc('date_dernier_depot', 'F');
                $form->setBloc('date_limite', 'D', '', 'interligne');
                $form->setBloc('date_limite_incompletude', 'F');
            $form->setBloc('date_limite_incompletude', 'F');
            // Col 2
            $form->setBloc('etat', 'D', '', 'col_6');
                $form->setBloc('etat', 'D');
                $form->setBloc('etat', 'F');
                $form->setBloc('evenement_suivant_tacite', 'D', '', 'evmt_suivant_tacite_di');
                $form->setBloc('evenement_suivant_tacite_incompletude', 'F');
            $form->setBloc('evenement_suivant_tacite_incompletude', 'F');
            $form->setFieldset('evenement_suivant_tacite_incompletude','F','');
        
        $form->setBloc('evenement_suivant_tacite_incompletude', 'F'); // Fin Suivi

        // Bloc 2 fieldsets
        $form->setBloc('date_decision', 'D', '', 'col_12');

        // Col 1 Fieldset "Décision"
        $form->setFieldset('date_decision', 'D', _('Decision'), 'col_6');
        $form->setFieldset('avis_decision','F',''); 
        // Col 2 Fieldset "Validité de l'autorisation"
        $form->setFieldset('date_validite', 'D', _("Validite de l'autorisation"), 'col_6');
        $form->setFieldset('date_validite','F',''); 

        $form->setBloc('date_validite', 'F'); // Fin bloc 2 fieldsets

        // XXX Champs cachés
        // // Fieldset "Autre"
        // $form->setBloc('accord_tacite', 'D', '', 'col_12');        
        //     $form->setFieldset('accord_tacite', 'D', _('Autre'), 'col_12');

        //         $form->setBloc('accord_tacite', 'D', '', 'col_4');
        //         $form->setBloc('accord_tacite', 'F');

        //         $form->setBloc('date_rejet', 'D', '', 'col_4');
        //         $form->setBloc('date_achevement', 'F');

        //         $form->setBloc('date_conformite', 'D', '', 'col_4');
        //         $form->setBloc('date_conformite', 'F');

        //     $form->setFieldset('date_conformite','F','');        
        // $form->setBloc('date_conformite', 'F'); // Fin Autre

        $form->setFieldset('date_conformite','F','');
        $form->setBloc('date_conformite', 'F'); // Fin Instruction

        // Fieldset "Localisation du terrain"
        $form->setBloc('terrain_adresse_voie_numero', 'D', '', 'col_12');

            $form->setFieldset('terrain_adresse_voie_numero', 'D', _('Localisation du terrain'), 'startClosed');
                // Col 1
                $form->setBloc('terrain_adresse_voie_numero', 'D', "", "col_6");
                $form->setBloc('terrain_references_cadastrales', 'F');
                // Col 2
                $form->setBloc('terrain_adresse_voie', 'D', "", "col_6");
                $form->setBloc('terrain_superficie', 'F');

            $form->setFieldset('terrain_superficie', 'F', '');

        $form->setBloc('terrain_superficie', 'F');
    }

    /**
     * Permet de retourner si le dossier est incomplet notifié
     *
     * @return boolean true si incomplet notifié
     */
    function is_incomplet_notifie() {
        // Si le dossier est défini en tant qu'incomplet notifie
        if($this->getVal('incomplet_notifie') == 't' AND
            $this->getVal('incompletude') == 't') {
            return true;
        }
        return false;
    }

    /* =============================================================
    * fonction trigger relative a la connexion SIG
    * $sig = 1 dans dyn/var.inc
    * utilisé aussi pour envoyer une message au service REST d'ERP
    * ===============================================================
    */

    function triggerajouterapres($id,&$db,$val,$DEBUG) {
        $this->sig_parametre($db);
        $id=$this->valF['dossier']; // id n est pas valorise en ajout
        if($this->sig==1 and $val['sig']!='Oui'){
            if($val['parcelle']!=''or $val['parcelle_lot']!=''){
                    
                $this->sig_interne($id,$db,$val,$DEBUG);
            }
            else
                $this->addToMessage("<br>"._("Parcelle non renseignee dans dossier")." ".$id." <br>");
            
        }
        
        
        if ($this->f->getParameter('option_erp') === 'true') {
            // envoi du message a ERP en cas d'un depot du dossier dat
            if ($this->f->getDATDCode($this->valF['dossier']) ==
                    $this->f->getParameter('erp_depot_dossier_dat')) {
                $msgenque = new MessageEnqueuer();
                $msgenque->setDossierInstructionIdentifier($this->valF['dossier']);
                $return = $msgenque->enqueueMessage($msgenque::$ERP_DEPOT_DOSSIER_DAT);
                //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."));
                }
            }
            
            // envoi du message a ERP en cas d'une demande d'ouverture DAT
            if ($this->f->getDATDCode($this->valF['dossier']) ==
                    $this->f->getParameter('erp_demande_ouverture_dat')) {
                $msgenque = new MessageEnqueuer();
                $msgenque->setDossierInstructionIdentifier($this->valF['dossier']);
                $return = $msgenque->enqueueMessage($msgenque::$ERP_DEMANDE_OUVERTURE_DAT);
                //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['erp'] === true) {
                // envoi du message a ERP en cas d'annulation d'une demande
                if ($this->f->getDATDCode($this->valF['dossier']) ==
                        $this->f->getParameter('erp_annulation_demande')) {
                    $msgenque = new MessageEnqueuer();
                    $msgenque->setDossierInstructionIdentifier($this->valF['dossier']);
                    $return = $msgenque->enqueueMessage($msgenque::$ERP_ANNULATION_DEMANDE);
                    //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."));
                    }
                }
                
                // envoi du message a ERP en cas d'ouverture d'un dossier PC "rattache"
                // au dossier DAACT
                if ($this->f->getDATDCode($this->valF['dossier']) ==
                        $this->f->getParameter('erp_demande_ouverture_pc_daact')) {
                    $msgenque = new MessageEnqueuer();
                    $msgenque->setDossierInstructionIdentifier($this->valF['dossier']);
                    $return = $msgenque->enqueueMessage($msgenque::$ERP_DEMANDE_OUVERTURE_PC);
                    //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') 
        
        //On ajoute les données techniques
        if($this->ajoutDonneesTechniquesDI($id, $db, $val, $DEBUG) === false){
            //
            $this -> addToMessage(
                _("Erreur lors de l'enregistrement du dossier.")." ".
                _("Contactez votre  administrateur.")
            );
            $this->correct = false;
            return false;
        }
        
        // Mise à jour des données du dossier d'autorisation
        require_once "../obj/dossier_autorisation.class.php";
        $da = new dossier_autorisation($this->valF["dossier_autorisation"], $this->db, DEBUG);
        $da->majDossierAutorisation();

        // Si le champ des références cadastrales n'est pas vide
        if ($this->valF['terrain_references_cadastrales'] != '') {

            // Ajout des parcelles dans la table dossier_parcelle
            $this->ajouter_dossier_parcelle($this->valF['dossier'], 
                $this->valF['terrain_references_cadastrales']);

        }

    }
    
    /**
     * Récupère l'identifiant du quartier et d'un arrondissement d'une référence 
     * cadastrale
     * @param string $reference_cadastrale
     * 
     * @return array
     */
    function getQuartierArrondissement($reference_cadastrale) {
             
        $reference_cadastrale = trim($reference_cadastrale);
        $quartier = '';
         
        //Récupère le code impot du quartier dans la référence cadastrale
        for ( $i = 0 ; $i < strlen($reference_cadastrale) ; $i++ ){
           
           //Si c'est un chiffre, c'est le code quartier
           if (is_numeric($reference_cadastrale[$i]) ){

               $quartier .= $reference_cadastrale[$i];
           }
           //Sinon c'est la section
           else{
               break;
           }
        }
       
        //Si le code impôt du quartier a bien été renseigné
        if ( $quartier !== '' ){
           
            //Requête de récupération de l'identifiantdu quartier et de 
            //l'arrondissement
            $sql = "SELECT
                        quartier, arrondissement
                    FROM
                        ".DB_PREFIXE."quartier
                    WHERE
                        code_impots='$quartier'";
            $this->addToLog("getQuartierArrondissement() : db->query(\"$sql\")", VERBOSE_MODE);
            $res = $this->db->query($sql);
            if (database::isError($res)) {
                die();
            }
           
            //Si on a un résultat
            if ( $res->numRows() == 1 ){
                //    
                return $res->fetchRow(DB_FETCHMODE_ASSOC);
            }
        }
       
        return NULL;
    }
    
    /**
     * Récupère la section d'une référence cadastrale
     * @param string $reference_cadastrale
     * 
     * @return string
     */
    function getSection($reference_cadastrale){
         
        $reference_cadastrale = trim($reference_cadastrale);
        $section = NULL;
         
        for ( $i = 0 ; $i < strlen($reference_cadastrale) ; $i++ )
            if ( !is_numeric($reference_cadastrale[$i]) && is_string($reference_cadastrale[$i]) && $reference_cadastrale[$i] !== ' ' )
                $section .= $reference_cadastrale[$i];
         
        return $section;
    }
    
    /*
     * Retourne l'intructeur correspondant le mieux à la parcelle
     * */
    /**
     * Récupère la section d'une référence cadastrale
     * @param string $quartier
     * @param string $arrondissement
     * @param string $section
     * @param string $dossier_autorisation
     * 
     * @return array
     */    
    function getInstructeurDivision( $quartier, $arrondissement, $section, $dossier_autorisation_type_detaille) {

        $quartier = ( $quartier == NULL ) ? -1 : $quartier;
        $arrondissement = ( $arrondissement == NULL ) ? -1 : $arrondissement;
 
        //Si le dossier d'autorisation a un type détaillé de dossier 
        //d'autorisation associé
        if ($dossier_autorisation_type_detaille != ''
            && $dossier_autorisation_type_detaille != null){

            //Requête de récupération de l'instructeur à affecter
            $sql = "
               SELECT
                   instructeur, section, quartier, arrondissement, dossier_autorisation_type_detaille
               FROM
                   ".DB_PREFIXE."affectation_automatique l
               WHERE
                   ( dossier_autorisation_type_detaille IS NULL AND arrondissement IS NULL AND quartier IS NULL AND section IS NULL ) OR
                   ( dossier_autorisation_type_detaille IS NULL AND arrondissement IS NULL AND quartier IS NULL AND section = '$section' ) OR
                   ( dossier_autorisation_type_detaille IS NULL AND arrondissement IS NULL AND quartier = $quartier AND section IS NULL ) OR
                   ( dossier_autorisation_type_detaille IS NULL AND arrondissement IS NULL AND quartier = $quartier AND section = '$section' ) OR
                   ( dossier_autorisation_type_detaille IS NULL AND arrondissement = $arrondissement AND quartier IS NULL AND section IS NULL ) OR
                   ( dossier_autorisation_type_detaille IS NULL AND arrondissement = $arrondissement AND quartier IS NULL AND section = '$section' ) OR
                   ( dossier_autorisation_type_detaille IS NULL AND arrondissement = $arrondissement AND quartier = $quartier AND section IS NULL ) OR
                   ( dossier_autorisation_type_detaille IS NULL AND arrondissement = $arrondissement AND quartier = $quartier AND section = '$section' ) OR
                   ( dossier_autorisation_type_detaille = ".$dossier_autorisation_type_detaille." AND arrondissement IS NULL AND quartier IS NULL AND section IS NULL ) OR
                   ( dossier_autorisation_type_detaille = ".$dossier_autorisation_type_detaille." AND arrondissement IS NULL AND quartier IS NULL AND section = '$section' ) OR
                   ( dossier_autorisation_type_detaille = ".$dossier_autorisation_type_detaille." AND arrondissement IS NULL AND quartier = $quartier AND section IS NULL ) OR
                   ( dossier_autorisation_type_detaille = ".$dossier_autorisation_type_detaille." AND arrondissement IS NULL AND quartier = $quartier AND section = '$section' ) OR
                   ( dossier_autorisation_type_detaille = ".$dossier_autorisation_type_detaille." AND arrondissement = $arrondissement AND quartier IS NULL AND section IS NULL ) OR
                   ( dossier_autorisation_type_detaille = ".$dossier_autorisation_type_detaille." AND arrondissement = $arrondissement AND quartier IS NULL AND section = '$section' ) OR
                   ( dossier_autorisation_type_detaille = ".$dossier_autorisation_type_detaille." AND arrondissement = $arrondissement AND quartier = $quartier AND section IS NULL ) OR
                   ( dossier_autorisation_type_detaille = ".$dossier_autorisation_type_detaille." AND arrondissement = $arrondissement AND quartier = $quartier AND section = '$section' )
               ORDER BY dossier_autorisation_type_detaille, section, quartier, arrondissement
               LIMIT 1";
            $this->addToLog("getInstructeurDivision : db->query(\"$sql\")", VERBOSE_MODE);
            $res = $this->db->query($sql);
            if (database :: isError($res))
                die($res->getMessage()."erreur ".$sql);
            
            //Si on a récupéré un instructeur correspondant aux critères
            if ( $res->numRows() > 0 ){
                
                $row = $res->fetchRow(DB_FETCHMODE_ASSOC);
                //On récupère sa division
                $sql = "SELECT division FROM ".DB_PREFIXE."instructeur WHERE instructeur = ".$row['instructeur'];
                $res = $this->db->query($sql);
                if (database :: isError($res))
                    die($res->getMessage()."erreur ".$sql);
                
                $row['division'] = NULL;
                //S'il a une division
                if ( $res->numRows() > 0 ){
                    
                    $rowT=& $res->fetchRow(DB_FETCHMODE_ASSOC);
                    $row['division'] = $rowT['division'];
                }
                
                return $row;
            }
        }

        return NULL; 
     }

     /**
      * Récupère le type détaillé d'une dossier d'autorisation.
      *
      * @param integer $dossier_autorisation DA
      *
      * @return mixed
      */
     function get_dossier_autorisation_da_type_detaille($dossier_autorisation) {

        //
        $resDATD = "";

        //Récupération du dossier_autorisation_type_detaille concerné par le 
        //$dossier_autorisation
        $sql = "
           SELECT
               dossier_autorisation_type_detaille
           FROM
               ".DB_PREFIXE."dossier_autorisation
           WHERE
               dossier_autorisation = '$dossier_autorisation'";
        $this->addToLog(__METHOD__." : db->query(\"$sql\")", VERBOSE_MODE);
        $resDATD = $this->db->getOne($sql);
        $this->f->isDatabaseError($resDATD);

        //
        return $resDATD;
     }
    
    /* =============================================================
    * fonction trigger relative a la connexion SIG
    * $sig = 1 dans dyn/var.inc
    * ===============================================================
    */

    function triggerajouter($id,&$db,$val,$DEBUG) {
        //
        $this->addToLog("triggerajouter() : start", EXTRA_VERBOSE_MODE);
        
        // Initialisation des variables nécessaires à l'affectation automatique
        $quartier = NULL;
        $arrondissement = NULL;
        $section = NULL;
        $instructeur = NULL;

        // Si la référence cadastrale n'est pas vide alors on récupère la 
        //section, le quartier et l'arrondissement
        if ($this->valF['terrain_references_cadastrales'] != '') {
            
            // Cette méthode récupère l'arrondissement et le quartier de la
            //référence cadastrale saisie 
            $quartierArrondissement = $this->getQuartierArrondissement($this->valF['terrain_references_cadastrales']);
            if ( $quartierArrondissement!= NULL ){
                
                $quartier = $quartierArrondissement['quartier'];
                $arrondissement = $quartierArrondissement['arrondissement'];
            }
            // Si il n'y a pas d'arrondissement alors on vide le quartier
            if ( strcmp($arrondissement,'') == 0 )  {
                
                $arrondissement = NULL;
                $quartier = NULL;
            }
            // On récupère la section
            $section = $this->getSection($this->valF['terrain_references_cadastrales']);
        }

        // Si aucun instructeur n'est saisi et que la dossier_autorisation_type_detaille n'est pas vide
        // alors on récupère l'instructeur et la division depuis l'affectation
        if ( ( empty($this->valF['instructeur']) || $this->valF['instructeur'] == '' ) && $val['dossier_autorisation'] != '' ) {

            // Récupère le type détaillé du DA
            $dossier_autorisation_type_detaille = $this->get_dossier_autorisation_da_type_detaille($this->valF['dossier_autorisation']);
            
            //Récupération de l'instructeur ainsi que de sa division
            $instructeurDivision = $this->getInstructeurDivision($quartier, $arrondissement, $section, $dossier_autorisation_type_detaille);

            //Si un instructeur et sa division ont été récupérés
            if ( $instructeurDivision != NULL ){
                
                $instructeur = $instructeurDivision['instructeur'];
                $division = $instructeurDivision['division'];
            }
            //Si un instructeur et sa division n'ont pas été récupérés, on 
            //ajoute pas les données
            if ( $instructeur != NULL ){
                
                $this->valF['instructeur'] = $instructeur;
                $this->valF['division'] = $division;
            } else {
                //On affiche un message à l'utilisateur pour lui signifier 
                //qu'aucun instructeur n'a été assigné au dossier d'instruction 
                //créé
                if ($this->f->isAccredited("dossier_modifier_instructeur")) {
                    $this->addToMessage("<br/> "._("Pensez a assigner un instructeur a ce dossier.")." <br/>");
                } else {
                    $this->addToMessage("<br/> "._("Aucun instructeur compatible avec ce dossier trouve, contactez votre administrateur afin d'en assigner un a ce dossier.")." <br/>");
                }
            }
        } else {
            $this->addToMessage("<br/> "._("Aucun instructeur compatible avec ce dossier trouve, contactez votre administrateur afin d'en assigner un a ce dossier.")." <br/>");
        }
        //
        $this->addToLog("triggerajouter() : end", EXTRA_VERBOSE_MODE);
    }

    function triggermodifierapres($id,&$db,$val,$DEBUG) {
        $this->sig_parametre($db);
        // si la parcelle est changée
        if(($this->sig==1 and $val['sig']!='Oui' and ($val['parcelle']!=$val['parcelle_archive'])
           or $val['parcelle_lot']!=$val['parcelle_lot_archive'])){ // parcelle_lot_archive
            if($val['parcelle']!='' or $val['parcelle_lot']!='')
                $this->sig_interne($this->valF['dossier'],$db,$val,$DEBUG);
            else{
                if($this->maj ==1){ // en maj mettre a null la geometrie si parcelle changée inexistante
                // XXX SERVITUDE
                $sql ="update ".DB_PREFIXE."dossier set geom = null, servitude = '', pos= '' where dossier ='".$id."'";
                $res = $db -> query($sql);
                // XXX SERVITUDE
                $this->addToLog("requete trigger modifier parcelle vide -> maj pos et servitude :".$sql, VERBOSE_MODE);
                if (database :: isError($res))
                    die($res->getMessage()."erreur ".$sql);
            }
                $this->addToMessage("<br>"._("Parcelle ou parcelle_lot non renseignee dans dossier")." ".$id." <br>");    
            }
        }
                
        // verification si envoi vers ERP est active
        if ($this->f->getParameter('option_erp') === 'true') {
            if ($this->val[array_search('a_qualifier', $this->champs)] == 't'
                && $this->valF['a_qualifier'] === false) {
                                
                // envoi du message "ERP Qualifie" pour un dossier DAT qui a besoin
                // de la qualification URBA
                if ($this->f->getDATDCode($this->valF['dossier']) ==
                             $this->f->getParameter('erp_nature_dat')) {
                    $msgenque = new MessageEnqueuer();
                    $msgenque->setDossierInstructionIdentifier($this->valF['dossier']);
                    $msgenque->setCompetence($this->valF['autorite_competente']);
                    // XXX SERVITUDE
                    $msgenque->setContraintePlu($this->valF['servitude']);
                    $msgenque->setReferenceCadastrale(
                            $this->getReferenceCadastrale($this->valF['dossier']));
                    $return = $msgenque->enqueueMessage($msgenque::$ERP_QUALIFIE);
                    //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."));
                    }                            
                }
                
                // envoi des messages a ERP en cas du dossier PC traite par URBA, et
                // qui etait classifie come ERP
                if ($this->f->getDATDCode($this->valF['dossier']) ==
                        $this->f->getParameter('erp_dossier_nature_pc')
                    && $this->valF['erp'] == true) {
                    $msgenque = new MessageEnqueuer();
                    $msgenque->setDossierInstructionIdentifier($this->valF['dossier']);
                    $return = $msgenque->enqueueMessage($msgenque::$ERP_DEMANDE_COMPLETUDE_PC);
                    //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."));
                    }
                
                    $return = $msgenque->enqueueMessage($msgenque::$ERP_DEMANDE_QUALIFICATION_PC);
                    //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"));
                        //Si c'est un problème de connexion vers rabbitMQ et AMQP
                        //On ne valide pas le formulaire
                        if ( $return === -3 ){
                            $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')  

        // Ajout ou modification des demandeurs
        $this->insertLinkDemandeDemandeur($db, $DEBUG);

        // Si le champ des références cadastrales n'est pas vide
        if ($this->getVal('terrain_references_cadastrales') 
            != $this->valF['terrain_references_cadastrales']) {

            // On supprime toutes les lignes de la table dossier_parcelle qui 
            // font référence le dossier en cours de modification
            $this->supprimer_dossier_parcelle($val['dossier']);

            // Ajout des parcelles dans la table dossier_parcelle
            $this->ajouter_dossier_parcelle($val['dossier'], 
                $val['terrain_references_cadastrales']);

        }

    }

    /**
     * Ne servira surement pas mais dans le doute autant recalculer les données du DA
     */
    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->valF["dossier_autorisation"], $this->db, DEBUG);
        $da->majDossierAutorisation();

        // On supprime toutes les lignes de la table dossier_parcelle qui 
        // font référence le dossier en cours de suppression
        $this->supprimer_dossier_parcelle($this->valF['dossier']);

    }
    
    
    /**
     * Retourne la reference cadastrale de la demande attache a un dossier ERP
     * specifique
     * @param string $dossier L'identifiant du dossier
     * @return string|null La reference cadastrale si elle est trouve,
     * sinon NULL. En cas d'erreur de la BD, l'execution s'arrete.
     */
    function getReferenceCadastrale($dossier) {
        $sql = "SELECT terrain_references_cadastrales FROM ".DB_PREFIXE."demande WHERE dossier_instruction = '" . $dossier . "'";
        $res = $this->db->limitquery($sql, 0, 1);
        $this->addToLog("getReferenceCadastrale(): db->limitquery(\"".
                        str_replace(",",", ",$sql)."\", 0, 1);", VERBOSE_MODE);
        // Si une erreur survient on die
        if (database::isError($res, true)) {
            // Appel de la methode de recuperation des erreurs
            $this->erreur_db($res->getDebugInfo(), $res->getMessage(), 'demande');
        }
        // retourne la nature du dossier
        while ($row =& $res->fetchRow()) {
            return $row[0];
        }
        // la nature n'etait pas trouve, ce qui ne devrait pas se passer
        return NULL;
    }
    

    function sig_parametre(&$db){
        if (file_exists ("../dyn/var.inc"))
            include ("../dyn/var.inc");
        if(!isset($sig))
            $this->sig=0;
        else
            $this->sig=1;
        if(!isset($auto_pos))
            $this->auto_pos=0;
        else
            $this->auto_pos=$auto_pos;
        if(!isset($auto_servitude_surfacique))
            $this->auto_servitude_surfacique=0;
        else
            $this->auto_servitude_surfacique=$auto_servitude_surfacique;
        if(!isset($auto_servitude_ligne))
            $this->auto_servitude_ligne=0;
        else
            $this->auto_servitude_ligne=$auto_servitude_ligne;
        if(!isset($auto_servitude_point))
            $this->auto_servitude_point=0;
        else
            $this->auto_servitude_point=$auto_servitude_point;
        if(!isset($auto_parcelle))
            $this->auto_parcelle=0;
        else
            $this->auto_parcelle=$auto_parcelle;
        if(!isset($auto_parcelle_lot))
            $this->auto_parcelle_lot=0;
        else
            $this->auto_parcelle_lot=$auto_parcelle_lot;
        $this->addToLog("trigger valeur sig :".$this->sig, VERBOSE_MODE);
        $this->addToLog("trigger valeur auto_pos :". $this->auto_pos, VERBOSE_MODE);
        $this->addToLog("trigger valeur auto_servitude_surfacique :".$this->auto_servitude_surfacique, VERBOSE_MODE);
        $this->addToLog("trigger valeur auto_servitude_ligne :". $this->auto_servitude_ligne, VERBOSE_MODE);
        $this->addToLog("trigger valeur auto_servitude_point :".$this->auto_servitude_point, VERBOSE_MODE);
        $this->addToLog("trigger valeur auto_parcelle :". $this->auto_parcelle, VERBOSE_MODE);
        $this->addToLog("trigger valeur auto_parcelle_lot :".$this->auto_parcelle_lot, VERBOSE_MODE);
    }


    function sig_interne($id,&$db,$val,$DEBUG){
        // Strategy interne dans var.inc
        // si la parcelle existe, il est cree un point au milieu de la parcelle
        // de maniere automatique
        $geom='';
        $parcelle=$val["parcelle"];
        $projection = $db -> getOne("select srid from geometry_columns where f_table_name='dossier'");
        if($this->auto_parcelle==1  and $val["parcelle"]!=''){
            $sql= "select astext(centroid(geom)) from ".DB_PREFIXE."parcelle where parcelle ='".$val["parcelle"]."'";
            $this->addToLog("recherche centroid parcelle :".$sql, VERBOSE_MODE);
            $geom = $db -> getOne($sql);
            if (database :: isError($geom))die($res->getMessage()."erreur ".$sql);
        }
        if($geom=='' and $this->auto_parcelle_lot==1 and $val["parcelle_lot"]!=''){ // lot
            $sql= "select astext(centroid(geom)) from ".DB_PREFIXE."parcelle_lot where parcelle_lot ='".$val["parcelle_lot"]."'";
            $this->addToLog("recherche centroid parcelle lot :".$sql, VERBOSE_MODE);
            $geom = $db -> getOne($sql);
            if (database :: isError($geom))die($res->getMessage()."erreur ".$sql);
            $parcelle=$val["parcelle_lot"]." ".$val["parcelle_lot_lotissement"];
        }
        if($geom!=''){ // la parcelle est exitante dans la table ou vue parcelle
            $sql ="update ".DB_PREFIXE."dossier set geom =geometryfromtext('".$geom."', ".$projection." ) where dossier ='".$id."'";
            $this->addToLog("sig_interne maj geom  :".$sql, VERBOSE_MODE);    
            $res = $db -> query($sql);
            if (database :: isError($res)) die($res->getMessage()."erreur ".$sql);
            $this->addToMessage(""._("centroid de parcelle calcule")." ".$parcelle." ");
            if($this->auto_pos==1) // recherche du pos 
                $this->calcul_auto_pos($id,$db,$geom,$projection);
            if($this->auto_servitude_surfacique==1) // recherche de servitude surfacique
                $this->calcul_auto_servitude_surfacique($id,$db,$geom,$projection);
            if($this->auto_servitude_ligne==1) // recherche de servitude ligne
                $this->calcul_auto_servitude_ligne($id,$db,$geom,$projection);
            if($this->auto_servitude_point==1) // recherche de servitude point
                $this->calcul_auto_servitude_point($id,$db,$geom,$projection);
            $temp=strtr($this->servitude,"'"," "); // enleve le '
            // XXX SERVITUDE
            $sql1 ="update ".DB_PREFIXE."dossier set servitude = '".$temp."' where dossier = '".$id."'";
            $res1 = $db -> query($sql1);
            // XXX SERVITUDE
            $this->addToLog("maj servitudes :".$sql1, VERBOSE_MODE);
            if (database:: isError($res1)) die($res1->getMessage()."erreur ".$sql1);
        }else{ // parcelle inexistante //***
            if($this->maj ==1){ // en maj mettre a null la geometrie si parcelle changée inexistante
                // XXX SERVITUDE
                $sql ="update ".DB_PREFIXE."dossier set geom = null, servitude = '', pos= '' where dossier ='".$id."'";
                $res = $db -> query($sql);
                $this->addToLog("requete sig_interne maj parcelle inexistante :".$sql, VERBOSE_MODE);
                if (database :: isError($res))
                    die($res->getMessage()."erreur ".$sql);
            }
            //$this->addToMessage("<br> parcelle ".$parcelle." "._("inexistante")." ".$id."");
        }
    }

    function calcul_auto_pos($id,&$db,$geom,$projection){
        // recherche du pos automatique 
        $sql="select pos from ".DB_PREFIXE."pos  WHERE ST_contains(geom,  geometryfromtext('".$geom."', ".$projection."))";
        $pos = $db -> getOne($sql);
        $this->addToLog("recherche auto_pos :".$sql, VERBOSE_MODE);
        if($pos!=''){
            $sql1 ="update ".DB_PREFIXE."dossier set pos = '".$pos."' where dossier = '".$id."'";
            $res1 = $db -> query($sql1);
            $this->addToLog("maj auto_pos :".$sql1, VERBOSE_MODE);
            if (database:: isError($res1)) die($res1->getMessage()."erreur ".$sql1);
            $this->addToMessage("<br>"._("POS/PLU")." : ".$pos."");
        }else{
            $this->addToMessage("<br>"._("POS/PLU non trouve")." ".$id.""); 
        }
    }

    function calcul_auto_servitude_surfacique($id,&$db,$geom,$projection){
        // recherche servitude surfacique
        $sql="select * from ".DB_PREFIXE."servitude_surfacique WHERE ST_contains(geom,  geometryfromtext('".$geom."', ".$projection."))";
        $res=$db->query($sql);
        if (database:: isError($res)) die($res1->getMessage()."erreur ".$sql);
        $this->addToLog("requete  :".$sql." executee ", VERBOSE_MODE);
        while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)){
            // XXX SERVITUDE
            $this->addToMessage("<br>"._("servitude")." : ".$row['libelle']." - ".$row['observation']);
            $this->servitude.="  [".$row['libelle']."] ".$row['observation']." - ";
       }
    }

    function calcul_auto_servitude_ligne($id,&$db,$geom,$projection){
        // recherche servitude ligne
        $sql="select * from ".DB_PREFIXE."servitude_ligne WHERE ST_contains(ST_buffer(geom, perimetre),  geometryfromtext('".$geom."', ".$projection."))";
        $res=$db->query($sql);
        if (database:: isError($res)) die($res1->getMessage()."erreur ".$sql);
        $this->addToLog("requete  :".$sql." executee ", VERBOSE_MODE);
        while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)){
            // XXX SERVITUDE
            $this->addToMessage("<br>"._("contraintes")." : ".$row['libelle']." - ".$row['observation']);
            $this->servitude.="  [".$row['libelle']."] ".$row['observation']." - ";
       }
    }

    function calcul_auto_servitude_point($id,&$db,$geom,$projection){
        // recherche servitude point
        $sql="select libelle,observation, perimetre, distance(geom, geometryfromtext('".$geom."', ".$projection.")) as distance from ".
            DB_PREFIXE."servitude_point WHERE distance(geom,  geometryfromtext('".$geom."', ".$projection."))<perimetre";
        $res=$db->query($sql);
        if (database:: isError($res)) die($res1->getMessage()."erreur ".$sql);
        $this->addToLog("requete  :".$sql." executee ", VERBOSE_MODE);
        while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)){
            $this->addToMessage("<br>"._("contraintes")." : ".$row['libelle']." - ".$row['observation']." a ".round($row['distance'],2)." m ");
            // XXX SERVITUDE
            $this->servitude.="  [".$row['libelle']."] ".$row['observation']." a ".round($row['distance'],2)." m - ";
       }
    }

    /**
     * Gestion des liens entre la demande et les demandeurs recemment ajoutés
     **/
    function insertLinkDemandeDemandeur($db, $DEBUG) {
        //
        require_once "../obj/lien_dossier_demandeur.class.php";
        // Sippression des anciens demandeurs
        $this->deleteLinkDossierDemandeur($db, $DEBUG);

        // Ajout du pétitionnaire principal
        if(!empty($this->postedIdDemandeur['petitionnaire_principal'])) {
            $this->addLinkDossierDemandeur($this->postedIdDemandeur['petitionnaire_principal'], true, $db, $DEBUG);
        }

        // Ajout du délégataire
        if(!empty($this->postedIdDemandeur['delegataire'])) {
            $this->addLinkDossierDemandeur($this->postedIdDemandeur['delegataire'], false, $db, $DEBUG);
        }

        // Ajout des pétitionnaires
        if(isset($this->postedIdDemandeur['petitionnaire'])) {
            // Ajout des nouveaux liens
            foreach ($this->postedIdDemandeur['petitionnaire'] as $petitionnaire) {
                $this->addLinkDossierDemandeur($petitionnaire, false, $db, $DEBUG);
            }
        }
    }


    /**
     * Fonction permettant d'ajouter un lien
     * entre la table demande et demandeur
     **/
    function addLinkDossierDemandeur($id, $principal, $db, $DEBUG) {
        $lienAjout = new lien_dossier_demandeur(
                                        "]",
                                        $db,
                                        $DEBUG);
        $lien = array('lien_dossier_demandeur' => "",
                           'petitionnaire_principal' => (($principal)?"t":"f"),
                           'dossier' => $this->valF['dossier'],
                           'demandeur' => $id);
        $lienAjout->ajouter($lien, $db, $DEBUG);
        $lienAjout->__destruct();
    }

    /**
     * Fonction permettant de supprimer un lien
     * entre la table demande et demandeur
     **/
    function deleteLinkDossierDemandeur($db, $DEBUG) {
        // Suppression
        $sql = "DELETE FROM ".DB_PREFIXE."lien_dossier_demandeur ".
                "WHERE dossier='".$this->valF['dossier']."'";
        // Execution de la requete de suppression de l'objet
        $res = $db->query($sql);
        // Logger
        $this->f->addToLog("supprimer(): db->query(\"".$sql."\");", VERBOSE_MODE);
        if ( database::isError($res)){
            die();
        }

    }

    /**
     * Methode de recupération des valeurs postées
     **/
    function getPostedValues() {
        // Récupération des demandeurs dans POST
        if ($this->f->get_submitted_post_value('petitionnaire_principal') !== null OR 
                $this->f->get_submitted_post_value('delegataire') !== null OR 
                    $this->f->get_submitted_post_value('petitionnaire') !== null) {
            if($this->f->get_submitted_post_value('petitionnaire_principal') !== null AND
                    $this->f->get_submitted_post_value('petitionnaire_principal') != '') {
                $this->postedIdDemandeur['petitionnaire_principal'] = $this->f->get_submitted_post_value('petitionnaire_principal');
            }
            if($this->f->get_submitted_post_value('delegataire') !== null AND
                    $this->f->get_submitted_post_value('delegataire') != '') {
                $this->postedIdDemandeur['delegataire'] = $this->f->get_submitted_post_value('delegataire');
            }
            if($this->f->get_submitted_post_value('petitionnaire') !== null AND
                    $this->f->get_submitted_post_value('petitionnaire') != '') {
                $this->postedIdDemandeur['petitionnaire'] = $this->f->get_submitted_post_value('petitionnaire');
            }
        }
    }

    /**
     * Méthode permettant de récupérer les id des demandeurs liés à la table
     * liée passée en paramètre
     *
     * @param string $from Table liée : "demande", "dossier", dossier_autorisation"
     * @param string $id Identifiant (clé primaire de la table liée en question)
     */
    function listeDemandeur($from, $id) {
        // Récupération des demandeurs de la base
        $sql = "SELECT demandeur.demandeur,
                        demandeur.type_demandeur,
                        lien_".$from."_demandeur.petitionnaire_principal
            FROM ".DB_PREFIXE."lien_".$from."_demandeur
            INNER JOIN ".DB_PREFIXE."demandeur 
            ON demandeur.demandeur=lien_".$from."_demandeur.demandeur 
            WHERE ".$from." = '".$id."'";
        $res = $this->f->db->query($sql);
        $this->f->addToLog("listeDemandeur(): db->query(\"".$sql."\")", VERBOSE_MODE);
        if ( database::isError($res)){
            die();
        }
        // Stockage du résultat dans un tableau
        while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)){
            if ($row['petitionnaire_principal'] == 't' AND
                $row['type_demandeur']=="petitionnaire") {
                $this->valIdDemandeur['petitionnaire_principal']=$row['demandeur'];
            } elseif ($row['petitionnaire_principal'] == 'f' AND
                $row['type_demandeur']=="petitionnaire"){
                $this->valIdDemandeur['petitionnaire'][]=$row['demandeur'];
            } elseif ($row['type_demandeur']=="delegataire"){
                $this->valIdDemandeur['delegataire']=$row['demandeur'];
            }
        }
    }

    /**
     * Récupère la liste des contraintes d'un dossier.
     * @param string $dossier Identifiant du dossier
     * 
     * @return object          Résultat de la requête
     */
    function getListContrainte($dossier) {

        // Select
        $select = "SELECT dossier_contrainte.dossier_contrainte as dossier_contrainte_id,
                    dossier_contrainte.texte_complete as dossier_contrainte_texte,
                    dossier_contrainte.reference as dossier_contrainte_reference,
                    contrainte.libelle as contrainte_libelle,
                    contrainte.nature as contrainte_nature,
                    contrainte.texte as contrainte_texte,
                    contrainte.reference as contrainte_reference,
                    lower(contrainte.groupe) as contrainte_groupe,
                    lower(contrainte.sousgroupe) as contrainte_sousgroupe ";

        // From
        $from = " FROM ".DB_PREFIXE."contrainte 
                    LEFT JOIN ".DB_PREFIXE."dossier_contrainte
                        ON  dossier_contrainte.contrainte = contrainte.contrainte ";

        // Where
        $where = " WHERE dossier_contrainte.dossier = '".$dossier."' ";

        // Si le paramètre "option_contrainte_di" est définit
        if ($this->f->getParameter('option_contrainte_di') != 'aucun') {
            // Ajoute la condition
            $where .= $this->f->traitement_condition_contrainte(
                $this->f->getParameter('option_contrainte_di'));
        }

        // Tri
        $tri = " ORDER BY contrainte_groupe DESC, contrainte_sousgroupe, 
                    contrainte.no_ordre, contrainte.libelle ";

        // Requête SQL
        $sql = $select.$from.$where.$tri;
        $res = $this->f->db->query($sql);
        $this->f->addToLog("listContrainte(): db->query(\"".$sql."\");", VERBOSE_MODE);
        $this->f->isDatabaseError($res);

        // Retourne le résultat
        return $res;
    }

    /**
     * Ajout de la liste des contraintes et des demandeurs
     */
    function formSpecificContent($maj) {

        /**
         * Liste des contraintes
         */
        //
        $listContrainte = $this->getListContrainte($this->getVal('dossier'));

        // Si le dossier possède des contraintes
        if ($listContrainte->numRows() != 0) {

            // Affiche du fieldset
            printf("<div id=\"liste_contrainte\" class=\"demande_hidden_bloc\">");
            printf("<fieldset class=\"cadre ui-corner-all ui-widget-content col_12 startClosed\">");
            printf("  <legend class=\"ui-corner-all ui-widget-content ui-state-active\"
                    id =\"fieldset_contraintes_liees\">"
                    ._("dossier_contrainte")."</legend>");
            printf("<div class=\"fieldsetContent\" style=\"display: none;\">");

            // Entête pour le groupe
            $groupeHeader = "
            <div class='dossier_contrainte_groupe'>
                <div class='dossier_contrainte_groupe_header'>
                    <span class='name'>
                        %s
                    </span>
                </div>
            ";

            // Entête pour le sous-groupe
            $sousgroupeHeader = "
            <div class='dossier_contrainte_sousgroupe'>
                <div class='dossier_contrainte_sousgroupe_header'>
                    <span class='name'>
                        %s
                    </span>
                </div>
            ";

            // Titres des colonnes
            $tableHeader = "
            <thead>
                <tr class='ui-tabs-nav ui-accordion ui-state-default tab-title'>
                    <th class='title col-0 firstcol contrainte_th_texte_complete'>
                        <span class='name'>
                            "._('texte_complete')."
                        </span>
                    </th>
                    <th class='title col-1 contrainte_th_reference'>
                        <span class='name'>
                            "._('reference')."
                        </span>
                    </th>
                    <th class='title col-2 contrainte_th_nature'>
                        <span class='name'>
                            "._('nature')."
                        </span>
                    </th>
                </tr>
            </thead>
            ";

            // Ligne de données
            $line = "
            <tr class='tab-data %s'>
                <td class='col-0 firstcol contrainte_th_texte_complete'>
                    %s
                </td>
                <td class='col-1 contrainte_th_reference'>
                    %s
                </td>
                <td class='col-2 contrainte_th_nature'>
                    %s
                </td>
            ";

            // Sauvegarde des données pour les comparer
            $lastRow = array();
            $lastRow['contrainte_groupe'] = 'empty';
            $lastRow['contrainte_sousgroupe'] = 'empty';

            // Tant qu'il y a des résultats
            while($row = &$listContrainte->fetchRow(DB_FETCHMODE_ASSOC)) {
                // Si l'identifiant du groupe de la contrainte présente et 
                // celle d'avant est différent
                if ($row['contrainte_groupe'] != $lastRow['contrainte_groupe']) {

                    // Si l'identifiant du groupe d'avant est vide
                    if ($lastRow['contrainte_groupe'] != 'empty') {
                        // Ferme le tableau
                        printf("</table>");
                        // Ferme le div
                        printf("</div>");
                        // Ferme le div
                        printf("</div>");
                    }

                    // Affiche le header du groupe
                    printf($groupeHeader, $row['contrainte_groupe']);
                }

                // Si l'identifiant du sous-groupe de la contrainte présente et 
                // celle d'avant est différent
                // Ou qu'ils soient identique mais n'appartiennent pas au même groupe
                if ($row['contrainte_sousgroupe'] != $lastRow['contrainte_sousgroupe']
                    || ($row['contrainte_sousgroupe'] == $lastRow['contrainte_sousgroupe']
                        && $row['contrainte_groupe'] != $lastRow['contrainte_groupe'])) {

                    //
                    if($row['contrainte_groupe'] == $lastRow['contrainte_groupe']) {
                        // Si l'identifiant de la sous-groupe d'avant est vide
                        if ($lastRow['contrainte_sousgroupe'] != 'empty') {
                            // Ferme le tableau
                            printf("</table>");
                            // Ferme le div
                            printf("</div>");
                        }
                    }

                    // Affiche le header du sous-groupe
                    printf($sousgroupeHeader, $row['contrainte_sousgroupe']);

                    // Ouvre le tableau
                    printf("<table id='sousgroupe_".$row['contrainte_sousgroupe']."' class='tab-tab dossier_contrainte_view'>");

                    // Affiche le header des données
                    printf($tableHeader);

                    // Définis le style des lignes
                    $style = 'odd';
                }

                // Si toujours dans la même groupe et même sous-groupe, 
                // on change le style de la ligne
                if ($row['contrainte_groupe'] == $lastRow['contrainte_groupe']
                    && $row['contrainte_sousgroupe'] == $lastRow['contrainte_sousgroupe']) {
                    // Définis le style
                    $style = ($style=='even')?'odd':'even';
                }
                
                // Affiche "Oui" ou "Non" pour le bouléen
                if ($row['dossier_contrainte_reference'] == 1 
                    || $row['dossier_contrainte_reference'] == "t"
                    || $row['dossier_contrainte_reference'] == "Oui") {
                    //
                    $contrainte_reference = "Oui";
                } else {
                    //
                    $contrainte_reference = "Non";
                }

                // Affiche les données
                printf($line, $style, 
                    $row['dossier_contrainte_texte'], 
                    $contrainte_reference,
                    $row['contrainte_nature']
                );

                // Sauvegarde les données
                $lastRow['contrainte_groupe'] = $row['contrainte_groupe'];
                $lastRow['contrainte_sousgroupe'] = $row['contrainte_sousgroupe'];
                
            }
            // Ferme le tableau
            printf("</table>");
            // Ferme le sous-groupe
            printf("</div>");
            // Ferme le groupe
            printf("</div>");

            printf("</div>");

            printf("<div class=\"visualClear\"></div>");            
            // Ferme le fieldset content
            printf("</div>");
            printf("</fieldset>");
        } 
        /**
         * Fin Liste des contraintes
         */

        /**
         * Liste des demandeurs
         */
        $this->listeDemandeur("dossier", $this->getVal('dossier'));

        if($maj < 2 AND !$this->correct) {
            $linkable = true;
        } else {
            $linkable = false;
        }

        // Conteneur de la listes des demandeurs
        echo "<div id=\"liste_demandeur\" class=\"demande_hidden_bloc col_12\">";
        echo "<fieldset class=\"cadre ui-corner-all ui-widget-content startClosed\">";
        echo "  <legend class=\"ui-corner-all ui-widget-content ui-state-active\">"
                ._("Petitionnaire")."</legend>";
        // Si des demandeurs sont liés à la demande
        require_once "../obj/petitionnaire.class.php";
        require_once "../obj/delegataire.class.php";
        // Affichage du bloc pétitionnaire principal / délégataire
        // L'ID DU DIV SUIVANT EST NECESSAIRE AU BON FONCTIONNEMENT DU JS
        echo "<div id=\"petitionnaire_principal_delegataire col_12\">";
        // Affichage de la synthèse
        if (isset ($this->valIdDemandeur["petitionnaire_principal"]) AND
            !empty($this->valIdDemandeur["petitionnaire_principal"])) {
            $demandeur = new petitionnaire(
                                $this->valIdDemandeur["petitionnaire_principal"],
                                $this->f->db,false);
            $demandeur -> afficherSynthese("petitionnaire_principal", $linkable);
            $demandeur -> __destruct();
        } elseif ( isset ($this->postedIdDemandeur["petitionnaire_principal"]) AND
            !empty($this->postedIdDemandeur["petitionnaire_principal"]) ) {
            $demandeur = new petitionnaire(
                                $this->postedIdDemandeur["petitionnaire_principal"],
                                $this->f->db,false);
            $demandeur -> afficherSynthese("petitionnaire_principal", $linkable);
            $demandeur -> __destruct();
        }
        // Si en édition de formulaire
        if($maj < 2 AND $linkable) {
            // Bouton d'ajout du pétitionnaire principal
            // L'ID DE L'INPUT SUIVANT EST NECESSAIRE AU BON FONCTIONNEMENT DU JS
            echo "<span id=\"add_petitionnaire_principal\"
                class=\"om-form-button add-16\">".
                _("Saisir le petitionnaire principal").
            "</span>";
        }
        // Bouton d'ajout du delegataire
        // L'ID DU DIV ET DE L'INPUT SUIVANT EST NECESSAIRE AU BON FONCTIONNEMENT DU JS
        echo "<div id=\"delegataire\">";
        // Affichage de la synthèse
        if (isset ($this->valIdDemandeur["delegataire"]) AND
            !empty($this->valIdDemandeur["delegataire"])) {
            $demandeur = new delegataire($this->valIdDemandeur["delegataire"],
                                       $this->f->db,false);
            $demandeur -> afficherSynthese("delegataire", $linkable);
            $demandeur -> __destruct();
        } elseif ( isset ($this->postedIdDemandeur["delegataire"]) AND
        !empty($this->postedIdDemandeur["delegataire"]) ) {

            $demandeur = new delegataire($this->postedIdDemandeur["delegataire"],
                                       $this->f->db,false);
            $demandeur -> afficherSynthese("delegataire", $linkable);
            $demandeur -> __destruct();
        }
        if($maj < 2 AND $linkable) {
            echo "<span id=\"add_delegataire\"
                    class=\"om-form-button add-16\">".
                    _("Saisir un autre correspondant").
                "</span>";
        }
        echo "</div>";
        echo "<div class=\"both\"></div>";
        echo "</div>";
        // Bloc des pétitionnaires secondaires
        // L'ID DU DIV SUIVANT EST NECESSAIRE AU BON FONCTIONNEMENT DU JS
        echo "<div id=\"listePetitionnaires col_12\">";

         // Affichage de la synthèse
        if (isset ($this->valIdDemandeur["petitionnaire"]) AND
            !empty($this->valIdDemandeur["petitionnaire"])) {
            
            foreach ($this->valIdDemandeur["petitionnaire"] as $petitionnaire) {
                $demandeur = new petitionnaire($petitionnaire,
                                       $this->f->db,false);
                $demandeur -> afficherSynthese("petitionnaire", $linkable);
                $demandeur -> __destruct();
            }
            
        } elseif ( isset ($this->postedIdDemandeur["petitionnaire"]) AND
            !empty($this->postedIdDemandeur["petitionnaire"]) )  {
            foreach ($this->postedIdDemandeur["petitionnaire"] as $petitionnaire) {
                $demandeur = new petitionnaire($petitionnaire,
                                       $this->f->db,false);
                $demandeur -> afficherSynthese("petitionnaire", $linkable);
                $demandeur -> __destruct();
            }
        }
        if ($maj < 2 AND $linkable) {
            // L'ID DE L'INPUT SUIVANT EST NECESSAIRE AU BON FONCTIONNEMENT DU JS
            echo "<span id=\"add_petitionnaire\"
                    class=\"om-form-button add-16\">".
                    _("Ajouter un petitionnaire")
                ."</span>";
        }
        echo "</div>";
        echo "</fieldset>";
        echo "</div>";
        /**
         * Fin liste des demandeurs
         */
    }

    /**
     * Retourne le statut du dossier
     * @return string Le statut du dossier d'instruction
     */
    function getStatut(){
        
        $statut = '';
        
        $etat = $this->getVal("etat");
        //Si l'état du dossier d'instruction n'est pas vide
        if ( $etat != '' ){
            
            $sql = "SELECT statut
                FROM ".DB_PREFIXE."etat
                WHERE libelle ='".$etat."'";
            $statut = $this->db->getOne($sql);
            $this->f->addToLog("getStatut() : db->getOne(\"".$sql."\")", VERBOSE_MODE);
            if ( database::isError($statut, true)){
                die();
            }
        }
        return $statut;
    }
    
    /**
     * Retourne l'identifiant du rapport d'instruction lié du dossier
     * @return string L'identifiant du rapport d'instruction lié du dossier
     */
    function getRapportInstruction(){
        
        $rapport_instruction = '';

        $sql = "SELECT rapport_instruction
            FROM ".DB_PREFIXE."rapport_instruction
            WHERE dossier_instruction ='".$this->getVal($this->clePrimaire)."'";
        $rapport_instruction = $this->db->getOne($sql);
        $this->f->addToLog("getStatut() : db->getOne(\"".$sql."\")", VERBOSE_MODE);
        if ( database::isError($rapport_instruction)){
            die();
        }

        return $rapport_instruction;
    }
    
    /**
     * Retourne l'identifiant des données techniques liées du dossier
     * @return string L'identifiant des données techniques liées du dossier
     */
    function getDonneesTechniques(){
        
        $donnees_techniques = '';

        $sql = "SELECT donnees_techniques
            FROM ".DB_PREFIXE."donnees_techniques
            WHERE dossier_instruction ='".$this->getVal($this->clePrimaire)."'";
        $donnees_techniques = $this->db->getOne($sql);
        $this->f->addToLog("getStatut() : db->getOne(\"".$sql."\")", VERBOSE_MODE);
        if ( database::isError($donnees_techniques)){
            die();
        }

        return $donnees_techniques;
    }

    /**
     * Surcharge du bouton retour afin de retourner sur la recherche de dossiers
     * d'instruction existant
     */
    function retour($premier = 0, $recherche = "", $tricol = "") {

        echo "\n<a class=\"retour\" ";
        echo "href=\"";
        //
        if($this->getParameter("idx_dossier") != "") {
            echo "tab.php?";
            echo "obj=recherche_dossier";

        } else {
            if($this->getParameter("retour")=="form" AND !($this->getParameter("validation")>0 AND $this->getParameter("maj")==2 AND $this->correct)) {
                echo "form.php?";
            } else {
                echo "tab.php?";
            }
            // Permet de retourner sur la bonne page
            if ($this->f->get_submitted_get_value('retourformulaire') !== null && $this->f->get_submitted_get_value('retourformulaire') != '') {
                echo "obj=".$this->f->get_submitted_get_value('retourformulaire');
            } else {
                echo "obj=".get_class($this);
            }
            if ($this->f->get_submitted_get_value('retourformulaire2') !== null && $this->f->get_submitted_get_value('retourformulaire2') != '') {
                echo "&retourformulaire=".$this->f->get_submitted_get_value('retourformulaire2');
            }
            if($this->getParameter("retour")=="form") {
                echo "&amp;idx=".$this->getParameter("idx");
                echo "&amp;idz=".$this->getParameter("idz");
                echo "&amp;action=3";
            }
        }
        echo "&amp;premier=".$this->getParameter("premier");
        echo "&amp;tricol=".$this->getParameter("tricol");
        echo "&amp;recherche=".$this->getParameter("recherche");
        echo "&amp;selectioncol=".$this->getParameter("selectioncol");
        echo "&amp;advs_id=".$this->getParameter("advs_id");
        echo "&amp;valide=".$this->getParameter("valide");
        //
        echo "\"";
        echo ">";
        //
        echo _("Retour");
        //
        echo "</a>\n";

    }

    /**
     * Permet de modifier le fil d'Ariane
     * @param string $ent Fil d'Ariane
     * @param array  $val Valeurs de l'objet
     * @param intger $maj Mode du formulaire
     */
    function getFormTitle($ent) {

        // Fil d'Ariane
        $ent = _("instruction")." -> "._("dossiers d'instruction");

        // Si différent de l'ajout
        if($this->getParameter("maj") != 0) {
            // Si le champ dossier_libelle existe
            if (trim($this->getVal("dossier_libelle")) != '') {
                $ent .= " -> ".strtoupper($this->getVal("dossier_libelle"));
            }
            // Si le champ dossier existe
            if (trim($this->getVal("dossier")) != '') {
                $demandeur = $this->get_demandeur($this->getVal("dossier"));
                // Si le demandeur existe
                if (isset($demandeur) && trim($demandeur) != '') {
                    $ent .= " ".mb_strtoupper($demandeur, "UTF-8");
                }
            }
        }

        // Change le fil d'Ariane
        return $ent;
    }

    /**
     * Récupère le demandeur du dossier
     * @return string Identifiant du dossier
     */
    private function get_demandeur($dossier) {

        // init de la variable de retour
        $demandeur = '';

        // Requête SQL
        $sql = "SELECT 
                    CASE WHEN demandeur.qualite='particulier' 
                        THEN TRIM(CONCAT(demandeur.particulier_nom, ' ', demandeur.particulier_prenom)) 
                        ELSE TRIM(CONCAT(demandeur.personne_morale_raison_sociale, ' ', demandeur.personne_morale_denomination)) 
                    END as demandeur
                FROM ".DB_PREFIXE."dossier
                    LEFT JOIN ".DB_PREFIXE."lien_dossier_demandeur 
                            ON lien_dossier_demandeur.dossier=dossier.dossier
                                AND lien_dossier_demandeur.petitionnaire_principal IS TRUE
                    LEFT JOIN ".DB_PREFIXE."demandeur
                        ON lien_dossier_demandeur.demandeur=demandeur.demandeur
            WHERE dossier.dossier ='".$dossier."'";
        $demandeur = $this->db->getOne($sql);
        $this->f->addToLog("get_demandeur() : db->getOne(\"".$sql."\")", VERBOSE_MODE);
        database::isError($demandeur);

        // Résultat retourné
        return $demandeur;
    }

    /**
     * Récupère la durée de validité
     * @param  string $dossier_autorisation Identifiant dossier d'autorisation
     * @return intger                       Durée de validité
     */
    function get_duree_validite($dossier_autorisation) {

        // init de la variable de retour
        $duree_validite = "";

        // Récupère le numéro de version
        $numeroVersion = $this->getNumeroVersion($dossier_autorisation);

        // Si c'est l'ajout du dossier initial
        if ($numeroVersion < 0) {

            // Récupération de la duree de validite depuis la table 
            // "dossier_autorisation_type_detaille"
            $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
                    WHERE dossier_autorisation.dossier_autorisation='".$dossier_autorisation."'";
            $duree_validite = $this->db->getOne($sql);
            $this->f->addToLog("get_duree_validite(): db->getOne(\"".$sql."\");", VERBOSE_MODE);
            database::isError($duree_validite);

        } else {

            // Récupération de la duree de validite depuis le P0
            $sql = "SELECT duree_validite
                    FROM ".DB_PREFIXE."dossier
                    LEFT JOIN ".DB_PREFIXE."dossier_autorisation
                        ON dossier_autorisation.dossier_autorisation = dossier.dossier_autorisation
                    WHERE dossier_autorisation.dossier_autorisation='".$dossier_autorisation."'
                    AND dossier.version = 0";
            $duree_validite = $this->db->getOne($sql);
            $this->f->addToLog("get_duree_validite(): db->getOne(\"".$sql."\");", VERBOSE_MODE);
            database::isError($duree_validite);
        }

        // retourne le résultat
        return $duree_validite;

    }

    /**
     * Ajoute les parcelles du dossier passé en paramètre et met à jour le 
     * quartier du dossier.
     * @param string $dossier                        Identifiant du dossier
     * @param string $terrain_references_cadastrales Références cadastrales du 
     *                                                dossier
     */
    function ajouter_dossier_parcelle($dossier, $terrain_references_cadastrales) {

        // Parse les parcelles
        $list_parcelles = $this->f->parseParcelles($terrain_references_cadastrales);

        // Fichier requis
        require_once "../obj/dossier_parcelle.class.php";

        // A chaque parcelle une nouvelle ligne est créée dans la table
        // dossier_parcelle
        foreach ($list_parcelles as $parcelle) {

            // Instance de la classe dossier_parcelle
            $dossier_parcelle = new dossier_parcelle("]", $this->db, DEBUG);

            // Valeurs à sauvegarder
            $value = array(
                'dossier_parcelle' => '',
                'dossier' => $dossier,
                'parcelle' => '',
                'libelle' => $parcelle['quartier']
                                .$parcelle['section']
                                .$parcelle['parcelle']
            );

            // Ajout de la ligne
            $dossier_parcelle->ajouter($value, $this->db, DEBUG);
        }

        // Si la liste des parcelles n'est pas vide
        if (count($list_parcelles) > 0) {

            // Récupère le code impôt de la première référence cadastrale
            $quartier_code_impots = $list_parcelles[0]['quartier'];
            // Récupère l'identifiant du quartier
            $quartier = $this->get_quartier_by_code_impot($quartier_code_impots);

            // Ajoute le quartier au dossier
            $this->modifier_quartier_dossier($dossier, $quartier);
        }
    }

    /**
     * Supprime les parcelles du dossier passé en paramètre et met à jour le 
     * quartier du dossier.
     * @param string $dossier Identifiant du dossier
     */
    function supprimer_dossier_parcelle($dossier) {

        // Suppression des parcelles du dossier
        $sql = "DELETE FROM ".DB_PREFIXE."dossier_parcelle
                WHERE dossier='".$dossier."'";
        $res = $this->db->query($sql);
        $this->addToLog("supprimer_dossier_parcelle() db->query(\"".$sql."\");",
            VERBOSE_MODE);
        database::isError($res);

        // Supprime le quartier dans dossier
        $this->modifier_quartier_dossier($dossier);
    }

    /**
     * Modifie le quartier au dossier.
     * @param string  $dossier  Numéro du dossier
     * @param integer $quartier Identifiant du quartier
     */
    function modifier_quartier_dossier($dossier, $quartier = null) {

        // Valeurs à mettre à jour
        $valF = array();
        $valF['quartier'] = $quartier;

        // Met à jour le quartier du dossier
        $cle = " dossier='".$dossier."'";
        $res = $this->db->autoExecute(
            DB_PREFIXE.'dossier', $valF, DB_AUTOQUERY_UPDATE, $cle);
        $this->addToLog("ajouter_quartier_dossier(): db->autoexecute(\""
            .DB_PREFIXE."dossier\", ".print_r($valF, true)
            .", DB_AUTOQUERY_UPDATE, \"".$cle."\");", VERBOSE_MODE);
        $this->f->isDatabaseError($res);
    }

    /**
     * Récupère le quartier par rapport au code impôts.
     * @param string $code_impots Code impôts du quartier
     * 
     * @return integer            Identifiant du quartier
     */
    function get_quartier_by_code_impot($code_impots) {

        // Initialisation résultat
        $quartier = null;

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

            // Requête SQL
            $sql = "SELECT quartier
                    FROM ".DB_PREFIXE."quartier
                    WHERE code_impots = '".$code_impots."'";
            $this->f->addToLog(
                "get_quartier_by_code_impots() : db->getOne(\"".$sql."\")", 
                VERBOSE_MODE);
            $quartier = $this->db->getOne($sql);
            $this->f->isDatabaseError($quartier);
        }

        // Retourne résultat
        return $quartier;
    }
    
    /**
     * Méthode permettant d'ajouter les données techniques d'un DI.
     *
     * @param integer  $id    identifiant de la demande
     * @param database &$db   handler de la base de donnée
     * @param array    $val   tableau de valeurs postées via le formulaire
     * @param boolean  $DEBUG debug
     *
     * @return boolean false si erreur
     */
    function ajoutDonneesTechniquesDI($id, &$db, $val, $DEBUG) {

        //On vérifie que le dossier d'autorisation a des données techniques
        $sql = "SELECT * "
            ."FROM ".DB_PREFIXE."donnees_techniques "
            ."WHERE dossier_autorisation = '".$this->valF["dossier_autorisation"]."'";
        $dtda = $this->db->query($sql);
        $this->addToLog(__METHOD__."(): db->query(\"".$sql."\")", VERBOSE_MODE);
        if($this->f->isDatabaseError($dtda, true)){
            $this->f->addToLog(__METHOD__."() : ERROR - Erreur de base de données. Impossible d'ajouter les données techniques du dossier d'instruction.", DEBUG_MODE);
            return false;
        }
        
        //Si le dossier d'autorisation a des données techniques
        if ( $dtda->numrows() == 1 ){
            //
            require_once '../obj/donnees_techniques.class.php';
            $dtdi = new donnees_techniques(']', $db, $DEBUG);
            //Préparation des données
            $valF = $dtda->fetchRow(DB_FETCHMODE_ASSOC);
            //Suppression de l'identifiant
            $valF["donnees_techniques"] = null;
            // Ajout du numéro de dossier d'instruction
            $valF['dossier_instruction'] = $this->valF['dossier'];
            // Suppression du numéro de dossier d'autorisation
            $valF['dossier_autorisation'] = null;
            // Ajout des données techniques
            if($dtdi->ajouter($valF, $db, $DEBUG) === false) {
                $this->f->addToLog(__METHOD__."() : ERROR - Impossible d'ajouter les données techniques du dossier d'instruction.", DEBUG_MODE);
                return false;
            }
        }
        else {
            //Le dossier d'autorisation n'a pas de données techniques
            $this->f->addToLog(__METHOD__."() : ERROR - le DA n'a pas de données techniques.", DEBUG_MODE);
            return -1;
        }

        //
        return true;
    }

    /**
     * VIEW - contrainte.
     *
     * Vue des contraintes du dossier
     *
     * Cette vue permet de gérer le contenu de l'onglet "Contrainte(s)" sur un 
     * dossier. Cette vue spécifique est nécessaire car l'ergonomie standard du
     * framework ne prend pas en charge ce cas.
     * C'est ici la vue spécifique des contraintes liées au dossier qui est
     * affichée directement au clic de l'onglet au lieu du soustab.
     * 
     * L'idée est donc de simuler l'ergonomie standard en créant un container 
     * et d'appeler la méthode javascript 'ajaxit' pour charger le contenu 
     * de la vue visualisation de l'objet lié.
     * 
     * @return void
     */
    function view_contrainte() {
        // Vérification de l'accessibilité sur l'élément
        $this->checkAccessibility();
        // Récupération des variables GET
        ($this->f->get_submitted_get_value('idxformulaire')!==null ? $idxformulaire = 
            $this->f->get_submitted_get_value('idxformulaire') : $idxformulaire = "");
        ($this->f->get_submitted_get_value('retourformulaire')!==null ? $retourformulaire = 
            $this->f->get_submitted_get_value('retourformulaire') : $retourformulaire = "");
        // Objet à charger
        $obj = "dossier_contrainte";
        // Construction de l'url de sousformulaire à appeler
        $url = "../scr/sousform.php?obj=".$obj;
        $url .= "&idx=".$idxformulaire;
        $url .= "&action=4";
        $url .= "&retourformulaire=".$retourformulaire;
        $url .= "&idxformulaire=".$idxformulaire;
        $url .= "&retour=form";
        // Affichage du container permettant le reffraichissement du contenu
        // dans le cas des action-direct.
        printf('
            <div id="sousform-href" data-href="%s">
            </div>',
            $url
        );
        // Affichage du container permettant de charger le retour de la requête
        // ajax récupérant le sous formulaire.
        printf('
            <div id="sousform-%s">
            </div>
            <script>
            ajaxIt(\'%s\', \'%s\');
            </script>',
            $obj,
            $obj,
            $url
        );
    }

    /**
     * Cette methode permet d'afficher le bouton de validation du formulaire
     *
     * @param integer $maj Mode de mise a jour
     * @return void
     */
    function bouton($maj) {
        
        if (!$this->correct
            && $this->checkActionAvailability() == true) {
            //
            switch($maj) {
                case 0 :
                    $bouton = _("Ajouter");
                    break;
                case 1 :
                    $bouton = _("Modifier");
                    break;
                case 2 :
                    $bouton = _("Supprimer");
                    break;
                default :
                    // Actions specifiques
                    if ($this->get_action_param($maj, "button") != null) {
                        //
                        $bouton = $this->get_action_param($maj, "button");
                    } else {
                        //
                        $bouton = _("Valider");
                    }
                    break;
            }
            //
            $params = array(
                "value" => $bouton,
                "name" => "submit",
                "onclick"=>"return getDataFieldReferenceCadastrale();",
            );
            //
            $this->f->layout->display_form_button($params);
        }

    }
    
}// fin classe
?>