<?php
/**
 * Ce script définit la classe 'emplacement'.
 *
 * @package opencimetiere
 * @version SVN : $Id$
 */

require_once "../gen/obj/emplacement.class.php";
require_once dirname(__DIR__)."/vendor/autoload.php";

/**
 * Définition de la classe 'emplacement' (om_dbform).
 *
 * classe contenant les elements de localisation + champ famille
 * heritage
 *  emplacement -> concession -> colombarium
 *                            -> terraincommunal
 *                            -> enfeu
 *              -> ossuaire   -> depositoire
 */
class emplacement extends emplacement_gen {

    function get_collectivite() {
        if ($this->exists()!== true) {
            return -1;
        }
        return $this->getVal("om_collectivite");
    }

    /**
     * Définition des actions disponibles sur la classe.
     *
     * @return void
     */
    function init_class_actions() {
        parent::init_class_actions();
        //ACTION 003 - View consulter
        //
        $this->class_actions[3]['view'] =  "view_consulter";
        //
        $this->class_actions[11] = array(
            "identifier" => "redirect-nature",
            "view" => "view_redirect_nature",
            "permission_suffix" => "consulter",
            "condition" => array(
                "exists",
            ),
        );
        //
        $this->class_actions[12] = array(
            "identifier" => "emplacement-summary",
            "view" => "view_summary",
            "permission_suffix" => "consulter",
            "condition" => array(
                "exists",
            ),
        );
        //
        $this->class_actions[13] = array(
            "identifier" => "emplacement-map",
            "view" => "view_om_sig_map",
            "permission_suffix" => "consulter",
            "crud" => "read",
            "condition" => array(
                "exists",
            ),
        );
        //
        $this->class_actions[21] = array(
            "identifier" => "view_overlay_select_voie_by_cimetiere_zone",
            "view" => "view_overlay_select_voie_by_cimetiere_zone",
            "permission_suffix" => "consulter",
        );
        //
        $this->class_actions[22] = array(
            "identifier" => "view_json_select_czv",
            "view" => "view_json_select_czv",
            "permission_suffix" => "consulter",
        );
        // ACTION - 031 - trt-fin-concession
        //
        $this->class_actions[31] = array(
            "identifier" => "trt-fin-concession",
            "permission_suffix" => "concessionfin",
            "view" => "view_fin_concession",
            "condition" => array(
                "exists",
            ),
        );
        // ACTION - 041 - plan-en-coupe
        //
        $this->class_actions[41] = array(
            "identifier" => "plan-en-coupe",
            "portlet" => array(
                "type" => "action-self",
                "libelle" => __("plan en coupe"),
                "description" => __("affiche le plan en coupe de l'emplacement"),
                "class" => "plan-en-coupe-16",
                "order" => 29,
            ),
            "permission_suffix" => "consulter",
            "view" => "view_plan_en_coupe",
            "condition" => array(
                "exists",
                "has_sepulture_type",
                "is_grille_setted"
            ),
        );

        $this->class_actions[42] = array(
            "identifier" => "emplacement-plan-en-coupe-case",
            // "method" => "modifier",
            "view" => "view_maj_etat_case_pec",
            "permission_suffix" => "verrouiller",
            "condition" => array(
                "exists",
            ),
        );
        //
        $this->class_actions[91] = array(
            "identifier" => "view_calcul_place",
            "view" => "view_calcul_place",
            "permission_suffix" => "calculer_place",
        );
        // ACTION - 101 - edition
        //
        $this->class_actions[101] = array(
            "identifier" => "pdf-edition",
            "portlet" => array(
                "type" => "action-blank",
                "libelle" => __("récapitulatif"),
                "description" => __('télécharger le récapitulatif au format pdf'),
                "class" => "pdf-16",
                "order" => 30,
            ),
            "permission_suffix" => "edition",
            "view" => "view_pdf_edition_etat",
            "condition" => array(
                "exists",
            ),
        );
        // ACTION - 102 - edition
        //
        $this->class_actions[102] = array(
            "identifier" => "pdf-edition-libre",
            "portlet" => array(
                "type" => "action-blank",
                "libelle" => __("récapitulatif (libre)"),
                "description" => __('télécharger le récapitulatif (libre) au format pdf'),
                "class" => "pdf-16",
                "order" => 31,
            ),
            "permission_suffix" => "edition",
            "view" => "view_pdf_edition_etat",
            "condition" => array(
                "exists",
                "is_libre",
            ),
        );
    }

    /**
     * @return string
     */
    function get_default_om_sig_map() {
        return "emplacement";
    }

    /**
     * @return void
     */
     function form_specific_content_before_portlet_actions($maj) {
        //
    }

    /**
     * @return string
     */
    function get_om_etat_id() {
        // L'action 102 est utilisée pour les éditions :
        // - om_etat - colombariumlibre
        // - om_etat - concessionlibre
        // - om_etat - terraincommunallibre
        if ($this->getParameter("maj") == 102) {
            return $this->get_absolute_class_name()."libre";
        }
        // Sinon c'est l'action 101 pour les éditions :
        // - om_etat - colombarium
        // - om_etat - concession
        // - om_etat - terraincommunal
        // - om_etat - ossuaire
        // - om_etat - depositoire
        // - om_etat - enfeu
        return $this->get_absolute_class_name();
    }

    /**
     * CONDITION - has_sepulture_type
     *
     * Vérifie si l'emplacement contient un type de sépulture.
     *
     * @return boolean
     */
    function has_sepulture_type() {
        if (! empty($this->getVal('sepulturetype'))) {
            return true;
        }
        return false;
    }

    /**
     * CONDITION - is_grille_setted
     *
     * Vérifie si le type de sépulture contient un paramétrage de grille
     * colonne et ligne.
     *
     * @return boolean
     */
    function is_grille_setted() {
        $inst_sepulturetype = $this->f->get_inst__om_dbform(array(
            "obj" => "sepulture_type",
            "idx" => $this->getVal("sepulturetype"),
        ));
        if ($inst_sepulturetype->getVal('colonne') != 0 && $inst_sepulturetype->getVal('ligne') != 0) {
            return true;
        }
        return false;
    }

    /**
     *
     */
    function get_defunts() {
        $query = sprintf(
            'SELECT * FROM %1$sdefunt WHERE defunt.emplacement=%2$s ORDER BY nom, marital, prenom, datedeces',
            DB_PREFIXE,
            intval($this->getVal($this->clePrimaire))
        );
        $res = $this->f->db->query($query);
        $this->addToLog(__METHOD__."(): db->query(\"".$query."\");", VERBOSE_MODE);
        $this->f->isDatabaseError($res);
        $defunts = array();
        while ($row =& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
            $defunts[] = $row;
        }
        return $defunts;
    }

    /**
     *
     */
    function get_concessionnaires() {
        $query = sprintf(
            'SELECT titre_de_civilite.libelle as titre_de_civilite, nom, prenom, marital, dcd, adresse1, adresse2, cp, ville FROM %1$sautorisation LEFT JOIN %1$stitre_de_civilite ON autorisation.titre = titre_de_civilite.titre_de_civilite WHERE autorisation.nature=\'concessionnaire\' AND autorisation.emplacement=%2$s ORDER BY nom, marital, prenom',
            DB_PREFIXE,
            intval($this->getVal($this->clePrimaire))
        );
        $res = $this->f->db->query($query);
        $this->addToLog(__METHOD__."(): db->query(\"".$query."\");", VERBOSE_MODE);
        $this->f->isDatabaseError($res);
        $concessionnaires = array();
        while ($row =& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
            $concessionnaires[] = $row;
        }
        return $concessionnaires;
    }

    /**
     * Permet de récupérer les informations du cimetière lié à l'emplacement
     *
     * @return inst_om_dbform
     */
    function get_inst_omdbform_cimetiere_from_emplacement() {
        if (isset($this->_inst_cimetiere_from_emplacement) === true) {
            return $this->_inst_cimetiere_from_emplacement;
        }
        // On récupère l'identifiant du cimetière
        $qres = $this->f->get_one_result_from_db_query(
            sprintf(
                'SELECT
                    cimetiere.cimetiere
                FROM
                    %1$semplacement
                    INNER JOIN %1$svoie ON emplacement.voie = voie.voie
                    INNER JOIN %1$szone ON voie.zone = zone.zone
                    INNER JOIN %1$scimetiere ON zone.cimetiere = cimetiere.cimetiere
                WHERE
                    emplacement = %2$s
                ',
                DB_PREFIXE,
                $this->get_id_in_any_context($this->form,'emplacement')
            )
        );
        // On instancie le cimetiere
        $this->_inst_cimetiere_from_emplacement = $this->f->get_inst__om_dbform(array(
            "obj" => "cimetiere",
            "idx" => intval($qres['result']),
        ));
        return $this->_inst_cimetiere_from_emplacement;
    }

    /**
     * Permet de récupérer le libellé du cimetière lié à l'emplacement.
     *
     * @return string
     */
    function get_cimetierelib() {
        $inst_cimetiere = $this->get_inst_omdbform_cimetiere_from_emplacement();

        return $inst_cimetiere->getVal('cimetierelib');
    }

    /**
     * Permet de récupérer l'adresse du cimetière lié à l'emplacement.
     *
     * @return string
     */
    function get_cimetiere_adresse() {
        $inst_cimetiere = $this->get_inst_omdbform_cimetiere_from_emplacement();

        return sprintf("%s %s %s %s",
                $inst_cimetiere->getVal('adresse1'),
                $inst_cimetiere->getVal('adresse2'),
                $inst_cimetiere->getVal('cp'),
                $inst_cimetiere->getVal('ville')
            );
    }


    /**
     * Permet de récupérer le libellé de la zone où se situe l'emplacement.
     *
     */
    function get_zonelib() {
        $qres = $this->f->get_one_result_from_db_query(
            sprintf(
                'SELECT
                    zone.zonelib
                FROM
                    %1$semplacement
                    INNER JOIN %1$svoie ON emplacement.voie = voie.voie
                    INNER JOIN %1$szone ON voie.zone = zone.zone
                WHERE
                    emplacement = %2$s
                ',
                DB_PREFIXE,
                $this->get_id_in_any_context($this->form,'emplacement')
            )
        );

        return $qres['result'];
    }

    /**
     *
     * @return string
     */
    function getFormTitle($ent) {
        if ($this->getParameter("maj") == 91) {
            return __("operations")." -> ".__("calcul de la place");
        }
        if ($this->getParameter("maj") == 31) {
            $out = __("archives")." -> ".__($this->nature."fin");
            if ($this->getVal($this->clePrimaire) != "") {
                $out .= "<span class=\"libelle\"> -> ".$this->get_default_libelle()."</span>";
            }
            return $out;
        }
        return parent::getFormTitle($ent);
    }

    /**
     * Permet de récupérer un identifiant quelque soit le contexte
     * dans lequel on se trouve
     *
     *
     * @return integer
     */
    function get_id_in_any_context($form, $champ) {
        if (isset($_POST[$champ])) {
            return $_POST[$champ];
        } elseif($this->getParameter($champ) != "") {
            return $this->getParameter($champ);
        } elseif(isset($form->val[$champ])) {
            return $form->val[$champ];
        } elseif($this->getVal($champ) != null) {
            return $this->getVal($champ);
        }
        return -1;
    }

    /**
     *
     */
    function triggermodifierapres($id, &$dnu1 = null, $val = array(), $dnu2 = null) {
        $inst_emplacement = $this->f->get_inst__om_dbform(array(
            "obj" => "emplacement",
            "idx" => $id,
        ));

        $inst_sepulturetype_after = $this->f->get_inst__om_dbform(array(
            "obj" => "sepulture_type",
            "idx" => $inst_emplacement->getVal('sepulturetype'),
        ));

        $inst_sepulturetype_before = $this->f->get_inst__om_dbform(array(
            "obj" => "sepulture_type",
            "idx" => $this->getVal('sepulturetype'),
        ));
        // On vérifie que les deux types de sépulture ont les mêmes dimensions
        $is_same_line_col = false;
        if ($inst_sepulturetype_after->getVal('colonne') == $inst_sepulturetype_before->getVal('colonne')
            && $inst_sepulturetype_after->getVal('ligne') == $inst_sepulturetype_before->getVal('ligne')) {
            $is_same_line_col = true;
        }

        // On récupère les défunts de l'emplacement ainsi que leurs coordonnées
        $defunts = $this->f->get_all_results_from_db_query(
            sprintf("
                SELECT
                    defunt, x, y
                FROM
                    %sdefunt
                WHERE
                    emplacement = %s
                ",
                DB_PREFIXE,
                $this->getVal($this->clePrimaire)
            )
        );
        // Si le type de sépulture est mis à jour
        if ($this->getVal('sepulturetype') != $inst_emplacement->getVal('sepulturetype')) {
            // Permet d'indiquer si un défunt a été placé dans le plan en coupe
            $is_defunt_place = false;
            foreach($defunts['result'] as $defunt) {
                if ($defunt['x'] != NULL && $defunt['y'] != NULL) {
                    $is_defunt_place = true;
                }
            }
            // On bloque la modification avec message d'erreur
            if ($is_defunt_place == true && $is_same_line_col == false) {
                $this->addToMessage('Le type de sépulture ne peut pas être modifié car des défunts
                    sont placés dans le plan en coupe.');
                $this->addToLog(__METHOD__."(): Le type de sépulture ne peut pas être modifié car des défunts
                    sont placés dans le plan en coupe.", DEBUG_MODE);
                $this->correct = false;
                return false;
            }
            // On vide le schéma de l'état des cases si la dimension à changé
            if ($is_same_line_col == false) {
                $valF['etat_case_plan_en_coupe'] = '';
                $cle = " emplacement = ".$this->getVal($this->clePrimaire);
                $res = $this->f->db->autoExecute(
                    DB_PREFIXE.'emplacement',
                    $valF,
                    DB_AUTOQUERY_UPDATE,
                    $cle
                );
                // On log l'autoExecute
                $this->f->addToLog(__METHOD__."(): db->autoExecute(\"".DB_PREFIXE."emplacement\", ".print_r($valF, true).", DB_AUTOQUERY_UPDATE, \"".$cle."\");", DEBUG_MODE);
            }
        }

        $tab_etat_case = $inst_emplacement->getVal('etat_case_plan_en_coupe');

        if ($this->getVal('videsanitaire') != "Oui" && $inst_emplacement->getVal('videsanitaire') == "Oui") {
            // $valF = array(
            //     'y' => intval('y+1'),
            // );

            $update_defunt = sprintf(
                'UPDATE %1$sdefunt SET y = y+1 WHERE emplacement = %2$s AND x IS NOT NULL AND y >= 0',
                DB_PREFIXE,
                $this->getVal($this->clePrimaire)
            );
            // Mise à jour des champs
            $res = $this->db->query($update_defunt);
            $this->f->isDatabaseError($res);

            // Mise à jour de la grille de verrouillage des cases
            if (! empty($tab_etat_case)) {
                $this->gestion_vide_sanitaire_case_verrou(true, $inst_sepulturetype_after->getVal("colonne"), strval($inst_sepulturetype_after->getVal("ligne")+1));
            }
        } else if ($this->getVal('videsanitaire') == "Oui" && $inst_emplacement->getVal('videsanitaire') != "Oui") {
            // On vérifie qu'aucun défunt n'est présent dans le vide sanitaire
            $is_defunt_vs = false;
            foreach ($defunts['result'] as $defunt) {
                if ($defunt['y'] != "" && intval($defunt['y']) == 1) {
                    $is_defunt_vs = true;
                }
            }
            // On bloque la modification avec message d'erreur
            if ($is_defunt_vs == true) {
                $this->addToMessage('Le vide sanitaire ne peut pas être supprimé car des défunts
                    sont placés à l\'intérieur.');
                $this->addToLog(__METHOD__."(): Le vide sanitaire ne peut pas être supprimé car des défunts
                    sont placés à l\'intérieur.", DEBUG_MODE);
                $this->correct = false;
                return false;
            }
            $update_defunt = sprintf(
                'UPDATE %1$sdefunt SET y = y-1 WHERE emplacement = %2$s AND x IS NOT NULL AND y > 1',
                DB_PREFIXE,
                $this->getVal($this->clePrimaire)
            );
            // Mise à jour des champs
            $res = $this->db->query($update_defunt);
            $this->f->isDatabaseError($res);
            // Mise à jour de la grille de verrouillage des cases
            if (! empty($tab_etat_case)) {
                $this->gestion_vide_sanitaire_case_verrou(false, $inst_sepulturetype_after->getVal("colonne"), $inst_sepulturetype_after->getVal("ligne"));
            }

        }
    }

    /**
     * gestion_vide_sanitaire_case_verrou
     *
     * Permet d'ajouter ou d'enlever une ligne du tableau répertoriant
     * l'état des différentes cases du plan en coupe.
     * Si un vide sanitaire a été ajouté alors on ajoute une ligne au départ,
     * sinon on enlève la première ligne.
     * Cette fonction met à jour le champ etat_case_plan_en_coupe directement en bdd.
     *
     * @param bool $vide_sanitaire_added indique si on ajoute ou on enlève un vide
     *                                   sanitaire de l'emplacement
     * @param int $colonnes permet de spécifier le nombre de colonnes sur le plan en coupe
     * @param int $lignes permet de spécifier le nombre de ligne sur le plan en coupe
     *
     * @return void
     */
    function gestion_vide_sanitaire_case_verrou ($vide_sanitaire_added, $colonnes, $lignes) {
        $tab_etat_case = json_decode(str_replace("'", '"', $this->getVal('etat_case_plan_en_coupe')), true);
        $new_tab_etat_case = array();

        // Ajout ou suppression de la première ligne en fonction
        // du vide sanitaire
        for ($col=1; $col <= $colonnes; $col++) {
            if ($vide_sanitaire_added == true) {
                $new_tab_etat_case[$col.';1'] = array("etat" => "nv");
            }
            if ($vide_sanitaire_added == false) {
                unset($tab_etat_case[$col.';1']);
            }
        }

        $keys_tab_etat_case = array_keys($tab_etat_case);
        $new_keys_tab_etat_case = array();
        // Construction d'un mapping mettant en place
        // une correspondance entre les anciennes clés
        // et les nouvelles à mettre en place
        foreach ($keys_tab_etat_case as $key) {
            $key_splited = explode(';', $key);
            if ($vide_sanitaire_added == true) {
                $new_key = array($key_splited[0], $key_splited[1]+1);
            }
            if ($vide_sanitaire_added == false) {
               $new_key = array($key_splited[0], $key_splited[1]-1);
            }
            $new_keys_tab_etat_case[$key] = implode(';', $new_key);
        }

        // Ajout des anciennes valeurs avec les nouvelles clés
        foreach ($new_keys_tab_etat_case as $old_key => $new_key) {
            $new_tab_etat_case[$new_key] = $tab_etat_case[$old_key];
        }

        // Mise à jour du champ etat_case_plan_en_coupe en bdd
        $valF['etat_case_plan_en_coupe'] = json_encode($new_tab_etat_case);
        if (! empty($valF)) {
            $cle = " emplacement = ".$this->getVal($this->clePrimaire);
            $res = $this->f->db->autoExecute(
                DB_PREFIXE.'emplacement',
                $valF,
                DB_AUTOQUERY_UPDATE,
                $cle
            );

            // On log l'autoExecute
            $this->f->addToLog(__METHOD__."(): db->autoExecute(\"".DB_PREFIXE."emplacement\", ".print_r($valF, true).", DB_AUTOQUERY_UPDATE, \"".$cle."\");", VERBOSE_MODE);
        }
    }

    /**
     * VIEW - view_calcul_place.
     *
     * @return void
     */
    function view_calcul_place() {
        $this->checkAccessibility();
        $this->f->displaySubTitle(" -> ".__("Calcul de la place occupée"));
        $this->f->displayDescription(
            __("Cet écran vous permet de mettre à jour le champ 'place occupée' ".
            "de tous les emplacements en fonction de la taille des déunts de ".
            "l'emplacement.")
        );
        //
        $this->f->layout->display__form_container__begin(array(
            "id" => "traitement_calcul_concession_place_form",
            "action" => $this->getDataSubmit(),
            "onsubmit" => "return trt_form_submit('traitement_calcul_concession_place_result', 'calcul_concession_place', this);",
            "class" => "trt_form",
        ));
        // Exécution du traitement
        if (isset($_POST["traitement_calcul_concession_place_form_valid"])) {
            //
            echo "<div id=\"traitement_calcul_concession_place_result\">\n";
            // debut de transaction [begining transaction)
            $this->f->db->autoCommit(true);
            //
            $msg = "";
            //
            $sql = "select * from ".DB_PREFIXE."emplacement";
            $res = $this->f->db->query($sql);
            $this->addToLog(__METHOD__."(): db->query(\"".$sql."\");", VERBOSE_MODE);
            $this->f->isDatabaseError($res);
            //
            $valF = array();
            //
            while ($row =& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
                //
                $sql1 = " SELECT sum(taille) FROM ".DB_PREFIXE."defunt ";
                $sql1 .= " WHERE emplacement =".$row['emplacement'];
                //
                $valF['placeoccupe'] = $this->f->db->getOne($sql1);
                $this->addToLog(__METHOD__."(): db->getone(\"".$sql1."\");", VERBOSE_MODE);
                $this->f->isDatabaseError($res);
                //
                if ($valF['placeoccupe'] == '') {
                    $valF['placeoccupe'] = 0;
                }
                $cle = "emplacement=".$row['emplacement'];
                $res1 = $this->f->db->autoExecute(DB_PREFIXE."emplacement", $valF, DB_AUTOQUERY_UPDATE, $cle);
                $this->f->addToLog(__METHOD__."(): db->autoExecute(\"".DB_PREFIXE."emplacement\", ".print_r($valF, true).", DB_AUTOQUERY_UPDATE, \"".$cle."\");", VERBOSE_MODE);
                $this->f->isDatabaseError($res1);
            }
            //
            $msg=$msg."<p>".$res->numRows()." ".__("concession")." ".__("calcul_placeoccupe")."</p>";

            /**
             * Enregistrement d'un fichier temporaire de traces
             */
            // Composition du contenu du fichier
            $aff = "recalcul_place";
            $ent = date("d/m/Y   G:i:s");
            //
            echo sprintf(
                '<section>
                    <p>Calcul effectué le %1$s</p>
                    <p>No %2$s : %3$s</p>
                    <p>%4$s %5$s</p>
                </section>
                  %6$s
                ',
                $ent,
                __("collectivite"),
                $_SESSION['coll'],
                __("utilisateur"),
                $_SESSION['login'],
                $msg
            );
            // Écriture du fichier sur le disque
            $metadata = array(
                "filename" => $aff."_".date("dmy_Gis").".htm",
                "size" => strlen($msg),
                "mimetype" => "text/html",
            );
            $uid = $this->f->storage->create_temporary($msg, $metadata);
            // Affichage du lien de téléchargement du fichier de traces
            $this->f->layout->display_link(array(
                "href" => OM_ROUTE_FORM."&snippet=file&uid=".$uid."&amp;mode=temporary",
                "title" => __("Télécharger le fichier traces"),
                "class" => "om-prev-icon reqmo-16 button-secondary",
                "target" => "_blank",
            ));

            // fin de transaction  [end transaction]
            $this->f->db->commit();
            //
            echo "</div>\n";
        }
        //
        echo "<div id=\"traitement_calcul_concession_place_status\">\n";
        $sql = "select sum(placeoccupe) from ".DB_PREFIXE."emplacement";
        $value = $this->f->db->getone($sql);
        $this->f->addToLog(__METHOD__."(): db->getone(\"".$sql."\");", VERBOSE_MODE);
        $this->f->isDatabaseError($value);
        echo _("Valeur courante de la place occupée")." : ".$value;
        echo "</div>\n";
        //
        $this->f->layout->display__form_controls_container__begin(array(
            "controls" => "bottom",
        ));
        $this->f->layout->display__form_input_submit(array(
            "value" => __("Calculer"),
            "name" => "traitement.calcul_concession_place.form.valid",
        ));
        $this->f->layout->display__form_controls_container__end();
        //
        $this->f->layout->display__form_container__end();
    }

    /**
     * VIEW - view_overlay_select_voie_by_cimetiere_zone.
     *
     * @return void
     */
    function view_overlay_select_voie_by_cimetiere_zone() {
        //
        $this->checkAccessibility();
        //
        $this->f->displayStartContent();

        /**
         *
         */
        // voie
        $grandparentval = 0;
        $parentval = 0;
        $valeur = 0;
        if (isset($_GET['val']) && $_GET['val'] != "") {
            $valeur = $_GET['val'];
        }
        if ($valeur > 0) {
            // recherche de la valeur parent en maj
            $sql = sprintf(
                'SELECT
                    voie.zone
                FROM
                    %1$svoie
                WHERE
                    voie.voie=%2$s',
                //
                DB_PREFIXE,
                $valeur
            );
            $parentval = $this->f->db->getOne($sql);
            $this->f->addToLog(__METHOD__."(): db->getone(\"".$sql."\")", VERBOSE_MODE);
            $this->f->isDatabaseError($parentval);
            // recherche de le valeur grandparent en maj
            $sql = sprintf(
                'SELECT
                    zone.cimetiere
                FROM
                    %1$szone
                WHERE
                    zone.zone=%2$s',
                //
                DB_PREFIXE,
                $parentval
            );
            $grandparentval = $this->f->db->getOne($sql);
            $this->f->addToLog(__METHOD__."(): db->getone(\"".$sql."\")", VERBOSE_MODE);
            $this->f->isDatabaseError($grandparentval);
        }
        // *** form ***
        echo "<form name='f2'>";
        echo  "<table><tr>";

        // *** 1er select ***
        echo "<td>".__("Cimetière")."<br/>";
        //
        $options = "";
        $sql_cimetiere = sprintf(
            'SELECT
                cimetiere AS id,
                cimetierelib AS lib
            FROM
                %1$scimetiere',
            DB_PREFIXE
        );
        $res = $this->f->db->query($sql_cimetiere);
        $this->f->addToLog("db->query(\"".$sql_cimetiere."\")", VERBOSE_MODE);
        $this->f->isDatabaseError($res);
        while ($row =& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
            $options .= sprintf(
                '<option value="%1$s"%3$s>%2$s</option>',
                $row["id"],
                $row["lib"],
                ($row["id"] == $grandparentval ? ' selected="selected"' : '')
            );
        }
        printf(
            '<select id="combo-select-%1$s" name="combo-select-%1$s" class="champFormulaire">
                <option value="0">%2$s</option>
                %3$s
            </select>',
            "cimetiere",
            __("Choisir cimetière"),
            $options
        );
        echo "</td>";

        // *** 2eme Select ***
        echo "<td>".__("Zone")."<br/>";
        //
        $options = "";
        if ($valeur > 0) {
            // affichage table parent pour la valeur grand parent
            $sql = sprintf(
                'SELECT
                    zone.zone AS id,
                    CONCAT(zone_type.libelle, \' \', zone.zonelib) AS lib
                FROM
                    %1$szone
                    LEFT JOIN %1$szone_type ON zone.zonetype=zone_type.zone_type
                WHERE
                    zone.cimetiere=%2$s',
                //
                DB_PREFIXE,
                $grandparentval
            );
            $res = $this->f->db->query($sql);
            $this->f->addToLog("db->query(\"".$sql."\")", VERBOSE_MODE);
            $this->f->isDatabaseError($res);
            while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
                $options .= sprintf(
                    '<option value="%1$s"%3$s>%2$s</option>',
                    $row["id"],
                    $row["lib"],
                    ($row['id'] == $parentval ? ' selected="selected"' : '')
                );
            }
        }
        printf(
            '<select id="combo-select-%1$s" name="combo-select-%1$s" class="champFormulaire">
                <option value="0">---</option>
                %2$s
            </select>',
            "zone",
            $options
        );
        echo "</td>";

        // 3eme Select
        echo "<td>".__("Voie")."<br/>";
        //
        $options = "";
        if ($valeur > 0) {
            //
            $sql = sprintf(
                'SELECT
                    voie.voie AS id,
                    CONCAT(voie_type.libelle, \' \', voie.voielib) AS lib
                FROM
                    %1$svoie
                    LEFT JOIN %1$svoie_type
                        ON voie.voietype=voie_type.voie_type
                WHERE
                    voie.zone=%2$s',
                DB_PREFIXE,
                $parentval
            );
            //
            $res = $this->f->db->query($sql);
            $this->f->addToLog("db->query(\"".$sql."\")", VERBOSE_MODE);
            $this->f->isDatabaseError($res);
            while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
                $options .= sprintf(
                    '<option value="%1$s"%3$s>%2$s</option>',
                    $row["id"],
                    $row["lib"],
                    ($row["id"] == $valeur ? ' selected="selected"' : '')
                );
            }
        }
        printf(
            '<select id="combo-select-%1$s" name="combo-select-%1$s" class="champFormulaire">
                <option value="0">---</option>
                %2$s
            </select>',
            "voie",
            $options
        );
        echo "</td>";
        echo "</tr></table>";

        echo "\n<p class=\"linkjsclosewindow\">";
        echo "<a class=\"linkjsclosewindow\" href=\"#\" ";
        echo "onclick=\"recup();\">";
        echo __("Valider");
        echo "</a>";
        echo "</p>\n";

        echo "</form>";
        $this->f->displayEndContent();
        printf(
            '
        <script type="text/javascript">
        $(function() {
            //
            $("#combo-select-cimetiere").change(function() {
                selectrecur("cimetiere", "zone");
            });
            $("#combo-select-zone").change(function() {
                selectrecur("zone", "voie");
            });
        });
        function selectrecur(parent, child) {
            //
            var key = $("#combo-select-"+parent).val();
            //
            var data ="parent="+parent+"&tab="+child+"&key="+key;
            var link = "../app/index.php?module=form&obj=emplacement&idx=0&action=22";
            //
            $.ajax({
                type: "POST",
                url: link,
                cache: false,
                data: data,
                dataType: "json",
                success: function(res){
                    $("#combo-select-"+child).empty();
                    if (res.length == 0) {
                        $("#combo-select-"+child).append(
                             \'<option value="0">---</option>\'
                        );
                    } else {
                        $("#combo-select-"+child).append(
                             \'<option value="0">Choisir \'+child+\'</option>\'
                        );
                        for (j = 0; j < res.length; j++) {
                            $("#combo-select-"+child).append(
                                \'<option value="\'+res[j]["id"]+\'">\'+res[j]["lib"]+\'</option>\'
                            );
                        }
                    }
                    $("#combo-select-"+child).trigger("change");
                },
                async: false
            });
        }
        function recup() {
            //
            if ($("#combo-select-voie").val() != 0) {
                // ancienne adresse
                var x = %s;
                // nouvelle adresse
                var voie_id = $("#combo-select-voie").val()
                //
                if (x != voie_id) {
                    //
                    voie_label = $("#combo-select-voie option:selected").text()
                    zone_label = $("#combo-select-zone option:selected").text()
                    cimetiere_label = $("#combo-select-cimetiere option:selected").text()
                    // on remplit le champ et la valeur
                    $("#autocomplete-voie-search").val(voie_label+" ["+zone_label+"]["+cimetiere_label+"]");
                    $("#autocomplete-voie-id").val(voie_id);
                    // on exécute le onchange
                    $("#autocomplete-voie-id").trigger("change");
                    // on affiche les boutons effacer et valider
                    $("#autocomplete-voie-empty").show();
                    $("#autocomplete-voie-check").show();
                }
                $("#overlay-selection-voie-by-cimetiere-zone").dialog("close").remove();
            } else {
                alert("Aucune voie sélectionnée.")
                $("#overlay-selection-voie-by-cimetiere-zone").dialog("close").remove();
            }
        }
        </script>
            ',
            $valeur
        );
    }

    /**
     * VIEW - view_json_select_czv.
     *
     * @return void
     */
    function view_json_select_czv() {
        //
        $this->checkAccessibility();
        //

        /**
         *
         */
        $tab = $_POST["tab"];
        $parent = $_POST["parent"];
        $key = $_POST["key"];

        /**
         *
         */
        //
        if ($tab == "voie") {
            //
            $sql = sprintf(
                'SELECT
                    voie.voie AS id,
                    CONCAT(voie_type.libelle, \' \', voie.voielib) AS lib
                FROM
                    %1$svoie
                    LEFT JOIN %1$svoie_type
                        ON voie.voietype=voie_type.voie_type
                WHERE
                    voie.zone=%2$s',
                //
                DB_PREFIXE,
                $key
            );
        } elseif ($tab == "zone") {
            //
            $sql = sprintf(
                'SELECT
                    zone.zone AS id,
                    CONCAT(zone_type.libelle, \' \', zone.zonelib) AS lib
                FROM
                    %1$szone
                    LEFT JOIN %1$szone_type
                        ON zone.zonetype=zone_type.zone_type
                WHERE
                    zone.cimetiere=%2$s',
                //
                DB_PREFIXE,
                $key
            );
        }
        $res = $this->f->db->query($sql);
        $this->addToLog(__METHOD__."(): db->query(\"".$sql."\")", VERBOSE_MODE);
        $this->f->isDatabaseError($res);
        //
        $results = array();
        if ($res->numRows() != 0) {
            while ($row =& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
                $results[] = $row;
            }
        }
        //
        $res->free();
        //
        echo json_encode($results);
    }

    /**
     *
     * @return string
     */
    function get_default_libelle() {
        return $this->getVal($this->clePrimaire)."&nbsp;".$this->getVal("famille");
    }

    /**
     * GETTER_FORMINC - champs.
     *
     * @return array
     */
    function get_var_sql_forminc__champs() {
        return array(
            //infos concession
            "emplacement",//0
            "nature",
            "libre",
            //adresse
            "concat(
                trim(concat(
                    emplacement.numero,
                    ' ',
                    emplacement.complement
                )),
                ' ',
                voie_type.libelle,
                ' ',
                voie.voielib,
                ' [',
                zone_type.libelle,
                ' ',
                zone.zonelib,
                '][',
                cimetiere.cimetierelib,
                ']'
            ) as adresse",
            "numero",
            "complement",
            "emplacement.voie as voie",
            //plan image
            "plans",
            "positionx",
            "positiony",
            "'' as lien_sig_externe",
            "emplacement.geom",
            "emplacement.pgeom",
            //acte
            "famille",
            "typeconcession",
            "has_mort_pour_la_france",
            "numerocadastre",
            "numeroacte",
            "dateacte",
            "terme",
            "duree",//14
            "datevente",//10
            "daterenouvellement",//13
            "dateterme",//15
            //abandon
            "abandon",
            "date_abandon",
            "'' as suivi_reprise",
            //bati
            "sepulturetype",
            "emplacement.videsanitaire",
            "semelle",
            "etatsemelle",
            "monument",
            "etatmonument",
            "largeur",
            "profondeur",
            //places
            "nombreplace",
            "placeoccupe",
            "placeconstat",
            "dateconstat",
            "superficie",
            //temp
            "temp1",
            "temp2",
            "temp3",
            "temp4",
            "temp5",
            "observation",
            "photo",
            "etat_case_plan_en_coupe",
            "emplacement.om_collectivite",
        );
    }

    /**
     * GETTER_FORMINC - tableSelect.
     *
     * @return string
     */
    function get_var_sql_forminc__tableSelect() {
        return DB_PREFIXE."emplacement
            LEFT JOIN ".DB_PREFIXE."om_collectivite
                ON emplacement.om_collectivite=om_collectivite.om_collectivite
            LEFT JOIN ".DB_PREFIXE."voie
                ON emplacement.voie=voie.voie
            LEFT JOIN ".DB_PREFIXE."voie_type
                ON voie.voietype=voie_type.voie_type
            LEFT JOIN ".DB_PREFIXE."zone
                ON voie.zone=zone.zone
            LEFT JOIN ".DB_PREFIXE."zone_type
                ON zone.zonetype=zone_type.zone_type
            LEFT JOIN ".DB_PREFIXE."cimetiere
                ON zone.cimetiere=cimetiere.cimetiere
        ";
    }

    /**
     * GETTER_FORMINC - sql_voie.
     *
     * @return string
     */
    function get_var_sql_forminc__sql_voie() {
        return "select voie.voie,(' '||voie_type.libelle||' '||voie.voielib||' ['||zone_type.libelle||' '||zone.zonelib||']['||cimetierelib||']') as lib
            FROM ".DB_PREFIXE."voie
            INNER JOIN ".DB_PREFIXE."voie_type
                ON voie.voietype=voie_type.voie_type
            INNER JOIN ".DB_PREFIXE."zone
                ON voie.zone=zone.zone
            INNER JOIN ".DB_PREFIXE."zone_type
                ON zone.zonetype=zone_type.zone_type
            INNER JOIN ".DB_PREFIXE."cimetiere
                ON zone.cimetiere=cimetiere.cimetiere
        ";
    }

    /**
     * GETTER_FORMINC - sql_voie_by_id.
     *
     * @return string
     */
    function get_var_sql_forminc__sql_voie_by_id() {
        return "select voie.voie,(' '||voie_type.libelle||' '||voie.voielib||' ['||zone_type.libelle||' '||zone.zonelib||']['||cimetierelib||']') as lib
            FROM ".DB_PREFIXE."voie
            INNER JOIN ".DB_PREFIXE."voie_type
                ON voie.voietype=voie_type.voie_type
            INNER JOIN ".DB_PREFIXE."zone
                ON voie.zone=zone.zone
            INNER JOIN ".DB_PREFIXE."zone_type
                ON zone.zonetype=zone_type.zone_type
            INNER JOIN ".DB_PREFIXE."cimetiere
                ON zone.cimetiere=cimetiere.cimetiere
            WHERE voie.voie = <idx>
        ";
    }

    /**
     * GETTER_FORMINC - sql_zone.
     *
     * @return string
     */
    function get_var_sql_forminc__sql_zone() {
        return "select voie.voie,(' '||voie_type.libelle||' '||voie.voielib||' ['||zone_type.libelle||' '||zone.zonelib||']['||cimetierelib||']') as lib
            FROM ".DB_PREFIXE."voie
            INNER JOIN ".DB_PREFIXE."voie_type
                ON voie.voietype=voie_type.voie_type
            INNER JOIN ".DB_PREFIXE."zone
                ON voie.zone=zone.zone
            INNER JOIN ".DB_PREFIXE."zone_type
                ON zone.zonetype=zone_type.zone_type
            INNER JOIN ".DB_PREFIXE."cimetiere
                ON zone.cimetiere=cimetiere.cimetiere
            order by cimetiere.cimetierelib
        ";
    }

    /**
     * GETTER_FORMINC - sql_plans.
     *
     * @return string
     */
    function get_var_sql_forminc__sql_plans() {
        return "select plans,planslib from ".DB_PREFIXE."plans order by plans";
    }

    /**
     * SETTER_FORM - setLib.
     *
     * @return void
     */
    function setLib(&$form, $maj) {
        parent::setLib($form, $maj);
        //
        $form->setLib($this->clePrimaire, __("id"));
        $this->form->setLib("datevente", __("date vente initiale"));
        $this->form->setLib("daterenouvellement", __("date dernier renouvellement ou de transformation"));
        //
        $this->form->setLib("complement", "&nbsp;");
        //
        $this->form->setLib("suivi_reprise", __("suivi"));
        $this->form->setLib("lien_sig_externe", '');
    }

    /**
     * SETTER_FORM - setLayout.
     *
     * @return void
     */
    function setLayout(&$form, $maj) {
        parent::setLayout($form, $maj);

        //// CONTAINER GLOBAL - START
        $this->form->setBloc("emplacement", "D", "", "emplacement-form emplacement-consultation form-action-".$maj);


        // START : BLOC 1 : ID + NATURE and LIBRE
        $this->form->setBloc("emplacement", "D", "", "row-fluid emplacement-fields-metadata");

            $this->form->setBloc("emplacement", "DF", "", "emplacement-field-emplacement span6");
            $this->form->setBloc("nature", "DF", "", "emplacement-field-nature span5");
            $this->form->setBloc("libre", "DF", "", "emplacement-field-libre span12");

        $this->form->setBloc("libre", "F");
        // END - BLOC 1

        // START - BLOC 2 : ADRESSE
        $this->form->setBloc("numero", "D", __("Adresse"), "row-fluid emplacement-fields-adresse");

            $this->form->setBloc("numero", "DF", "", "emplacement-field-numero span10");
            $this->form->setBloc("complement", "DF", "", "no-label emplacement-field-complement span2");
            $this->form->setBloc("voie", "DF", "", "emplacement-field-voie span12");

        $this->form->setBloc("voie", "F");
        // END - BLOC 2

        // START - BLOC 3 : PLAN
        if ($this->f->getParameter("option_localisation") == "plan") {
            $this->form->setBloc("plans", "D", __("Plans"), "row-fluid emplacement-fields-plans");
                $this->form->setBloc("plans", "DF", "", "emplacement-field-plans span12");
                $this->form->setBloc("positionx", "DF", "", "emplacement-field-positionx span4");
                $this->form->setBloc("positiony", "DF", "", "emplacement-field-positiony span4");
            $this->form->setBloc("positiony", "F");
        }
        // END - BLOC 3 : PLANS

        // START - BLOC 4 : ACTE
        $this->form->setBloc("famille", "D", __("Acte de concession"), "row-fluid emplacement-fields-acte ");
            // Start Col 1 - Administratif
            $this->form->setBloc("famille", "D", __("Administratif"), "emplacement-field-administratif span6");
                $this->form->setBloc("famille", "DF", "", "emplacement-field-famille span10");
                $this->form->setBloc("typeconcession", "DF", "", "emplacement-field-typeconcession span10");
                $this->form->setBloc("numerocadastre", "DF", "", "emplacement-field-numerocadastre span10");
                $this->form->setBloc("numeroacte", "DF", "", "emplacement-field-numeroacte span10");
                $this->form->setBloc("dateacte", "DF", "", "emplacement-field-dateacte span10");
            $this->form->setBloc("dateacte", "F");
            // End Col 1 - Administratif

             // Start Col 2 - Dates clé
            $this->form->setBloc("terme", "D", __("Dates clés"), "emplacement-field-dates span5");
                $this->form->setBloc("terme", "DF", "", "emplacement-field-terme span10");
                $this->form->setBloc("duree", "DF", "", "emplacement-field-duree span10");
                $this->form->setBloc("datevente", "DF", "", "emplacement-field-datevente span10");
                $this->form->setBloc("daterenouvellement", "DF", "", "emplacement-field-daterenouvellement span10");
                $this->form->setBloc("dateterme", "DF", "", "emplacement-field-dateterme span10");
            $this->form->setBloc("dateterme", "F");
            // End Col 1 - Dates clé
        $this->form->setBloc("dateterme", "F");
        // END - BLOC 4 - ACTE

        // START - BLOC 5 : ABANDON
        $this->form->setBloc("abandon", "D", __("Abandon"), "row-fluid emplacement-fields-abandon");
            $this->form->setBloc("abandon", "DF", "", "emplacement-field-abandon span6");
            $this->form->setBloc("date_abandon", "DF", "", "emplacement-field-abandon span5");
        $this->form->setBloc("date_abandon", "F");
        // END - BLOC 5 : ABANDON

        // START - BLOC 6 : BATI
        $this->form->setBloc("sepulturetype", "D", __("Bâti"), "row-fluid emplacement-fields-bati");
            // Start Col 1 - Structure funéraire
            $this->form->setBloc("sepulturetype", "D", __("Structure funéraire"), "span6");
                $this->form->setBloc("sepulturetype", "DF", "", "emplacement-field-sepulture span8");
                $this->form->setBloc("videsanitaire", "DF", "", "emplacement-field-vide span4");
                $this->form->setBloc("semelle", "DF", "", "emplacement-field-semelle span8");
                $this->form->setBloc("etatsemelle", "DF", "", "emplacement-field-etatsemelle span3");
                $this->form->setBloc("monument", "DF", "", "emplacement-field-monument span8");
                $this->form->setBloc("etatmonument", "DF", "", "emplacement-field-etatmonument span3");
            $this->form->setBloc("etatmonument", "F");
            // End Col 1 - Structure funéraire

            // Start Col 2 - Dimensions
            $this->form->setBloc("largeur", "D", __("Dimensions"), "span5 emplacement-field-dates");
                $this->form->setBloc("largeur", "DF", "", "emplacement-field-largeur span6");
                $this->form->setBloc("profondeur", "DF", "", "emplacement-field-profondeur span6");
            $this->form->setBloc("profondeur", "F");
            // End Col 1 - Dimensions

        $this->form->setBloc("profondeur", "F");
        // END - BLOC 6 : BATI

        // START - BLOC 7 : PLACES
        $this->form->setBloc("nombreplace", "D", __("Gestion de la place"), "row-fluid emplacement-fields-places");
            $this->form->setBloc("nombreplace", "DF", "", "emplacement-field-nombreplace span6");
            $this->form->setBloc("placeoccupe", "DF", "", "emplacement-field-placeoccupe span4");
            $this->form->setBloc("placeconstat", "DF", "", "emplacement-field-placeconstat span6");
            $this->form->setBloc("dateconstat", "DF", "", "emplacement-field-dateconstat span4");
            $this->form->setBloc("superficie", "DF", "", "emplacement-field-superficie span1");
        $this->form->setBloc("dateconstat", "F");
        // END - BLOC 7 : PLACES

        // START - BLOC 8 : OBSERVATIONS
            $this->form->setBloc("observation", "DF",  __("Observations"), "row-fluid no-label emplacement-field-observations span12");
        // END - BLOC 8 : OBSERVATIONS

        //// CONTAINER GLOBAL - END
        $this->form->setBloc("observation", "F");
    }

    /**
     *
     * @return string
     */
    function compose_form_url($case = "form", $override = array()) {
        //
        $out = parent::compose_form_url($case, $override);
        //
        if ($this->getParameter("specific_origin") != null) {
            $out .= "&amp;specific_origin=".$this->getParameter("specific_origin");
        }
        //
        return $out;
    }

    /**
     * Retourne le lien de retour (VIEW formulaire et VIEW sousformulaire).
     *
     * @param string $view Appel dans le contexte de la vue 'formulaire' ou de
     *                     la vue 'sousformulaire'.
     *
     * @return string
     */
    function get_back_link($view = "formulaire") {
        // Récupération du mode de l'action
        $crud = $this->get_action_crud();
        //
        if ($view === "formulaire") {
            $tab_script = OM_ROUTE_TAB;
            $form_script = OM_ROUTE_FORM;
        } elseif ($view === "sousformulaire") {
            $tab_script = OM_ROUTE_SOUSTAB;
            $form_script = OM_ROUTE_SOUSFORM;
        }
        // On revient au tableau, ou au formulaire si le param retour vaut 'form'
        // et on n'a pas validé avec succès une suppression
        if ($this->get_back_target() === "form") {
            //
            $href = $form_script;
        } else {
            $href = $tab_script;
        }
        //
        if ($this->get_back_target() !== "form"
            && $this->getParameter("specific_origin") != null) {
            $href .= "&obj=".$this->getParameter("specific_origin");
        } else {
            $href .= "&obj=".$this->get_absolute_class_name();
            if ($this->getParameter("specific_origin") != null) {
                $href .= "&specific_origin=".$this->getParameter("specific_origin");
            }
        }
        //
        if ($this->get_back_target() === "form") {
            if (($crud === 'create'
                 || ($crud === null
                     && $this->getParameter('maj') == 0))
                && $this->correct == true) {
                $href .= "&idx=".$this->valF[$this->clePrimaire];
            } else {
                $href .= "&idx=".$this->getParameter("idx");
            }
            $href .= "&action=3";
        }
        //
        if ($view === "formulaire") {
            $href .= "&advs_id=".$this->getParameter("advs_id");
            $href .= "&premier=".$this->getParameter("premier");
            $href .= "&tricol=".$this->getParameter("tricol");
            $href .= "&valide=".$this->getParameter("valide");
        } elseif ($view === "sousformulaire") {
            $href .= "&retourformulaire=".$this->getParameter("retourformulaire");
            $href .= "&idxformulaire=".$this->getParameter("idxformulaire");
            $href .= "&advs_id=".$this->getParameter("advs_id");
            $href .= "&premier=".$this->getParameter("premiersf");
            $href .= "&tricol=".$this->getParameter("tricolsf");
            $href .= "&valide=".$this->getParameter("valide");
        }
        return $href;
    }

    /**
     * CHECK_TREATMENT - verifier.
     *
     * @return void
     */
    function verifier($val = array(), &$dnu1 = null, $dnu2 = null) {
        //
        if (isset($this->valF['libre']) && $this->valF['libre']=='Non' && $this->valF['famille'] == "") {
            $this->correct = false;
            $this->addToMessage(__("Le champ")." ".__("famille")." ".__("est obligatoire"));
        }
        //
        parent::verifier($val);
        //
        if ($this->valF['voie'] == "") {
            $this->correct = false;
            $this->addToMessage(__("Le champ")." ".__("voie")." ".__("est obligatoire"));
        }
        if ($this->valF['numero'] == "") {
            $this->correct = false;
            $this->addToMessage(__("Le champ")." ".__("numero")." ".__("est obligatoire"));
        }

        if ($this->valF['nature'] == NULL || $this->valF['nature'] == "") {
            $this->correct = false;
            $this->addToMessage(__("Le champ")." ".__("nature")." ".__("est obligatoire"));
        }


        //
        if ($this->has_at_least_one_contrat() !== true) {
            //
            if ($val["terme"] == "perpetuite"
                && $val["duree"] != 0) {
                //
                $this->correct = false;
                $this->addToMessage(_("La durée doit être égale à 0 sur un terme perpétuité."));
            } elseif($val["terme"] == "temporaire"
                && $val["duree"] < 0) {
                //
                $this->correct = false;
                $this->addToMessage(_("La durée doit être supérieur à 0 sur un terme temporaire."));
            }
            //
            $datevente = DateTime::createFromFormat('d/m/Y', $val["datevente"]);
            $dateterme = DateTime::createFromFormat('d/m/Y', $val["dateterme"]);
            $daterenouvellement = DateTime::createFromFormat('d/m/Y', $val["daterenouvellement"]);
            if ($val["terme"] == "temporaire"
                && $val["duree"] != 0
                && $daterenouvellement != null
                && $daterenouvellement->add(new DateInterval("P".intval($val["duree"])."Y")) != $dateterme) {
                //
                $this->correct = false;
                $this->addToMessage(_("La date de terme ne correspond pas à la date de renouvellement + la durée."));
            } elseif ($val["terme"] == "temporaire"
                && $val["duree"] != 0
                && $datevente != null
                && $daterenouvellement == null
                && $datevente->add(new DateInterval("P".intval($val["duree"])."Y")) != $dateterme) {
                //
                $this->correct = false;
                $this->addToMessage(_("La date de terme ne correspond pas à la date de vente + la durée."));
            }
        }
    }

    /**
     * Configuration du widget de formulaire autocomplete du champ 'voie'.
     *
     * @return array
     */
    function get_widget_config__voie__autocomplete() {
        return array(
            // Surcharge visée pour l'ajout
            'obj' => "voie",
            // Table de l'objet
            'table' => "voie",
            // Permission d'ajouter
            'droit_ajout' => false,
            // Critères de recherche
            'criteres' => array(
                "voie_type.libelle" => __("type de voie"),
                "voie.voielib" => __("libellé de la voie"),
                "zone_type.libelle" => __("type de zone"),
                "zone.zonelib" => __("libellé de la zone"),
                "cimetiere.cimetierelib" => __("libellé du cimetière"),
            ),
            // Tables liées
            'jointures' => array(
                "voie_type ON voie.voietype=voie_type.voie_type",
                "zone ON voie.zone=zone.zone",
                "zone_type ON zone.zonetype=zone_type.zone_type",
                "cimetiere ON zone.cimetiere=cimetiere.cimetiere",
            ),
            // Colonnes ID et libellé du champ
            // (si plusieurs pour le libellé alors une concaténation est faite)
            'identifiant' => "voie.voie",
            //
            'libelle' => array(
                "(voie_type.libelle||' '||voie.voielib||' ['||zone_type.libelle||' '||zone.zonelib||']['||cimetiere.cimetierelib||']')",
            ),
            //
            'group_by' => array(
                "voie.voie",
                "voie_type.libelle",
                "voie.voielib",
                "zone_type.libelle",
                "zone.zonelib",
                "cimetiere.cimetierelib",
            ),
            //

            //
            'link_selection' => true,
        );
    }

    /**
     * SETTER_FORM - setSelect.
     *
     * @return void
     */
    function setSelect(&$form, $maj, &$dnu1 = null, $dnu2 = null) {
        parent::setSelect($form, $maj);
        //
        if($maj<2){
            // AUTOCOMPLETE voie
            $form->setSelect(
                "voie",
                $this->get_widget_config("voie", "autocomplete")
            );
            // complement
            $contenu=array();
            $contenu[0]=array('',__("bis"),__("ter"),__("quater"),__("A"),__("B"),__("C"),__("D"),__("E"),__("F"),__("G"),__("H"));
            $contenu[1]=array('',__("bis"),__("ter"),__("quater"),__("A"),__("B"),__("C"),__("D"),__("E"),__("F"),__("G"),__("H"));
            $form->setSelect("complement",$contenu);
        }
        // geom
        if ($maj == 1 || $maj == 3) { //modification ou visualisation
            $contenu=array();
            $contenu[0]=array($this->nature, $this->getParameter("idx"),"0");
            $form->setSelect('geom', $contenu);
        }
        if ($maj == 3) {
            if ($this->f->getParameter("option_localisation") == "sig_externe") {
                $contenu[0] = 'Lien vers le SIG externe';
                // $contenu[1] = $url;
                // $form->setType('lien_sig_externe', 'http');
                $form->setSelect("lien_sig_externe",$contenu);

            }
        }
    }

    /**
     * SETTER_FORM - setOnchange.
     *
     * @return void
     */
    function setOnchange(&$form, $maj) {
        parent::setOnchange($form, $maj);
        //
        // * mise en majuscule
        // On liste les champs sur lesquels on veut forcer les majuscules automatiques
        $fields_to_upper_case = array('famille');
        // On récupère les valeurs de l'option, si il y en a pas retourne un tableau vide
        $option_casse_force_majuscule = $this->f->get_option_casse_force_majuscule();
        // On boucle sur les champs à mettre en majuscule auto
        foreach ($fields_to_upper_case as $field) {
            // Si la clé existe dans l'option et que la valeur est true ou que la clé n'existe pas
            if (array_key_exists($this->clePrimaire.'.'.$field, $option_casse_force_majuscule)
                && $option_casse_force_majuscule[$this->clePrimaire.'.'.$field] === true
                || array_key_exists($this->clePrimaire.'.'.$field, $option_casse_force_majuscule) == false) {
                // On force la majuscule sur le champ
                $form->setOnchange($field, "this.value=this.value.toUpperCase()");
            }
        }
    }


    function setvalF($val = array()) {
        parent::setValF($val);
        $this->valF['nature'] = $this->nature;
    }

    /**
     * SETTER_FORM - setVal.
     *
     * @return void
     */
    function setVal(&$form, $maj, $validation, &$dnu1 = null, $dnu2 = null) {
        // XXX rappel du parent pour insérer la collectivité de l'utilisateur dans le forumlaire
        // XXX vérifier pourquoi le parent était commenté
        parent::setVal($form, $maj, $validation);
        //
        if ($validation==0) {
            if ($maj == 0){
                $form->setVal('emplacement', "[...]");

              $form->setVal('placeoccupe', 0);
              $form->setVal('numerocadastre', 0);
              $form->setVal('numeroacte', 0);
              $form->setVal('terme', 0);
              $form->setVal('duree', 0.0);
              $form->setVal('nombreplace', 0.0);
              $form->setVal('superficie', 0.0);
              $form->setVal('placeconstat', 0.0);
              $form->setVal('positionx', 10); // compatibilite localisation mozilla
              $form->setVal('positiony', 10); // compatibilite localisation mozilla
            }
        }

        $form->setVal('nature', $this->nature);
    }

    /**
     * CHECK_TREATMENT - verifierVoie.
     *
     * @return void
     */
    function verifierVoie($val = array()) {
        // verif voie [verify street]
        $sql = "select voie from ".DB_PREFIXE."voie where voie ='".$val['voie']."'";
        $res = $this->f->db->query($sql);
        $this->addToLog(__METHOD__."(): db->query(\"".$sql."\");", VERBOSE_MODE);
        $this->f->isDatabaseError($res);
        $nbligne = $res->numrows();
        if ($nbligne == 0) {
            $this->addToMessage(__("voie")." ".$val['voie']." ".__("inexistant"));
            $this->correct = false;
        }
        // maj
        if($val['emplacement']==""){
            $maj=0;
        }else
            $maj=1;
        // verif DOUBLON numero + complement + voie [Doubloon street]
        $sql = "select emplacement from ".DB_PREFIXE."emplacement where numero='".$val['numero'].
        "' and complement='".$val['complement']."' and voie='".$val['voie']."'";
        $res = $this->f->db->query($sql);
        $this->addToLog(__METHOD__."(): db->query(\"".$sql."\");", VERBOSE_MODE);
        $this->f->isDatabaseError($res);
        $nbligne = $res->numrows();
        if ($nbligne > 1 and $maj == 1) {
            $this->addToMessage(__("adresse")." ".$val['numero']." ".$val['complement']." ".$val['voie']." ".__("existant"));
            $this->correct = false;
        }
        if ($nbligne > 0 and $maj == 0) {
            $this->addToMessage(__("adresse")." ".$val['numero']." ".$val['complement']." ".$val['voie']." ".__("existant"));
            $this->correct = false;
        }
    }

    /**
     * CONDITION - has_operation_in_progress.
     *
     * @return boolean
     */
    function has_operation_in_progress() {
        $sql = sprintf(
            'SELECT count(operation) FROM %1$soperation WHERE etat=\'actif\' AND (emplacement=%2$s OR emplacement_transfert=%2$s)',
            DB_PREFIXE,
            $this->getVal($this->clePrimaire)
        );
        $operation = $this->f->db->getOne($sql);
        $this->f->addToLog(__METHOD__."(): db->getone(\"".$sql."\");", VERBOSE_MODE);
        $this->f->isDatabaseError($operation);
        if ($operation == 0) {
            return false;
        }
        return true;
    }

    /**
     * CONDITION - has_not_operation_in_progress.
     *
     * @return boolean
     */
    function has_not_operation_in_progress() {
        return !$this->has_operation_in_progress();
    }

    /**
     * VIEW - view_fin_concession.
     *
     * @return void
     */
    function view_fin_concession() {
        $this->checkAccessibility();
        //
        if ($this->has_operation_in_progress() !== false) {
            $this->retour();
            $this->f->displayMessage(
                "error",
                __("Cet emplacement possède une ou plusieurs opérations dans l'état actif. Le traitement est interdit.")
            );
            return;
        }
        //
        $idx = $this->getVal($this->clePrimaire);
        //
        set_time_limit(1800);
        //
        $validation = 0;
        if ($this->getParameter("validation") > 1) {
            $validation = 1;

            /**
             * Vérification des valeurs postées
             */
            $this->correct = true;
            if (isset($_POST['dateexhumation'])) {
                $dateexhumation = $_POST['dateexhumation'];
            } else {
                $dateexhumation = "";
            }
            if (isset($_POST['ossuaire'])) {
                $ossuaire = $_POST['ossuaire'];
            } else {
                $ossuaire = "";
            }
            if (isset($_POST['libre'])) {
                $libre =  $_POST['libre'];
            } else {
                $libre = "";
            }
            if ($ossuaire == "") {
                $this->correct = false;
                $this->addToMessage(__("Le champ")." <span class=\"bold\">".__("ossuaire")."</span> ".__("est obligatoire"));
            }
            if ($libre == "") {
                $this->correct = false;
                $this->addToMessage(__("Le champ")." <span class=\"bold\">".__("libre")."</span> ".__("est obligatoire"));
            }
            if ($dateexhumation <> "") {
                $date = explode("/", $dateexhumation);
                if (sizeof($date) == 3 and (checkdate($date[1], $date[0], $date[2]))) {
                    $dateexhumation = $date[2]."-".$date[1]."-".$date[0];
                } else {
                    $this->correct = false;
                    $this->addToMessage(__("La date")." <span class=\"bold\">".__("dateexhumation")."</span> ".__("n'est pas valide"));
                }
            } else {
                $this->correct = false;
                $this->addToMessage(__("Le champ")." <span class=\"bold\">".__("dateexhumation")."</span> ".__("est obligatoire"));
            }

            /**
             * Exécution du traitement
             */
            if ($this->correct === true) {
                // debut de transaction [beginning transaction]
                $this->f->db->autoCommit(false);
                // msg
                $msg = __("archive")." ".__("concession")." ".$idx."<br><br>";

                /**
                 * traitement qui est en relation avec defunt et qui empeche
                 * la suppression de defunt.
                 * est ce interessant d archiver les operations pour des
                 * concessions terminées ?
                 */
                // traitement opérations [transaction treatment]
                $valF=array();
                $sql= "select * from ".DB_PREFIXE."operation  where emplacement =".$idx;
                $res=$this->f->db->query($sql);
                if ($this->f->isDatabaseError($res, true) !== false) {
                    $verif = false;
                    die($res->getMessage()."erreur ".$sql);
                }else{
                    while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)){
                        $valF = array();
                        $valF['operation']=$row['operation'];
                        $valF['numdossier'] = $row['numdossier'];
                        if($row['date'] !=null)
                            $valF['date'] = $row['date'];
                        if($row['heure'] !=null)
                            $valF['heure'] = $row['heure'];
                        $valF['emplacement'] = $row['emplacement'];
                        $valF['demandeur'] = $row['demandeur'] == '' ? NULL : $row['demandeur'];
                        $valF['societe_coordonnee'] = $row['societe_coordonnee'];
                        $valF['pf_coordonnee'] = $row['pf_coordonnee'];
                        $valF['etat'] = $row['etat'];
                        $valF['categorie'] = $row['categorie'];
                        $valF['particulier'] = $row['particulier'];
                        if($row['emplacement_transfert'] !=null)
                            $valF['emplacement_transfert'] = $row['emplacement_transfert'];
                        $valF['observation'] = $row['observation'];
                        // archivage opération
                        $res1= $this->f->db->autoExecute(DB_PREFIXE."operation_archive",$valF,DB_AUTOQUERY_INSERT);
                        if ($this->f->isDatabaseError($res1, true) !== false)
                            echo $res1->getDebugInfo()." ".$res1->getMessage()."<br>";
                        $msg.= sprintf(
                            '%1$s %2$s %3$s n° de dossier %4$s dans la table operation_archive<br>',
                            __("enregistrement"),
                            $row['categorie'],
                            $row['operation'],
                            $row['numdossier']
                        );
                        // archivage opération défunt
                        $valF2=array();
                        $sql2= "select * from ".DB_PREFIXE."operation_defunt  where operation =".$row['operation'];
                        $res2=$this->f->db->query($sql2);
                        if ($this->f->isDatabaseError($res2, true) !== false) {
                            $verif = false;
                            die($res2->getMessage()."erreur ".$sql2);
                        }else{
                            while ($row2=& $res2->fetchRow(DB_FETCHMODE_ASSOC)){
                                $valF2=array();
                                $valF2['operation_defunt']=$row2['operation_defunt'];
                                $valF2['operation'] = $row2['operation'];
                                if($row2['defunt'] !=null)
                                    $valF2['defunt'] = $row2['defunt'];
                                if($row2['defunt_titre'] !=null)
                                    $valF2['defunt_titre'] = $row2['defunt_titre'];
                                $valF2['defunt_nom'] = $row2['defunt_nom'];
                                $valF2['defunt_marital'] = $row2['defunt_marital'];
                                $valF2['defunt_prenom'] = $row2['defunt_prenom'];
                                if($row2['defunt_datenaissance'] !=null)
                                    $valF2['defunt_datenaissance'] = $row2['defunt_datenaissance'];
                                if($row2['defunt_datedeces'] !=null)
                                    $valF2['defunt_datedeces'] = $row2['defunt_datedeces'];
                                 $valF2['defunt_lieudeces'] = $row2['defunt_lieudeces'];
                                 $valF2['defunt_nature'] = $row2['defunt_nature'];
                                if ($row2['defunt_parente'] != null && $row2['defunt_parente'] != '') {
                                    $valF2['defunt_parente'] = $row2['defunt_parente'];
                                }
                                if ($row2['defunt_lieunaissance'] != null && $row2['defunt_lieunaissance'] != '') {
                                    $valF2['defunt_lieunaissance'] = $row2['defunt_lieunaissance'];
                                }
                                // transfert archive
                                $res1= $this->f->db->autoExecute(DB_PREFIXE."operation_defunt_archive",$valF2,DB_AUTOQUERY_INSERT);
                                if ($this->f->isDatabaseError($res1, true) !== false)
                                    echo $res1->getDebugInfo()." ".$res1->getMessage()."<br>";
                                $msg.= sprintf(
                                    '%1$s %2$s %3$s %4$s id d\'operation : %5$s dans la table operation_defunt_archive<br>',
                                    __("enregistrement"),
                                    $row2['defunt_nom'],
                                    $row2['defunt_marital'],
                                    $row2['defunt_prenom'],
                                    $row2['operation']
                                );
                                // destruction operation défunt [delete transaction]
                                $sql3= "delete from ".DB_PREFIXE."operation_defunt where operation =".$row2['operation'];
                                $res3= $this->f->db->query($sql3);
                                if ($this->f->isDatabaseError($res3, true) !== false)
                                    echo $res3->getDebugInfo()." ".$res3->getMessage()."<br>";
                          }
                        }
                            // destruction operation [delete transaction]
                        $sql4= "delete from ".DB_PREFIXE."operation where operation =".$row['operation'];
                        $res4= $this->f->db->query($sql4);
                        if ($this->f->isDatabaseError($res4, true) !== false)
                            echo $res4->getDebugInfo()." ".$res4->getMessage()."<br>";
                    }
                }

                // traitement genealogie
                $valF=array();
                $sql= "select * from ".DB_PREFIXE."genealogie  where emplacement =".$idx;
                $res=$this->f->db->query($sql);
                $this->addToLog(__METHOD__."(): db->query(\"".$sql."\");", VERBOSE_MODE);
                if (DB :: isError($res)) {
                    die($res->getMessage()."erreur ".$sql);
                    $verif = false;
                } else {
                    while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
                        $valF=array();
                        $valF['genealogie'] = $row['genealogie'];
                        $valF['emplacement'] = $row['emplacement'];
                        if ($row['autorisation_p1'] === '') {
                            $valF['autorisation_p1'] = null;
                        } else {
                            $valF['autorisation_p1'] = $row['autorisation_p1'];
                        }
                        if ($row['defunt_p1'] === '') {
                            $valF['defunt_p1'] = null;
                        } else {
                            $valF['defunt_p1'] = $row['defunt_p1'];
                        }
                        if ($row['personne_1'] === '') {
                            $valF['personne_1'] = null;
                        } else {
                            $valF['personne_1'] = $row['personne_1'];
                        }
                        if ($row['personne_2'] === '') {
                            $valF['personne_2'] = null;
                        } else {
                            $valF['personne_2'] = $row['personne_2'];
                        }
                        $valF['lien_parente'] = $row['lien_parente'];
                        if ($row['autorisation_p2'] === '') {
                            $valF['autorisation_p2'] = null;
                        } else {
                            $valF['autorisation_p2'] = $row['autorisation_p2'];
                        }
                        if ($row['defunt_p2'] === '') {
                            $valF['defunt_p2'] = null;
                        } else {
                            $valF['defunt_p2'] = $row['defunt_p2'];
                        }
                        if ($row['commentaire'] === '') {
                            $valF['commentaire'] = null;
                        } else {
                            $valF['commentaire'] = $row['commentaire'];
                        }

                        // transfert genealogie_archive
                        $res1 = $this->f->db->autoExecute(DB_PREFIXE."genealogie_archive", $valF, DB_AUTOQUERY_INSERT);
                        if (DB :: isError($res1)) {
                            echo $res1->getDebugInfo()." ".$res1->getMessage()."<br>";
                        }
                        $msg .= $row['genealogie']." : ".$this->f->db->affectedRows()." ".__("enregistrement")." ".__("ajoute")." ".__("table")." genealogie_archive <br>" ;
                        $msg .= " ".$row['genealogie']." ".__("enregistrement")." ".$row['genealogie']." genealogie_archive<br>";
                        // destruction genealogie
                        $sql2= "delete from ".DB_PREFIXE."genealogie where genealogie =".$row['genealogie'];
                        $res2= $this->f->db->query($sql2);
                        $this->addToLog(__METHOD__."(): db->query(\"".$sql2."\");", VERBOSE_MODE);
                        if (DB :: isError($res2)) {
                            echo $res2->getDebugInfo()." ".$res2->getMessage()."<br>";
                        }
                        $msg .= $row['genealogie']." : ".$this->f->db->affectedRows()." ".__("enregistrement")." ".__("supprime")." ".__("table")." genealogie <br>";
                    }
                }
                //
                $valF=array();
                $sql= "select * from ".DB_PREFIXE."defunt  where emplacement =".$idx;
                $res = $this->f->db->query($sql);
                $this->addToLog(__METHOD__."(): db->query(\"".$sql."\");", VERBOSE_MODE);
                if ($this->f->isDatabaseError($res, true) !== false) {
                    die($res->getMessage()."erreur ".$sql);
                    $verif = false;
                } else {
                    while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
                        $valF=array();
                        // traitement defunt   [treatment Deceased]
                        if ($row['exhumation']=="Oui") {
                            // defunt exhume [Dug up deceased]
                            //  ajout defunt en defunt archive
                            // [add deceased in table defunt_archive]
                            $valF['defunt'] = $row['defunt'];
                            $valF['nature'] = $row['nature'];
                            $valF['taille'] = $row['taille'];
                            $valF['emplacement'] = $row['emplacement'];
                            if ($row['titre'] != null && $row['titre'] != '') {
                                $valF['titre'] = $row['titre'];
                            }
                            $valF['nom'] = $row['nom'];
                            $valF['prenom'] = $row['prenom'];
                            $valF['marital'] = $row['marital'];
                            $valF['lieudeces'] = $row['lieudeces'];
                            $valF['lieunaissance'] = $row['lieunaissance'];
                            $valF['parente'] = $row['parente'];
                            $valF['exhumation'] = $row['exhumation'];
                            $valF['observation'] = $row['observation'];
                            $valF['reduction'] = $row['reduction'];
                            $valF['exhumation'] = $row['exhumation'];
                            $valF['mort_pour_la_france'] = $row['mort_pour_la_france'];
                            if ($row['datenaissance'] != null) {
                                $valF['datenaissance'] = $row['datenaissance'];
                            }
                            if ($row['datedeces'] != null) {
                                $valF['datedeces'] = $row['datedeces'];
                            }
                            if ($row['dateinhumation'] != null) {
                                $valF['dateinhumation'] = $row['dateinhumation'];
                            }
                            if ($row['datereduction'] != null) {
                                $valF['datereduction'] = $row['datereduction'];
                            }
                            if ($row['dateexhumation'] != null) {
                                $valF['dateexhumation'] = $row['dateexhumation'];
                            }
                            //
                            $historique_decoded = array();
                            if (! empty($row['historique'])) {
                                $historique_decoded = json_decode(str_replace("'", '"', $row['historique']), true);
                            }

                            if ($historique_decoded != null && json_last_error() != JSON_ERROR_NONE) {
                                $this->correct = false;
                                $this->addToMessage("Une erreur est survenue. Contactez votre administrateur.");
                                $this->addToLog('Erreur lors du décodage du json. erreur :'.var_export(json_last_error_msg(), true));
                                return $this->end_treatment(__METHOD__, false);
                            }

                            if ($historique_decoded == null) {
                                $historique_decoded = array();
                            }

                            $lastElement = end($historique_decoded);
                            $idValue = isset($lastElement['id']) ? $lastElement['id'] : 0;
                            $historique_decoded[] = array(
                                "id" => $idValue + 1,
                                "categorie" => "transfert",
                                "type" => "exhumation",
                                "dossier" => "",
                                "date" => $_POST['dateexhumation'],
                                "heure" => "",
                                "emplacement_source" => $row['emplacement'],
                                "emplacement_dest" => ""
                            );

                            $valF['historique'] = json_encode($historique_decoded);
                            if (json_last_error() != JSON_ERROR_NONE) {
                                $this->correct = false;
                                $this->addToMessage("Une erreur est survenue. Contactez votre administrateur.");
                                $this->addToLog('Erreur lors de l\'encodage du json. Erreur :'.var_export(json_last_error_msg(), true));
                                return $this->end_treatment(__METHOD__, false);
                            }
                            // transfert defunt_archive
                            // [transfer deceased in archive]
                            $res1= $this->f->db->autoExecute(DB_PREFIXE."defunt_archive", $valF, DB_AUTOQUERY_INSERT);
                            if ($this->f->isDatabaseError($res1, true) !== false) {
                                echo $res1->getDebugInfo()." ".$res1->getMessage()."<br>";
                            }
                            $msg .= __("defunt")." ".$row['nom']." ".$row['prenom']." : ".$this->f->db->affectedRows()." ".__("enregistrement")." ".__("ajoute")." ".__("table")." defunt_archive <br>" ;
                            $msg .= "defunt ".$row['nom']." ".$row['prenom']." enregistrement ".$row['defunt']." en archive_defunt<br>";
                            // destruction en defunt
                            // delete deceeded
                            $sql2= "delete from ".DB_PREFIXE."defunt where defunt =".$row['defunt'];
                            $res2= $this->f->db->query($sql2);
                            $this->addToLog(__METHOD__."(): db->query(\"".$sql2."\");", VERBOSE_MODE);
                            if ($this->f->isDatabaseError($res2, true) !== false) {
                                echo $res2->getDebugInfo()." ".$res2->getMessage()."<br>";
                            }
                            $msg .= __("defunt")." ".$row['nom']." ".$row['prenom']." : ".$this->f->db->affectedRows()." ".__("enregistrement")." ".__("supprime")." ".__("table")." defunt <br>";
                        } else {
                            // defunt non exhume [not dug up deceased]
                            // modifier transfert defunt en ossuaire
                            // [modify transfer deceased in Ossuary]
                            unset($valF['defunt']);
                            $valF['emplacement'] = $ossuaire;
                            $historique_decoded = array();
                            $historique_decoded = json_decode(str_replace("'", '"', $row['historique']), true);
                            if ($historique_decoded != null && json_last_error() != JSON_ERROR_NONE) {
                                $this->correct = false;
                                $this->addToMessage("Une erreur est survenue. Contactez votre administrateur.");
                                $this->addToLog('Erreur lors du décodage du json. erreur :'.var_export(json_last_error_msg(), true));
                                return $this->end_treatment(__METHOD__, false);
                            }

                            if ($historique_decoded == null) {
                                $historique_decoded = array();
                            }
                            $lastElement = end($historique_decoded);
                            $idValue = isset($lastElement['id']) ? $lastElement['id'] : 0;
                            $historique_decoded[] = array(
                                "id" => $idValue + 1,
                                "categorie" => "transfert",
                                "type" => "exhumation",
                                "dossier" => "",
                                "date" => $_POST['dateexhumation'],
                                "heure" => "",
                                "emplacement_source" => $row['emplacement'],
                                "emplacement_dest" => $ossuaire
                            );
                            $historique_decoded[] = array(
                                "id" => $idValue + 2,
                                "categorie" => "transfert",
                                "type" => "inhumation",
                                "dossier" => "",
                                "date" => $_POST['dateexhumation'],
                                "heure" => "",
                                "emplacement_source" => $row['emplacement'],
                                "emplacement_dest" => $ossuaire
                            );
                            $valF['historique'] = json_encode($historique_decoded);
                            if (json_last_error() != JSON_ERROR_NONE) {
                                $this->correct = false;
                                $this->addToMessage("Une erreur est survenue. Contactez votre administrateur.");
                                $this->addToLog('Erreur lors de l\'encodage du json. Erreur :'.var_export(json_last_error_msg(), true));
                                return $this->end_treatment(__METHOD__, false);
                            }
                            $cle = "defunt =".$row['defunt'];
                            $res3 = $this->f->db->autoExecute(DB_PREFIXE."defunt", $valF, DB_AUTOQUERY_UPDATE, $cle);
                            if ($this->f->isDatabaseError($res3, true) !== false) {
                                echo $res3->getDebugInfo()." ".$res3->getMessage()."<br>";
                            }
                            $msg .= ' '.__("defunt")." ".$row['nom']." ".$row['prenom']." ".$this->f->db->affectedRows()." ".__("mis_a_jour")." ".__("table")." defunt <br>" ;
                            $msg .= " ".__('defunt')." ".$row['nom']." ".$row['prenom']." ".__("enregistrement")." ".$row['defunt']." ".__("mis_a_jour")." [".__("ossuaire")." n ".$ossuaire."]<br>";
                        }
                    }

                    $inst_emplacement = $this->f->get_inst__om_dbform(array(
                        "obj" => 'emplacement',
                        "idx" => $ossuaire,
                    ));
                    $cle= " emplacement = ".$ossuaire;
                    $val_ossuaire['has_mort_pour_la_france'] = true;
                    $res = $this->f->db->autoExecute(
                        DB_PREFIXE.'emplacement',
                        $val_ossuaire,
                        DB_AUTOQUERY_UPDATE,
                        $cle
                    );
                    $this->addToLog(__METHOD__."(): db->autoExecute(\"".DB_PREFIXE.$this->table."\", ".print_r($ossuaire, true).", DB_AUTOQUERY_UPDATE, ".$this->getCle($this->getVal($this->clePrimaire)).")", VERBOSE_MODE);
                    if ($this->f->isDatabaseError($res, true) !== false) {
                        return $this->end_treatment(__METHOD__, false);
                    }
                }

                // traitement courrier [mail treatement]
                $valF=array();
                $sql= "select * from ".DB_PREFIXE."courrier  where emplacement =".$idx;
                $res=$this->f->db->query($sql);
                $this->addToLog(__METHOD__."(): db->query(\"".$sql."\");", VERBOSE_MODE);
                if ($this->f->isDatabaseError($res, true) !== false) {
                    die($res->getMessage()."erreur ".$sql);
                    $verif = false;
                } else {
                    while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
                        $valF['courrier'] = $row['courrier'];
                        if ($row['destinataire'] === '') {
                            $valF['destinataire'] = null;
                        } else {
                            $valF['destinataire'] = $row['destinataire'];
                        }
                        $valF['lettretype'] = $row['lettretype'];
                        if ($row['datecourrier'] != null) {
                            $valF['datecourrier'] = $row['datecourrier'];
                        }
                        if ($row['contrat'] != null) {
                            $valF['contrat'] = $row['contrat'];
                        }
                        if ($row['reprise_abandon'] != null) {
                            $valF['reprise_abandon'] = $row['reprise_abandon'];
                        }
                        if ($row['travaux'] != null) {
                            $valF['travaux'] = $row['travaux'];
                        }
                        if ($row['date_finalisation'] != null) {
                            $valF['date_finalisation'] = $row['date_finalisation'];
                        }
                        $valF['complement'] = $row['complement'];
                        $valF['contexte'] = $row['contexte'];
                        $valF['emplacement'] = $row['emplacement'];
                        $valF['fichier'] = $row['fichier'];
                        $valF['finalise'] = $row['finalise'];

                        // transfert courrier_archive
                        // [transfer mail archive]
                        $res1 = $this->f->db->autoExecute(DB_PREFIXE."courrier_archive", $valF, DB_AUTOQUERY_INSERT);
                        if ($this->f->isDatabaseError($res1, true) !== false) {
                            echo $res1->getDebugInfo()." ".$res1->getMessage()."<br>";
                        }
                        $msg .= $row['lettretype']." : ".$this->f->db->affectedRows()." ".__("enregistrement")." ".__("ajoute")." ".__("table")." courrier_archive <br>" ;
                        $msg .= " ".$row['lettretype']." ".__("enregistrement")." ".$row['courrier']." courrier_archive<br>";
                        // destruction courrier
                        //[delete mail]
                        $sql2= "delete from ".DB_PREFIXE."courrier where courrier =".$row['courrier'];
                        $res2= $this->f->db->query($sql2);
                        $this->addToLog(__METHOD__."(): db->query(\"".$sql2."\");", VERBOSE_MODE);
                        if ($this->f->isDatabaseError($res2, true) !== false) {
                            echo $res2->getDebugInfo()." ".$res2->getMessage()."<br>";
                        }
                        $msg .= $row['lettretype']." : ".$this->f->db->affectedRows()." ".__("enregistrement")." ".__("supprime")." ".__("table")." courrier <br>";
                    }
                }


                // traitement contrat
                $valF=array();
                $sql= "select * from ".DB_PREFIXE."contrat  where emplacement =".$idx;
                $res=$this->f->db->query($sql);
                $this->addToLog(__METHOD__."(): db->query(\"".$sql."\");", VERBOSE_MODE);
                if (DB :: isError($res)) {
                    die($res->getMessage()."erreur ".$sql);
                    $verif = false;
                } else {
                    while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
                        $valF=array();
                        $valF['contrat'] = $row['contrat'];
                        $valF['emplacement'] = $row['emplacement'];
                        if ($row['datedemande'] === '') {
                            $valF['datedemande'] = null;
                        } else {
                            $valF['datedemande'] = $row['datedemande'];
                        }
                        $valF['origine'] = $row['origine'];
                        $valF['terme'] = $row['terme'];
                        $valF['duree'] = $row['duree'];
                        if ($row['datevente'] === '') {
                            $valF['datevente'] = null;
                        } else {
                            $valF['datevente'] = $row['datevente'];
                        }
                        if ($row['dateterme'] === '') {
                            $valF['dateterme'] = null;
                        } else {
                            $valF['dateterme'] = $row['dateterme'];
                        }
                        if ($row['montant'] === '') {
                            $valF['montant'] = null;
                        } else {
                            $valF['montant'] = $row['montant'];
                        }
                        $valF['monnaie'] = $row['monnaie'];
                        $valF['valide'] = $row['valide'];
                        $valF['mode_paiement'] = $row['mode_paiement'];
                        $valF['num_ref'] = $row['num_ref'];
                        $valF['observation'] = $row['observation'];

                        // transfert contrat_archive
                        $res1 = $this->f->db->autoExecute(DB_PREFIXE."contrat_archive", $valF, DB_AUTOQUERY_INSERT);
                        if (DB :: isError($res1)) {
                            echo $res1->getDebugInfo()." ".$res1->getMessage()."<br>";
                        }
                        $msg .= $row['contrat']." : ".$this->f->db->affectedRows()." ".__("enregistrement")." ".__("ajoute")." ".__("table")." contrat_archive <br>" ;
                        $msg .= " ".$row['contrat']." ".__("enregistrement")." ".$row['contrat']." contrat_archive<br>";
                        // destruction courrier
                        //[delete mail]
                        $sql2= "delete from ".DB_PREFIXE."contrat where contrat =".$row['contrat'];
                        $res2= $this->f->db->query($sql2);
                        $this->addToLog(__METHOD__."(): db->query(\"".$sql2."\");", VERBOSE_MODE);
                        if (DB :: isError($res2)) {
                            echo $res2->getDebugInfo()." ".$res2->getMessage()."<br>";
                        }
                        $msg .= $row['contrat']." : ".$this->f->db->affectedRows()." ".__("enregistrement")." ".__("supprime")." ".__("table")." contrat <br>";
                    }
                }

                // traitement reprise_abandon
                $valF = array();
                $sql = "SELECT * FROM ".DB_PREFIXE."reprise_abandon WHERE emplacement =".$idx;
                $res = $this->f->db->query($sql);
                $this->addToLog(__METHOD__."(): db->query(\"".$sql."\");", VERBOSE_MODE);

                if (DB::isError($res)) {
                    die($res->getMessage()." erreur ".$sql);
                    $verif = false;
                } else {
                    while ($row = &$res->fetchRow(DB_FETCHMODE_ASSOC)) {
                        $valF = array();
                        $valF['reprise_abandon'] = $row['reprise_abandon'];
                        $valF['emplacement'] = $row['emplacement'];
                        $valF['statut'] = $row['statut'];
                        $valF['etat'] = $row['etat'];
                        $valF['date_suspendue'] = ($row['date_suspendue'] === '') ? null : $row['date_suspendue'];
                        $valF['datecreation'] = $row['datecreation'];
                        $valF['effectuee'] = ($row['effectuee'] === '') ? null : $row['effectuee'];
                        $valF['date_fin_prelim'] = ($row['date_fin_prelim'] === '') ? null : $row['date_fin_prelim'];
                        $valF['dateconvocationvisite1'] = ($row['dateconvocationvisite1'] === '') ? null : $row['dateconvocationvisite1'];
                        $valF['dateconstatpv1'] = ($row['dateconstatpv1'] === '') ? null : $row['dateconstatpv1'];
                        $valF['heureconstatpv1'] = ($row['heureconstatpv1'] === '') ? null : $row['heureconstatpv1'];
                        $valF['descriptionpv1'] = ($row['descriptionpv1'] === '') ? null : $row['descriptionpv1'];
                        $valF['personnepresentepv1'] = ($row['personnepresentepv1'] === '') ? null : $row['personnepresentepv1'];
                        $valF['datenotificationpv1'] = ($row['datenotificationpv1'] === '') ? null : $row['datenotificationpv1'];
                        $valF['debutaffichage1pv1'] = ($row['debutaffichage1pv1'] === '') ? null : $row['debutaffichage1pv1'];
                        $valF['finaffichage1pv1'] = ($row['finaffichage1pv1'] === '') ? null : $row['finaffichage1pv1'];
                        $valF['debutaffichage2pv1'] = ($row['debutaffichage2pv1'] === '') ? null : $row['debutaffichage2pv1'];
                        $valF['finaffichage2pv1'] = ($row['finaffichage2pv1'] === '') ? null : $row['finaffichage2pv1'];
                        $valF['debutaffichage3pv1'] = ($row['debutaffichage3pv1'] === '') ? null : $row['debutaffichage3pv1'];
                        $valF['finaffichage3pv1'] = ($row['finaffichage3pv1'] === '') ? null : $row['finaffichage3pv1'];
                        $valF['dateconvocationvisite2'] = ($row['dateconvocationvisite2'] === '') ? null : $row['dateconvocationvisite2'];
                        $valF['dateconstatpv2'] = ($row['dateconstatpv2'] === '') ? null : $row['dateconstatpv2'];
                        $valF['heureconstatpv2'] = ($row['heureconstatpv2'] === '') ? null : $row['heureconstatpv2'];
                        $valF['descriptionpv2'] = ($row['descriptionpv2'] === '') ? null : $row['descriptionpv2'];
                        $valF['personnepresentepv2'] = ($row['personnepresentepv2'] === '') ? null : $row['personnepresentepv2'];
                        $valF['datenotificationpv2'] = ($row['datenotificationpv2'] === '') ? null : $row['datenotificationpv2'];
                        $valF['debutaffichagepv2'] = ($row['debutaffichagepv2'] === '') ? null : $row['debutaffichagepv2'];
                        $valF['finaffichagepv2'] = ($row['finaffichagepv2'] === '') ? null : $row['finaffichagepv2'];
                        $valF['datedeliberation'] = ($row['datedeliberation'] === '') ? null : $row['datedeliberation'];
                        $valF['numrefdeliberation'] = ($row['numrefdeliberation'] === '') ? null : $row['numrefdeliberation'];
                        $valF['deliberation'] = ($row['deliberation'] === '') ? null : $row['deliberation'];
                        $valF['datearrete'] = ($row['datearrete'] === '') ? null : $row['datearrete'];
                        $valF['numrefarrete'] = ($row['numrefarrete'] === '') ? null : $row['numrefarrete'];
                        $valF['arrete'] = ($row['arrete'] === '') ? null : $row['arrete'];
                        $valF['datearretedebut'] = ($row['datearretedebut'] === '') ? null : $row['datearretedebut'];
                        $valF['datearretefin'] = ($row['datearretefin'] === '') ? null : $row['datearretefin'];

                        // Transfert reprise_abandon_archive
                        $res1 = $this->f->db->autoExecute(DB_PREFIXE."reprise_abandon_archive", $valF, DB_AUTOQUERY_INSERT);
                        if (DB::isError($res1)) {
                            echo $res1->getDebugInfo()." ".$res1->getMessage()."<br>";
                        }
                        $msg .= $row['reprise_abandon']." : ".$this->f->db->affectedRows()." ".__("enregistrement")." ".__("ajoute")." ".__("table")." reprise_abandon_archive <br>";
                        $msg .= " ".$row['reprise_abandon']." ".__("enregistrement")." ".$row['reprise_abandon']." reprise_abandon_archive<br>";

                        // Destruction reprise_abandon
                        $sql2 = "DELETE FROM ".DB_PREFIXE."reprise_abandon WHERE reprise_abandon =".$row['reprise_abandon'];
                        $res2 = $this->f->db->query($sql2);
                        $this->addToLog(__METHOD__."(): db->query(\"".$sql2."\");", VERBOSE_MODE);
                        if (DB::isError($res2)) {
                            echo $res2->getDebugInfo()." ".$res2->getMessage()."<br>";
                        }
                        $msg .= $row['reprise_abandon']." : ".$this->f->db->affectedRows()." ".__("enregistrement")." ".__("supprime")." ".__("table")." reprise_abandon <br>";
                    }
                }

                // traitement travaux [work treatment]
                $valF=array();
                $sql= "select * from ".DB_PREFIXE."travaux  where emplacement =".$idx;
                $res=$this->f->db->query($sql);
                $this->addToLog(__METHOD__."(): db->query(\"".$sql."\");", VERBOSE_MODE);
                if ($this->f->isDatabaseError($res, true) !== false) {
                    die($res->getMessage()."erreur ".$sql);
                    $verif = false;
                } else {
                    while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
                        $valF=array();
                        $valF['travaux']=$row['travaux'];
                        if ($row['entreprise'] !== '' && $row['entreprise'] !== null) {
                            $valF['entreprise'] = $row['entreprise'];
                        }
                        $valF['emplacement'] = $row['emplacement'];
                        if ($row['datedebinter'] != null) {
                            $valF['datedebinter'] = $row['datedebinter'];
                        }
                        if ($row['datefininter'] != null) {
                            $valF['datefininter'] = $row['datefininter'];
                        }
                        $valF['observation'] = $row['observation'];
                        $valF['naturedemandeur'] = $row['naturedemandeur'];
                        if ($row['naturetravaux'] !== '' && $row['naturetravaux'] !== null) {
                            $valF['naturetravaux'] = $row['naturetravaux'];
                        }
                        $valF['demandeur'] = $row['demandeur'] == '' ? NULL : $row['demandeur'];
                        // transfert archive
                        // [transfer work archive]
                        $res1 = $this->f->db->autoExecute(DB_PREFIXE."travaux_archive", $valF, DB_AUTOQUERY_INSERT);
                        if ($this->f->isDatabaseError($res1, true) !== false) {
                            echo $res1->getDebugInfo()." ".$res1->getMessage()."<br>";
                        }
                        $msg .= $row['naturetravaux']." : ".$this->f->db->affectedRows()." ".__("enregistrement")." ".__("ajoute")." ".__("table")." travaux_archive <br>" ;
                        $msg .= " ".__("enregistrement")." ".$row['travaux']." travaux_archive<br>";
                        // destruction travaux
                        // delete work
                        $sql2= "delete from ".DB_PREFIXE."travaux where travaux =".$row['travaux'];
                        $res2= $this->f->db->query($sql2);
                        $this->addToLog(__METHOD__."(): db->query(\"".$sql2."\");", VERBOSE_MODE);
                        if ($this->f->isDatabaseError($res2, true) !== false) {
                            echo $res2->getDebugInfo()." ".$res2->getMessage()."<br>";
                        }
                        $msg .= $row['naturetravaux']." : ".$this->f->db->affectedRows()." ".__("enregistrement")." ".__("supprime")." ".__("table")." travaux <br>" ;
                    }
                }

                // traitement dossier [file treatment]
                $valF=array();
                $sql= "select * from ".DB_PREFIXE."dossier where emplacement =".$idx;
                $res = $this->f->db->query($sql);
                if ($this->f->isDatabaseError($res, true) !== false) {
                    die($res->getMessage()."erreur ".$sql);
                    $verif = false;
                } else {
                    while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
                        $valF=array();
                        $valF['dossier']=$row['dossier'];
                        $valF['emplacement'] = $row['emplacement'];
                        if ($row['datedossier'] != null) {
                            $valF['datedossier'] = $row['datedossier'];
                        }
                        $valF['typedossier'] = $row['typedossier'];
                        $valF['observation'] = $row['observation'];
                        $valF['fichier'] = $row['fichier'];
                        // transfert archive    [transfer archive]
                        $res1= $this->f->db->autoExecute(DB_PREFIXE."dossier_archive", $valF, DB_AUTOQUERY_INSERT);
                        if ($this->f->isDatabaseError($res1, true) !== false) {
                            echo $res1->getDebugInfo()." ".$res1->getMessage()."<br>";
                        }
                        $msg .= $row['fichier']." : ".$this->f->db->affectedRows()." ".__("enregistrement")." ".__("ajoute")." dossier_archive <br>" ;
                        $msg .= $row['fichier']." ".__("enregistrement")." ".$row['dossier']." en dossier_archive<br>";
                        // destruction [delete]
                        $sql2= "delete from ".DB_PREFIXE."dossier where dossier =".$row['dossier'];
                        $res2= $this->f->db->query($sql2);
                        $this->addToLog(__METHOD__."(): db->query(\"".$sql2."\");", VERBOSE_MODE);
                        if ($this->f->isDatabaseError($res2, true) !== false) {
                            echo $res2->getDebugInfo()." ".$res2->getMessage()."<br>";
                        }
                        $msg .= $row['fichier']." : ".$this->f->db->affectedRows()." ".__("enregistrement")." ".__("supprime")." ".__("table")." dossier <br>" ;
                    }
                }

                // traitement autorisation   [treatment Authorization]
                $valF=array();
                $sql= "select * from ".DB_PREFIXE."autorisation  where emplacement =".$idx;
                $res = $this->f-> db -> query($sql);
                if ($this->f->isDatabaseError($res, true) !== false) {
                    die($res->getMessage()."erreur ".$sql);
                    $verif = false;
                } else {
                    while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
                        $valF=array();
                        $valF['autorisation'] = $row['autorisation'];
                        $valF['emplacement'] = $row['emplacement'];
                        $valF['nature'] = $row['nature'];
                        if ($row['titre'] !=null) {
                            $valF['titre'] = $row['titre'];
                        }
                        $valF['nom'] = $row['nom'];
                        $valF['prenom'] = $row['prenom'];
                        $valF['marital'] = $row['marital'];
                        if ($row['datenaissance'] !=null) {
                            $valF['datenaissance'] = $row['datenaissance'];
                        }
                        $valF['adresse1'] = $row['adresse1'];
                        $valF['adresse2'] = $row['adresse2'];
                        $valF['cp'] = $row['cp'];
                        $valF['ville'] = $row['ville'];
                        $valF['telephone1'] = $row['telephone1'];
                        $valF['telephone2'] = $row['telephone2'];
                        $valF['courriel'] = $row['courriel'];
                        $valF['dcd'] = $row['dcd'];
                        if ($row['datedeces'] !=null) {
                            $valF['datedeces'] = $row['datedeces'];
                        }
                        $valF['lieudeces'] = $row['lieudeces'];
                        $valF['observation'] = $row['observation'];
                        $valF['parente'] = $row['parente'];
                        // transfert autorisation_archive [transfer archive]
                        $res1 = $this->f->db->autoExecute(DB_PREFIXE."autorisation_archive", $valF, DB_AUTOQUERY_INSERT);
                        if ($this->f->isDatabaseError($res1, true) !== false) {
                            echo $res1->getDebugInfo()." ".$res1->getMessage()."<br>";
                        }
                        $msg .= __($row['nature'])." ".$row['nom']." ".$row['prenom']." : ".$this->f->db->affectedRows()." ".__("enregistrement")." ".__("ajoute")." ".__("table")." autorisation_archive <br>";
                        $msg .= $row['nature']." ".$row['nom']." ".$row['prenom']." ".__('enregistrement')." ".$row['autorisation']." autorisation_archive<br>";
                        // destruction [delete]
                        $sql2= "delete from ".DB_PREFIXE."autorisation where autorisation =".$row['autorisation'];
                        $res2= $this->f->db->query($sql2);
                        $this->addToLog(__METHOD__."(): db->query(\"".$sql2."\");", VERBOSE_MODE);
                        if ($this->f->isDatabaseError($res2, true) !== false) {
                            echo $res2->getDebugInfo()." ".$res2->getMessage()."<br>";
                        }
                        $msg .= __($row['nature'])." ".$row['nom']." ".$row['prenom']." : ".$this->f->db->affectedRows()." ".__("supprime")." ".__("table")." autorisation <br>";
                    }
                }

                // traitement de la concession [concession treatment]
                // concession
                $valF=array();
                $sql= "select * from ".DB_PREFIXE."emplacement  where emplacement =".$idx;
                $res=$this->f->db->query($sql);
                $this->addToLog(__METHOD__."(): db->query(\"".$sql."\");", VERBOSE_MODE);
                if ($this->f->isDatabaseError($res, true) !== false) {
                    die($res->getMessage()."erreur ".$sql);
                    $verif = false;
                } else {
                    while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
                        $valF=array();
                        $valF['emplacement'] = $row['emplacement'];
                        $valF['nature'] = $row['nature'];
                        $valF['numero'] = $row['numero'];
                        $valF['complement'] = $row['complement'];
                        $valF['voie'] = $row['voie'];
                        $valF['numerocadastre'] = $row['numerocadastre'];
                        $valF['famille'] = $row['famille'];
                        $valF['numeroacte'] = $row['numeroacte'];
                        $valF['has_mort_pour_la_france'] = $row['has_mort_pour_la_france'];
                        if ($row['datevente'] !=null) {
                            $valF['datevente'] = $row['datevente'];
                        }
                        if ($row['daterenouvellement'] !=null) {
                            $valF['daterenouvellement'] = $row['daterenouvellement'];
                        }
                        if ($row['typeconcession'] !=null or $row['typeconcession'] != "") {
                            $valF['typeconcession'] = $row['typeconcession'];
                        }
                        if ($row['videsanitaire'] !=null or $row['videsanitaire'] != "") {
                            $valF['videsanitaire'] = $row['videsanitaire'];
                        }
                        if ($row['semelle'] !=null or $row['semelle'] != "") {
                            $valF['semelle'] = $row['semelle'];
                        }
                        if ($row['etatsemelle'] !=null or $row['etatsemelle'] != "") {
                            $valF['etatsemelle'] = $row['etatsemelle'];
                        }
                        if ($row['monument'] !=null or $row['monument'] != "") {
                            $valF['monument'] = $row['monument'];
                        }
                        if ($row['etatmonument'] !=null or $row['etatmonument'] != "") {
                            $valF['etatmonument'] = $row['etatmonument'];
                        }
                        if ($row['largeur'] !=null or $row['largeur'] != "") {
                            $valF['largeur'] = $row['largeur'];
                        }
                        if ($row['profondeur'] !=null or $row['profondeur'] != "") {
                            $valF['profondeur'] = $row['profondeur'];
                        }
                        if ($row['abandon'] !=null or $row['abandon'] != "") {
                            $valF['abandon'] = $row['abandon'];
                        }
                        if ($row['date_abandon'] !=null) {
                            $valF['date_abandon'] = $row['date_abandon'];
                        }
                        if ($row['dateacte'] !=null) {
                            $valF['dateacte'] = $row['dateacte'];
                        }
                        $valF['terme'] = $row['terme'];
                        if ($row['duree'] !=null or $row['duree'] != "") {
                            $valF['duree'] = $row['duree'];
                        }
                        if ($row['dateterme'] !=null or $row['dateterme'] != "") {
                            $valF['dateterme'] = $row['dateterme'];
                        }
                        if ($row['nombreplace'] !=null or $row['nombreplace'] != "") {
                            $valF['nombreplace'] = $row['nombreplace'];
                        }
                        if ($row['placeoccupe'] !=null or $row['placeoccupe'] != "") {
                            $valF['placeoccupe'] = $row['placeoccupe'];
                        }
                        if ($row['superficie'] !=null or $row['superficie'] != "") {
                            $valF['superficie'] = $row['superficie'];
                        }
                        if ($row['placeconstat'] !=null or $row['placeconstat'] != "") {
                            $valF['placeconstat'] = $row['placeconstat'];
                        }
                        if ($row['dateconstat'] !=null) {
                            $valF['dateconstat'] = $row['dateconstat'];
                        }
                        $valF['observation'] = $row['observation'];
                        if ($row['positionx'] !=null or $row['positionx'] != "") {
                            $valF['positionx'] = $row['positionx'];
                        }
                        if ($row['positiony'] !=null or $row['positiony'] != "") {
                            $valF['positiony'] = $row['positiony'];
                        }
                        $valF['photo'] = $row['photo'];
                        if ($row['plans'] !=null) {
                            $valF['plans'] = $row['plans'];
                        }
                        if ($row['sepulturetype'] !=null) {
                            $valF['sepulturetype'] = $row['sepulturetype'];
                        }
                        if ($row['geom'] !=null or $row['geom'] != "") {
                            $valF['geom'] = $row['geom'];
                        }
                        if ($row['pgeom'] !=null or $row['pgeom'] != "") {
                            $valF['pgeom'] = $row['pgeom'];
                        }
                        // transfert archive    [transfer archive ]
                        $res1 = $this->f->db->autoExecute(DB_PREFIXE."emplacement_archive", $valF, DB_AUTOQUERY_INSERT);
                        if ($this->f->isDatabaseError($res1, true) !== false) {
                            echo $res1->getDebugInfo()." ".$res1->getMessage()."<br>";
                        }
                        $msg .= $row['famille']." : ".$this->f->db->affectedRows()." ".__("enregistrement")." ".__("ajoute")." ".__("table")." emplacement_archive <br>";
                        $msg .= " ".__("concession")." ".$row['famille']." ".__("enregistrement")." ".$row['emplacement']." emplacement_archive<br>";
                        // destruction  [delete concession]
                        $sql2= "delete from ".DB_PREFIXE."emplacement where emplacement =".$row['emplacement'];
                        $res2= $this->f->db->query($sql2);
                        $this->addToLog(__METHOD__."(): db->query(\"".$sql2."\");", VERBOSE_MODE);
                        if ($this->f->isDatabaseError($res2, true) !== false) {
                            echo $res2->getDebugInfo()." ".$res2->getMessage()."<br>";
                        }
                        $msg .= $row['famille']." : ".$this->f->db->affectedRows()." ".__("enregistrement")." ".__("supprime")." ".__("table")." emplacement <br>";
                        if ($libre=='Oui') {
                            $valG['emplacement'] = $this->f->db->nextId(DB_PREFIXE.'emplacement');
                            $valG['famille']= __('emplacement')." ".__('libre');
                            $valG['libre']='Oui';
                            $valG['nature'] = $row['nature'];
                            if ($valG['nature'] == "terraincommunal") {
                                $valG['duree'] = $this->f->getParameter('duree_terraincommunal');
                                $valG['terme'] = 'temporaire';
                            }
                            $valG['numero'] = $row['numero'];
                            $valG['complement'] = $row['complement'];
                            $valG['voie'] = $row['voie'];
                            $valG['numerocadastre'] = $row['numerocadastre'];
                            $valG['superficie'] = $row['superficie'];
                            $valG['nombreplace'] = $row['nombreplace'];
                            $valG['positionx'] = $row['positionx'];
                            $valG['positiony'] = $row['positiony'];
                            $valG['photo'] = $row['photo'];
                            $valG['plans'] = $row['plans'];
                            if ($valG['plans'] == "") {
                                $valG['plans'] = null;
                            }
                            // mise a niveau sig
                            if ($row['geom']!='') {
                                $valG['geom'] = $row['geom'];
                            }
                            if ($row['pgeom']!='') {
                                $valG['pgeom'] = $row['pgeom'];
                            }
                            $res3 = $this->f->db->autoExecute(DB_PREFIXE."emplacement", $valG, DB_AUTOQUERY_INSERT);
                            if ($this->f->isDatabaseError($res3, true) !== false) {
                                echo $res3->getDebugInfo()." ".$res3->getMessage()."<br>";
                            }
                            $msg .= " ".__("emplacement")." ".$valG['emplacement']." ".__("libre")." ".$this->f->db->affectedRows()." ".__("ajoute")." ".__("table")." emplacement <br>";
                            $msg .= " ".__("emplacement")." ".__("libre")." n ".$valG['emplacement']." ".__("ajoute")."<br>";
                        }
                    }
                }
                //
                // fin de transaction  [end transaction]
                $this->f->db->commit();
                //
                $this->f->displayMessage(
                    "valid",
                    __("Le traitement est terminé.")
                );
                $this->retour();
                printf(
                    '<div>%s</div>',
                    $msg
                );

               /**
                 * Enregistrement d'un fichier temporaire de traces
                 */
                // Composition du contenu du fichier
                $aff = "concessionfin";
                $ent = date("d/m/Y   G:i:s").
                "<br>No ".__("collectivite")." : ".$_SESSION['coll'].
                "<br>".__("utilisateur")." : ".$_SESSION['login']."<br>".
                "=========================================="."<br>";
                $msg = $ent."<br>".$msg;
                // Écriture du fichier sur le disque
                $metadata = array(
                    "filename" => $aff."_".date("dmy_Gis").".htm",
                    "size" => strlen($msg),
                    "mimetype" => "text/html",
                );
                $uid = $this->f->storage->create_temporary($msg, $metadata);
                // Affichage du lien de téléchargement du fichier de traces
                $this->f->layout->display_link(array(
                    "href" => OM_ROUTE_FORM."&snippet=file&uid=".$uid."&amp;mode=temporary",
                    "title" => __("Télécharger le fichier traces"),
                    "class" => "om-prev-icon reqmo-16",
                    "target" => "_blank",
                ));
            } else {
                $validation = 0;
                $this->addToMessage("");
                $this->addToMessage(__("TRAITEMENT NON EXÉCUTÉ"));
                $this->message();
            }
        }

        /**
         * Affichage du formulaire
         */
        if ($validation == 0) {
            //
            echo "<form";
            echo " method=\"post\"";
            echo " action=\"".$this->getDataSubmit()."\"";
            echo " name=\"f1\">\n";
            //
            $this->f->displayDescription(
                __("Cet écran permet d'archiver l'emplacement.")
            );
            echo "<fieldset class=\"cadre ui-corner-all ui-widget-content\">\n";
            echo "\t<legend class=\"ui-corner-all ui-widget-content ui-state-active\">";
            echo __("Fin Concession");
            echo "</legend>\n";
            //
            echo "<table  width='100%' border='0'>\n";
            // date exhumation
            echo "<tr>";
            echo "<td>";
            //
            echo __("dateexhumation");
            echo " <span class=\"not-null-tag\">*</span>";
            //
            echo "</td>";
            echo "<td>";
            //
            echo "<input type='text' id='dateexhumation' name='dateexhumation' tabindex=\"1\" size=\"15\" class=\"champFormulaire datepicker\" onchange='fdate(this)'  onkeyup=\"\" onclick=\"\" />";            //
            echo "</td>";
            echo "</tr>\n";
            // ossuaire  [ossuary]
            //
            echo "<tr>";
            echo "<td>";
            //
            echo __("ossuaire")."";
            echo " <span class=\"not-null-tag\">*</span>";
            //
            echo "</td>";
            echo "<td>";
            //
            echo "<select id='ossuaire' name='ossuaire' class='champFormulaire'>";
            $sql_ossuaire = " SELECT emplacement, famille ";
            $sql_ossuaire .= " FROM ".DB_PREFIXE."emplacement ";
            $sql_ossuaire .= " WHERE nature='ossuaire' ";
            $res = $this->f->db->query($sql_ossuaire);
            $this->f->addToLog(__METHOD__."(): db->query(\"".$sql_ossuaire."\");", VERBOSE_MODE);
            $this->f->isDatabaseError($res);
            while ($row =& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
                echo "<option value='".$row["emplacement"]."'>";
                echo $row["emplacement"]." - ".$row["famille"];
                echo "</option>";
            }
            $res->free();
            echo "</select>";
            //
            echo "</td>";
            echo "</tr>\n";
            // emplacement libre  [free place]
            echo "<tr>";
            echo "<td>";
            //
            echo __("creation")." ".__("concession")." ".__("libre");
            echo " <span class=\"not-null-tag\">*</span>";
            //
            echo "</td>";
            echo "<td>";
            //
            echo "<select id='libre' name='libre' class='champFormulaire'>";
            echo "<option value='Oui' selected=\"selected\">".__("Oui")."</option>";
            echo "<option value='Non'>".__("Non")."</option>";
            echo "</select>";
            //
            echo "</td>";
            echo "</tr>\n";
            echo "</table>";

            //
            echo "\n";
            echo "</fieldset>\n";
            //
            $this->f->layout->display__form_controls_container__begin(array(
                "controls" => "bottom",
            ));
            $this->f->layout->display__form_input_submit(array(
                "value" => __("Valider"),
            ));
            $this->retour();
            $this->f->layout->display__form_controls_container__end();
            //
            $this->f->layout->display__form_container__end();
            // avertissement sur defunt deja exhume
            // warning already dug up deceased
            $sql_exhumation = " SELECT defunt, nom, prenom, marital ";
            $sql_exhumation .= " FROM ".DB_PREFIXE."defunt ";
            $sql_exhumation .= " WHERE emplacement=".$idx." and exhumation='Oui' ";
            $res = $this->f->db->query($sql_exhumation);
            $this->f->addToLog(__METHOD__."(): db->query(\"".$sql_exhumation."\");", VERBOSE_MODE);
            $this->f->isDatabaseError($res);
            $nbC = $res->numRows();
            echo "<table>";
            if ($nbC > 0) {
                //
                echo "<tr>";
                echo "<td colspan=\"2\">";
                echo "<b>".__("Controle")." ".__("defunt")." ".__("exhume")."</b>";
                //
                echo "</td>";
                echo "</tr>\n";
                echo "<tr>";
                echo "<td colspan=\"2\">";
                echo "".__("Si les défunts de cet emplacement ont été cochés comme exhumés, ils seront archivés dans l'emplacement, sinon ils seront déplacés dans l'ossuaire de destination.")."";
                //
                echo "</td>";
                echo "<tr>";
                echo "<td colspan=\"2\">";
                echo "".__("Les défunts suivants sont marqués comme exhumés, ils seront archivés avec l'emplacement : ")."";
                //
                echo "</td>";
                echo "</tr>\n";
            }
            while ($row =& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
                //
                echo "<tr>";
                echo "<td colspan=\"2\">";
                //
                if (isset($row['marital'])){
                    echo "- ".$row["nom"]." ".$row['prenom']." (".$row['marital'].")"."";
                }
                else {
                    echo "- ".$row["nom"]." ".$row['prenom']."";
                }
                //
                echo "</td>";
                echo "</tr>\n";
            }
            $res->free();
            //
            echo "</table>\n";
        }
    }

    /**
     * CONDITION - has_at_least_one_contrat.
     *
     * @return boolean
     */
    function has_at_least_one_contrat() {
        $query = sprintf(
            'SELECT count(*) FROM %1$scontrat WHERE emplacement=%2$s',
            DB_PREFIXE,
            intval($this->getVal($this->clePrimaire))
        );
        $nb_contrats = $this->f->db->getone($query);
        $this->f->addToLog(__METHOD__."(): db->getone(\"".$query."\");", VERBOSE_MODE);
        $this->f->isDatabaseError($nb_contrats);
        if ($nb_contrats == 0) {
            return false;
        }
        return true;
    }

    /**
     * CONDITION - get_last_reprise.
     *
     * Permet de récupérer des informations de la dernière
     * reprise sur abandon ajoutée sur l'emplacement.
     *
     * @return mixed
     */
    function get_last_reprise() {
        $last_reprise = $this->f->get_all_results_from_db_query(
            sprintf('
                SELECT
                    statut, etat, datecreation, reprise_abandon
                FROM
                    %1$sreprise_abandon
                WHERE
                    emplacement=%2$d
                ORDER BY
                    datecreation DESC, reprise_abandon DESC
                LIMIT 1',
                DB_PREFIXE,
                intval($this->getVal($this->clePrimaire))
            ),
            true
        );
        if ($last_reprise['code'] == 'KO') {
            $this->f->addToLog(__METHOD__."(): \"".$last_reprise['message']."\";", VERBOSE_MODE);
            return false;
        }

        return ! empty($last_reprise['result']) ? $last_reprise['result'][0] : null;
    }

    /**
     * TREATMENT - update_contrat_info_from_contrats.
     *
     * L'objetif de cette méthode est de mettre à jour les informations de
     * l'emplacement liées aux contrats à chaque modification de contrat.
     * Les informations sont : terme, duree, datevente, dateterme,
     * daterenouvellement.
     *
     * @param array $val Tableau des valeurs brutes.
     *
     * @return boolean
     */
    function update_contrat_info_from_contrats() {
        $this->begin_treatment(__METHOD__);
        // Si aucun contrat n'existe sur cet emplacement, on ne fait rien
        if ($this->has_at_least_one_contrat() !== true) {
            return $this->end_treatment(__METHOD__, true);
        }
        // On récupère la date de vente du plus vieux contrat d'achat
        // (normalement il n'y en a qu'un)
        $query = sprintf(
            'SELECT datevente FROM %1$scontrat WHERE emplacement=%2$s AND origine=\'achat\' ORDER BY datevente ASC LIMIT 1',
            DB_PREFIXE,
            intval($this->getVal($this->clePrimaire))
        );
        $datevente_initiale = $this->f->db->getone($query);
        $this->f->addToLog(__METHOD__."(): db->getone(\"".$query."\");", VERBOSE_MODE);
        $this->f->isDatabaseError($datevente_initiale);
        // On récupère les autres dates, terme et durée du plus récent (par date de vente)
        // contrat qui existe
        $query = sprintf(
            'SELECT * FROM %1$scontrat WHERE emplacement=%2$s ORDER BY datevente DESC, dateterme DESC LIMIT 1',
            DB_PREFIXE,
            intval($this->getVal($this->clePrimaire))
        );
        $res = $this->f->db->query($query);
        $this->f->addToLog(__METHOD__."(): db->query(\"".$query."\");", VERBOSE_MODE);
        $this->f->isDatabaseError($res);
        $row = $res->fetchRow(DB_FETCHMODE_ASSOC);
        $emplacement = array(
            "terme" => $row["terme"],
            "duree" => $row["duree"],
            "datevente" => $row["datevente"],
            "daterenouvellement" => null,
            "dateterme" => ( $row["dateterme"] == '' ? null : $row['dateterme'] ) ,
        );
        if ($datevente_initiale != $row["datevente"]) {
            $emplacement["datevente"] = $datevente_initiale;
            $emplacement["daterenouvellement"] = $row["datevente"];
        }
        $res = $this->f->db->autoExecute(
            DB_PREFIXE.$this->table,
            $emplacement,
            DB_AUTOQUERY_UPDATE,
            $this->getCle($this->getVal($this->clePrimaire))
        );
        $this->addToLog(__METHOD__."(): db->autoExecute(\"".DB_PREFIXE.$this->table."\", ".print_r($emplacement, true).", DB_AUTOQUERY_UPDATE, ".$this->getCle($this->getVal($this->clePrimaire)).")", VERBOSE_MODE);
        if ($this->f->isDatabaseError($res, true)) {
            return $this->end_treatment(__METHOD__, false);
        }
        return $this->end_treatment(__METHOD__, true);
    }

    /**
     * SETTER_FORM - setType.
     *
     * @return void
     */
    function setType(&$form, $maj) {
        parent::setType($form, $maj);
        $crud = $this->get_action_crud($maj);

        $form->setType("adresse", "hidden");
        $form->setType("geom", "hidden");
        $form->setType("pgeom", "hidden");

        // On cache le champ stockant l'état des case du plan en coupe
        $form->setType("etat_case_plan_en_coupe", "hidden");
        $form->setType("suivi_reprise", "hidden");
        $form->setType("lien_sig_externe", "hidden");

        $form->setType("has_mort_pour_la_france", "hidden");

        // MODE AJOUTER
        if ($maj == 0 || $crud == 'create') {
            $form->setType("terme", "select");
            $form->setType("duree", "text");
            $form->setType("datevente", "date");
            $form->setType("daterenouvellement", "date");
            $form->setType("dateterme", "date");
        }
        // MODE MODIFIER
        if ($maj == 1 || $crud == 'update') {
            if ($this->has_at_least_one_contrat() === true) {
                $form->setType("terme", "hiddenstatic");
                $form->setType("duree", "hiddenstatic");
                $form->setType("datevente", "hiddenstaticdate");
                $form->setType("daterenouvellement", "hiddenstaticdate");
                $form->setType("dateterme", "hiddenstaticdate");
            } else {
                $form->setType("terme", "select");
                $form->setType("duree", "text");
                $form->setType("datevente", "date");
                $form->setType("daterenouvellement", "date");
                $form->setType("dateterme", "date");
            }
        }

        if ($this->f->getParameter("option_localisation") == "sig_externe") {
            $form->setType('lien_sig_externe', 'http_localisation_sig_externe');
        }
    }


    function adresse_template ($data) {
        $map_plan = "";
        $map_sig = "";

        // Display Visualise button when localisation option is set to "plan"
        if ($this->f->getParameter("option_localisation") === 'plan') {
            $map_plan = sprintf('
                    <a href="%1$s" class="button button-secondary">
                        <i class="ri-map-pin-2-line"></i>
                        %2$s
                    </a>
                ',
                // "../app/localisation_plan_view.php?idx=".$data["emplacement"]."&amp;obj=".$data["nature"]."&amp;retour=form#camap0",
                "../app/localisation_plan_view.php?idx=".$data["emplacement"]."&obj=".$data["nature"]."&retour=form#camap0",
                _("Visualiser sur le plan")
            );
        }

        // Display Dropdown with map when localisation option is set to "sig_interne"
        if ($this->f->getParameter("option_localisation") === 'sig_interne') {
            $map_sig = sprintf('
                    <input type="checkbox" name="map-dropdown" class="map-dropdown" id="map_dropdown_button">
                    <label for="map_dropdown_button" class="display_map__label">
                        <i id="map_sig_button_icon" class="ri-arrow-down-s-line"></i>
                        <span id="map_sig_button_text">Afficher la carte</span>
                    </label>
                    <div class="tab__content">
                        <iframe style="width:100%%;border: 0 none; height: 600px;" src="%1$s"></iframe>
                    </div>
                ',
                OM_ROUTE_MAP."&mode=tab_sig&obj=".$this->get_default_om_sig_map()."&action=13&idx=".$this->getVal($this->clePrimaire)."&popup=1",

            );
        }


        return sprintf(
            '<article id="emplacement-adresse">
                <h2 class="article-tile">%1$s</h2>
                <div class="container">
                <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Placeat perspiciatis voluptatem laboriosam quos quam eveniet minima esse consequuntur</p>
                %2$s
                %3$s
                </div>
            </article>',
            _('Adresse'),
            $map_sig,
            $map_plan
        );
    }

    function getVisibleSteps(int $currentStep, int $totalSteps): array {
        // Définir les limites de la fenêtre
        $start = max(1, $currentStep - 1); // Une étape avant, sauf si on est à la première étape
        $end = min($totalSteps, $currentStep + 1); // Une étape après, sauf si on est à la dernière étape

        // Ajuster si la fenêtre ne couvre pas exactement 3 étapes
        if ($start === 1) {
            $end = min($totalSteps, 3);
        } elseif ($end === $totalSteps) {
            $start = max(1, $totalSteps - 2);
        }

        // Retourner les étapes visibles
        return range($start, $end);
    }



    /**
     * Affiche le contenu de la vue personnalisée
     *
     * @return void
     */
    function display__view_consulter_content() {

        // Initialisation et paramétrage de twig
        $loader = new \Twig\Loader\FilesystemLoader('../app/views');
        $twig = new \Twig\Environment($loader, [
            'cache' => PATH_TWIG_CACHE,
        ]);
        $twig->enableAutoReload();

        // $components correspond aux éléments affichés selon le type d'emplacement.
        // WIP : Une fonctionnalité d'emplacement personnalisé sera bientôt implémenté
        // et $components devra être actualisé
        $components = [];

        switch ($this->val[array_search('nature', $this->champs)]){
            case 'concession':
                $components = ['adresse', 'acte-concession', 'bati', 'abandon', 'gestion-place', 'observations', 'contrats', 'travaux', 'operations', 'contacts'];
                break;
            case 'colombarium':
                $components = ['adresse', 'acte-concession', 'bati', 'abandon', 'gestion-place', 'observations', 'contrats', 'travaux', 'operations', 'contacts'];
                break;
            case 'enfeu':
                $components = ['adresse', 'acte-concession', 'gestion-place', 'observations', 'contacts'];
                break;
            case 'ossuaire':
                $components = ['adresse', 'acte-concession', 'observations'];
                break;
            case 'depositoire':
                $components = ['adresse', 'acte-concession', 'observations'];
                break;
            case 'terraincommunal':
                $components = ['adresse', 'acte-concession',  'gestion-place', 'observations', 'travaux', 'operations', 'contacts'];
                break;
            default:
                $components = ['adresse', 'acte-concession', 'observations'];
                break;
        }

        // On définit $values, soit un tableau clé-valeur avec toutes les données souhaitées pour l'affichage
        // de la page de synthèse
        $values = [];
        foreach ($this->champs as $key => $champ){
            $values[$champ] = $this->val[$key];
        }
        $values["type"] = _($this->getVal('nature'));
        $values["reprise_sur_abandon"] = $this->get_last_reprise();
        if ($values["reprise_sur_abandon"]) {
            $values["reprise_sur_abandon"]['link'] = sprintf('%1$s&direct_link=true&obj=%2$s&action=3&idx=%3$s&direct_form=reprise_abandon&direct_action=3&direct_idx=%4$s',
            OM_ROUTE_FORM,
            "concession",
            $this->getVal("emplacement"),
            $this->getVal($values["reprise_sur_abandon"]['reprise_abandon'])
        );
        }

        $values["reprise_etapes_labels"] = [
                                    'Phase préliminaire',
                                    'Convocation première visite',
                                    'Rédaction PV1',
                                    'Notification / Affichage PV1',
                                    'Convocation deuxième visite',
                                    'Rédaction PV2',
                                    'Notification / Affichage PV2 ',
                                    'Délibération',
                                    'Arreté',
                                    ];

        $values['reprise_etapes_visibles'] = $this->get_last_reprise() ? $this->getVisibleSteps($values["reprise_sur_abandon"]["etat"], 9) : '';
        $values["sepulture_libelle"] = $this->get_sepulture_libelle();
        $values["contrats"] = $this->get_contrats();
        $values["travaux"] = $this->get_travaux();
        $values["operations"] = $this->get_operations();
        $values["contacts"] = $this->get_contacts();
        $values["option_localisation"] = $this->f->getParameter("option_localisation");
        $values["map_sig"] = OM_ROUTE_MAP."&mode=tab_sig&obj=".$this->get_default_om_sig_map()."&action=13&idx=".$this->getVal($this->clePrimaire)."&popup=1";
        // $values["map_plan"] = "../app/localisation_plan_view.php?idx=".$values["emplacement"]."&amp;obj=".$values["nature"]."&amp;retour=form#camap0";
        $values["map_plan"] = "../app/localisation_plan_view.php?idx=".$values["emplacement"]."&obj=".$values["nature"]."&retour=form#camap0";

        $url = '';
        if ($this->f->getParameter("option_localisation") == "sig_externe") {
            // Instance geocimetiere
            try {
                $geocimetiere = $this->f->get_geocimetiere_instance(true);
            } catch(geocimetiere_exception $e) {
                    $this->addToLog(
                        __METHOD__."() échec de l'instanciation du connecteur SIG. ".
                        gettype($e).": ".$e->getMessage(), DEBUG_MODE);
                    $this->f->handle_geocimetiere_exception($e);
            }
            if (! empty($geocimetiere)) {
                $url = $geocimetiere->redirection_web("emplacement");
            }
            if (! empty($url)) {
                $values['lien_sig_externe'] = $url.$this->getVal('emplacement');
            }
        }
        $values['components']= $components;

        // Rendu Twig
        try {
            echo $twig->render('emplacement/emplacement.html', $values);
        } catch (\Twig\Error\Error $e) {
            echo "Erreur Twig : " . $e->getMessage();
        }

        echo "<pre style=\"overflow:auto; height: 200px; margin-top:2em; background: #111; color: white\">" . json_encode($values, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)."</pre>";

    }

    /**
     * VIEW - view_redirect_nature.
     *
     * @return void
     */
    function view_redirect_nature() {
        $this->checkAccessibility();
        header(sprintf(
            'Location: %s&obj=%s&action=%s&idx=%s',
            OM_ROUTE_FORM,
            $this->getVal("nature"),
            "3",
            $this->getVal($this->clePrimaire)
        ));
        return;
    }

    /**
     * VIEW - view_summary.
     *
     * @return void
     */
    function view_summary() {
        $this->checkAccessibility();
        //
        $idx = $this->getVal($this->clePrimaire);
        // requêtes
        if (file_exists("../sql/".OM_DB_PHPTYPE."/emplacement.scr.inc.php")) {
            include "../sql/".OM_DB_PHPTYPE."/emplacement.scr.inc.php";
        }


        // Template d'un bloc d'information
        $template_bloc = '<div class="bloc %s-bloc-%s col_12"><div class="bloc-titre"><span class="text">%s</span></div>%s</div>';
        // Template d'un champ d'information de l'emplacement
        $template_field_empl = '<div class="field field-type-static"><div class="form-libelle"><label for="%1$s" class="libelle-%1$s" id="lib-%1$s">%2$s</label></div><div class="form-content"><span class="field_value" id="%1$s">%3$s</span></div></div>';
        // Template d'un tableau à 5 colonnes
        $template_table_5_columns = '<table id="%s" class="tab-tab %s"><thead><tr class="ui-tabs-nav ui-accordion ui-state-default tab-title"><th class="title">%s</th><th class="title">%s</th><th class="title">%s</th><th class="title">%s</th><th class="title">%s</th></tr></thead><tbody>%s</tbody></table>';
        // Template d'un tableau à 4 colonnes
        $template_table_4_columns = '<table id="%s" class="tab-tab %s"><thead><tr class="ui-tabs-nav ui-accordion ui-state-default tab-title"><th class="title">%s</th><th class="title">%s</th><th class="title">%s</th><th class="title">%s</th></tr></thead><tbody>%s</tbody></table>';
        // Template d'un tableau à 3 colonnes
        $template_table_3_columns = '<table id="%s" class="tab-tab %s"><thead><tr class="ui-tabs-nav ui-accordion ui-state-default tab-title"><th class="title">%s</th><th class="title">%s</th><th class="title">%s</th></tr></thead><tbody>%s</tbody></table>';
        // Template ligne et cellule d'un tableau
        $template_table_td = '<td class="%s">%s</td>';
        $template_table_tr = '<tr class="tab-data %s">%s</tr>';
        // Template lorsqu'il n'y a pas de resultat
        $template_colspan = '<td colspan="%s" align="center">%s</td>';
        // Template d'un lien
        $template_link_edition = '<a id="%1$s_%3$s" target="blank" href="../app/index.php?module=form&obj=%2$s&idx=%3$s%4$s" title="%5$s"><span class="om-prev-icon om-icon-16 pdf-16">%5$s</span></a>';
        // Template pour les téléchargement de dossier
        $template_link_dl_dossier = '<a id="%1$s_%2$s" target="blank" href="../app/index.php?module=form&snippet=file&uid=%2$s" title="%3$s"><span class="om-prev-icon om-icon-16 pdf-16">%3$s</span></a>';

        $res = $this->f->db->query($sql_emplacement);
        $this->addToLog(__METHOD__."(): db->query(\"".$sql_emplacement."\");", VERBOSE_MODE);
        $this->f->isDatabaseError($res);

        while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
            //Bloc n°1 - Informations de l'empalcement
            //Liste des champs composant les caractéristiques de l'emplacement
            $empl_fields = sprintf($template_field_empl, 'emplacement', 'Nature et Famille', trim($row["nature"]." ".$row["famille"]));
            $empl_fields .= sprintf($template_field_empl, 'emplacement', 'Adresse', trim($row["numero"]." ".$row["complement"]." ".$row["voietype"]." ".$row["voielib"]));
            $empl_fields .= sprintf($template_field_empl, 'emplacement', 'Emplacement cimetiere', trim($row["cimetierelib"]." ".$row["zonetype"]." ".$row["zonelib"]));
            $empl_fields .= sprintf($template_field_empl, 'emplacement', 'Observation', $row["observation"]);
            $bloc_empl = sprintf($template_bloc, 'emplacement', 'emplacement' ,__('emplacement'), $empl_fields);

            //Bloc n°2 - Informations des places
            $empl_fields = sprintf($template_field_empl, 'place', 'nombre de place(s) libre(s)', $row["nombreplace"]);
            $empl_fields .= sprintf($template_field_empl, 'place', 'nombre de place(s) occupée(s)', $row["placeoccupe"]);
            $empl_fields .= sprintf($template_field_empl, 'place', 'nombre de place(s)', $row["placeconstat"]);
            $empl_fields .= sprintf($template_field_empl, 'place', 'constate le', $row["dateconstat"]);
            $bloc_place = sprintf($template_bloc, 'place', 'place' ,__('place'), $empl_fields);

            //Bloc n°3 - Informations des defunts
            $res1=$this->f->db->query($sql_defunt);
            $this->addToLog(__METHOD__."(): db->query(\"".$sql_defunt."\");", VERBOSE_MODE);
            $this->f->isDatabaseError($res1);
            //
            $defunt_lines = '';
            $odd_even = 0;
            while ($row1=& $res1->fetchRow(DB_FETCHMODE_ASSOC)) {
                  $defunt_cells = sprintf($template_table_td, '', trim($row1['nom']." ".$row1['prenom']." ".$row1['marital']));
                  $defunt_cells .= sprintf($template_table_td, '', $row1['datenaissance']);
                  $defunt_cells .= sprintf($template_table_td, '', $row1['dateinhumation']);
                  $defunt_cells .= sprintf($template_table_td, '', $row1['dateexhumation']);
                  $defunt_cells .= sprintf($template_table_td, '', trim($row1['nature']." [".$row1['taille'].']'));
                  $defunt_lines .= sprintf($template_table_tr, ($odd_even % 2 == 0 ? 'odd' : 'even'), $defunt_cells);
                  $odd_even++;
            }

            if ($defunt_lines === '') {
                $defunt_lines = sprintf($template_colspan, 5, __('Aucun enregistrement.'));
            }

            $table_defunt = sprintf($template_table_5_columns, 'tab-defunt', 'ui-widget', __('nom'), __('né(e) le'), __('inhume le'), __('exhume le'), __('nature et place'), $defunt_lines);
            $bloc_defunt = sprintf($template_bloc, 'defunt', 'defunt', __('defunt'), $table_defunt);

            //Bloc n°4 - Informations des concessionnaires
            $res2=$this->f->db->query($sql_concessionnaire);
            $this->addToLog(__METHOD__."(): db->query(\"".$sql_concessionnaire."\");", VERBOSE_MODE);
            $this->f->isDatabaseError($res2);
            //
            $concess_lines = '';
            $odd_even = 0;
            while ($row2=& $res2->fetchRow(DB_FETCHMODE_ASSOC)) {
                $concess_cells = sprintf($template_table_td, '', trim($row2['nom']." ".$row2['prenom']." ".$row2['marital']));
                $concess_cells .= sprintf($template_table_td, '', $row2['datenaissance']);
                $concess_cells .= sprintf($template_table_td, '', $row2['dcd']);
                $concess_lines .= sprintf($template_table_tr, ($odd_even % 2 == 0 ? 'odd' : 'even'), $concess_cells);
                $odd_even++;
            }

            if ($concess_lines === '') {
                $concess_lines = sprintf($template_colspan, 3, __('Aucun enregistrement.'));
            }

            $table_concess = sprintf($template_table_3_columns, 'tab-concess', 'ui-widget', __('nom'), __('datenaissance'), 'dcd', $concess_lines);
            $bloc_concess = sprintf($template_bloc, 'concessionnaire', 'concessionnaire', __('concessionnaire'), $table_concess);

            //Bloc n°5 - Informations des ayantdroits
            $res3=$this->f->db->query($sql_ayantdroit);
            $this->addToLog(__METHOD__."(): db->query(\"".$sql_ayantdroit."\");", VERBOSE_MODE);
            $this->f->isDatabaseError($res3);
            //
            $ayantdroit_lines = '';
            $odd_even = 0;
            while ($row3=& $res3->fetchRow(DB_FETCHMODE_ASSOC)) {
                $ayantdroit_cells = sprintf($template_table_td, '', trim($row3['nom']." ".$row3['prenom']." ".$row3['marital']));
                $ayantdroit_cells .= sprintf($template_table_td, '', $row3['datenaissance']);
                $ayantdroit_cells .= sprintf($template_table_td, '', $row3['dcd']);
                $ayantdroit_cells .= sprintf($template_table_td, '', $row3['parente']);
                $ayantdroit_lines .= sprintf($template_table_tr, ($odd_even % 2 == 0 ? 'odd' : 'even'), $ayantdroit_cells);
                $odd_even++;
            }

            if ($ayantdroit_lines === '') {
                $ayantdroit_lines = sprintf($template_colspan, 4, __('Aucun enregistrement.'));
            }

            $table_ayantdroit = sprintf($template_table_4_columns, 'tab-concess', 'ui-widget', __('nom'), __('datenaissance'), __('dcd'), __('parente'), $ayantdroit_lines);
            $bloc_ayantdroit = sprintf($template_bloc, 'ayantdroit', 'ayantdroit', __('ayantdroit'), $table_ayantdroit);
            //Bloc n°6 - Informations des courriers
            $res4=$this->f->db->query($sql_courrier);
            $this->addToLog(__METHOD__."(): db->query(\"".$sql_courrier."\");", VERBOSE_MODE);
            $this->f->isDatabaseError($res4);

            $courrier_lines = '';
            $odd_even = 0;
            while ($row4=& $res4->fetchRow(DB_FETCHMODE_ASSOC)) {


                $courrier_edition = sprintf($template_link_edition, 'edition_courrier', 'courrier', $row4['id'], '&action=31', __("télécharger le courrier"));
                $courrier_cells = sprintf($template_table_td, '', $courrier_edition);
                $courrier_cells .= sprintf($template_table_td, '', $row4['nom']);
                $courrier_cells .= sprintf($template_table_td, '', $row4['lettretype']);
                $courrier_cells .= sprintf($template_table_td, '', $row4['date']);
                $courrier_lines .= sprintf($template_table_tr, ($odd_even % 2 == 0 ? 'odd' : 'even'), $courrier_cells);
                $odd_even++;
            }

            if ($courrier_lines === '') {
                $courrier_lines = sprintf($template_colspan, 4, __('Aucun enregistrement.'));
            }

            $table_courrier = sprintf($template_table_4_columns, 'tab-concess', 'ui-widget', __('id'), __('nom'), __('lettretype'), __('date'), $courrier_lines);
            $bloc_courrier = sprintf($template_bloc, 'courrier', 'courrier', __('courrier'), $table_courrier);

            //Bloc n°7 - Informations des operations
            $res5=$this->f->db->query($sql_operation);
            $this->f->isDatabaseError($res5);
            //
            $operation_lines = '';
            $odd_even = 0;
            while ($row5=& $res5->fetchRow(DB_FETCHMODE_ASSOC)) {
                $operation_cells = sprintf($template_table_td, '', $row5['numdossier']);
                $operation_cells .= sprintf($template_table_td, '', $row5['nom']);
                $operation_cells .= sprintf($template_table_td, '', $row5['categorie']);
                $operation_cells .= sprintf($template_table_td, '', $row5['date']);
                $operation_cells .= sprintf($template_table_td, '', $row5['etat']);
                $operation_lines .= sprintf($template_table_tr, ($odd_even % 2 == 0 ? 'odd' : 'even'), $operation_cells);
                $odd_even++;
            }

            if ($operation_lines === '') {
                $operation_lines = sprintf($template_colspan, 5, __('Aucun enregistrement.'));
            }

            $table_operation = sprintf($template_table_5_columns, 'tab-operation', 'ui-widget', __('numdossier'), __('nom'), __('categorie'), __('date'), __('etat') , $operation_lines);
            $bloc_operation = sprintf($template_bloc, 'operation', 'operation', __('operation'), $table_operation);

            //Bloc n°8 - Informations des dossiers
            $res6=$this->f->db->query($sql_dossier);
            $this->f->isDatabaseError($res6);

            $dossier_lines = '';
            $odd_even = 0;
            while ($row6=& $res6->fetchRow(DB_FETCHMODE_ASSOC)) {
                $dossier_dl = sprintf($template_link_dl_dossier, 'dl_dossier', $row6['fichier'], __("télécharger la pièce"));
                $dossier_cells = sprintf($template_table_td, '', $dossier_dl);
                $dossier_cells .= sprintf($template_table_td, '', $row6['date']);
                $dossier_cells .= sprintf($template_table_td, '', $row6['typedossier']);
                $dossier_lines .= sprintf($template_table_tr, ($odd_even % 2 == 0 ? 'odd' : 'even'), $dossier_cells);
                $odd_even++;
            }

            if ($dossier_lines === '') {
                $dossier_lines = sprintf($template_colspan, 3, __('Aucun enregistrement.'));
            }


            $table_dossier = sprintf($template_table_3_columns, 'tab-dossier', 'ui-widget', __('fichier'), __('date'), __('typedossier'), $dossier_lines);
            $bloc_dossier = sprintf($template_bloc, 'dossier', 'dossier', __('dossier'), $table_dossier);

            //Bloc n°9 - Informations des travaux
            $res7=$this->f->db->query($sql_travaux);
            $this->f->isDatabaseError($res7);
            //
            $travaux_lines = '';
            $odd_even = 0;

            while ($row7=& $res7->fetchRow(DB_FETCHMODE_ASSOC)) {
                $travaux_cells = sprintf($template_table_td, '', $row5['entreprise']);
                $travaux_cells .= sprintf($template_table_td, '', $row5['debut']);
                $travaux_cells .= sprintf($template_table_td, '', $row5['fin']);
                $travaux_cells .= sprintf($template_table_td, '', $row5['demandeur']);
                $travaux_cells .= sprintf($template_table_td, '', $row5['nature']);
                $travaux_lines .= sprintf($template_table_tr, ($odd_even % 2 == 0 ? 'odd' : 'even'), $travaux_cells);
                $odd_even++;
            }

            if ($travaux_lines === '') {
                $travaux_lines = sprintf($template_colspan, 5, __('Aucun enregistrement.'));
            }

            $table_travaux = sprintf($template_table_5_columns, 'tab-travaux', 'ui-widget', __('entreprise'), __('debut'), __('fin'), __('demandeur'), __('nature') , $travaux_lines);
            $bloc_travaux = sprintf($template_bloc, 'travaux', 'travaux', __('travaux'), $table_travaux);

            // Affichage de la fiche
            printf('<div class="formEntete ui-corner-all">%s%s%s%s%s%s%s%s%s</div>', $bloc_empl, $bloc_place, $bloc_defunt, $bloc_concess, $bloc_ayantdroit, $bloc_courrier, $bloc_operation, $bloc_dossier, $bloc_travaux);

        }
    }

    /**
     * Récupération des contrats
     *
     * @return string
     */
    function get_sepulture_libelle(){
        // Traitement de la première exécution
        if($this->getVal("sepulturetype") == NULL) return;

         $sql = sprintf(
            'SELECT
                sepulture_type.libelle
            FROM
                %2$s%1$s
            WHERE
                %1$s = %3$s
                ',
            'sepulture_type',
            DB_PREFIXE,
            $this->getVal("sepulturetype"),
        );

       // Exécution de la requête
       $res = $this->f->db->query($sql);
       $this->f->addToLog(__METHOD__.": db->query(\"".$sql."\")", VERBOSE_MODE);
       $this->f->isDatabaseError($res);

       // Stockage des contacts
       $sepulture_libelle = "";
       while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
           $sepulture_libelle = $row['libelle'];
       }
       return $sepulture_libelle;
    }


    /**
     * Récupération des contrats
     *
     * @return array
     */
    function get_contrats(){
        // Traitement de la première exécution
        if($this->getVal($this->clePrimaire) == NULL) return;

         $sql = sprintf(
            'SELECT
                %1$s.contrat,
                %1$s.emplacement,
                %1$s.datedemande,
                %1$s.datevente,
                %1$s.origine,
                %1$s.dateterme,
                %1$s.terme,
                %1$s.duree,
                %1$s.montant,
                %1$s.monnaie,
                %1$s.valide,
                %1$s.observation
            FROM
                %2$s%1$s
            WHERE
                %1$s.emplacement = %3$s
                ',
            'contrat',
            DB_PREFIXE,
            $this->getVal("emplacement"),
        );

       // Exécution de la requête
       $res = $this->f->db->query($sql);
       $this->f->addToLog(__METHOD__.": db->query(\"".$sql."\")", VERBOSE_MODE);
       $this->f->isDatabaseError($res);

       // Stockage des contacts
       $contrats = array();
       while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
            $row['onclick'] = "";
           array_push($contrats, $row);
       }
       return $contrats;
    }

    /**
     * Récupération des travaux
     *
     * @return array
     */
    function get_travaux(){
        // Traitement de la première exécution
        if($this->getVal($this->clePrimaire) == NULL) return;

         $sql = sprintf(
            'SELECT
                %1$s.travaux,
                entreprise.nomentreprise as entreprise,
                %1$s.datedebinter,
                %1$s.datefininter,
                %1$s.naturedemandeur,
                travaux_nature.libelle as naturetravaux,
                CONCAT(autorisation.prenom , \' \', autorisation.nom) as demandeur
            FROM
                %2$s%1$s
            LEFT JOIN
                %2$sentreprise on entreprise.entreprise = %1$s.entreprise
            LEFT JOIN
                %2$stravaux_nature on travaux_nature.travaux_nature = %1$s.naturetravaux
            LEFT JOIN
                %2$sautorisation on autorisation.autorisation = %1$s.demandeur
            WHERE
                %1$s.emplacement = %3$s
                ',
            'travaux',
            DB_PREFIXE,
            $this->getVal("emplacement"),
        );

       // Exécution de la requête
       $res = $this->f->db->query($sql);
       $this->f->addToLog(__METHOD__.": db->query(\"".$sql."\")", VERBOSE_MODE);
       $this->f->isDatabaseError($res);

       // Stockage des contacts
       $travaux = array();
       while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
           array_push($travaux, $row);
       }
       return $travaux;
    }

    /**
     * Récupération des travaux
     *
     * @return array
     */
    function get_operations(){
        // Traitement de la première exécution
        if($this->getVal($this->clePrimaire) == NULL) return;

         $sql = sprintf(
            'SELECT
                %1$s.operation,
                %1$s.numdossier,
                %1$s.date,
                %1$s.heure,
                %1$s.emplacement,
                %1$s.societe_coordonnee,
                %1$s.pf_coordonnee,
                %1$s.etat,
                %1$s.categorie,
                %1$s.particulier,
                %1$s.emplacement_transfert,
                %1$s.observation,
                %1$s.consigne_acces,
                %1$s.prive,
                %1$s.edition_operation,
                %1$s.consigne_acces_transfert,
                %1$s.demandeur
            FROM
                %2$s%1$s
            WHERE
                %1$s.emplacement = %3$s
                ',
            'operation',
            DB_PREFIXE,
            $this->getVal("emplacement"),
        );

       // Exécution de la requête
       $res = $this->f->db->query($sql);
       $this->f->addToLog(__METHOD__.": db->query(\"".$sql."\")", VERBOSE_MODE);
       $this->f->isDatabaseError($res);

       // Stockage des contacts
       $operations = array();
       while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
           array_push($operations, $row);
       }
       return $operations;
    }

    /**
     * Récupération des contacts
     *
     * @return array
     */
    function get_contacts(){
        // Traitement de la première exécution
        if($this->getVal($this->clePrimaire) == NULL) return;

         $sql = sprintf(
            'SELECT
                %1$s.autorisation,
                %1$s.emplacement,
                %1$s.nature,
                titre_de_civilite.libelle as titre,
                %1$s.nom,
                %1$s.marital,
                %1$s.prenom,
                %1$s.adresse1,
                %1$s.adresse2,
                %1$s.cp,
                %1$s.ville,
                %1$s.telephone1,
                %1$s.telephone2,
                %1$s.courriel
            FROM
                %2$s%1$s
            LEFT JOIN
                %2$stitre_de_civilite on titre_de_civilite.titre_de_civilite = %1$s.titre
            WHERE
                %1$s.emplacement = %3$s
                ',
            'autorisation',
            DB_PREFIXE,
            $this->getVal("emplacement"),
        );

       // Exécution de la requête
       $res = $this->f->db->query($sql);
       $this->f->addToLog(__METHOD__.": db->query(\"".$sql."\")", VERBOSE_MODE);
       $this->f->isDatabaseError($res);

       // Stockage des contacts
       $contacts = array();
       while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
           array_push($contacts, $row);
       }
       return $contacts;
    }

    /**
     * MERGE_FIELDS - merge_fields_to_avoid_obj.
     * @var array
     */
    var $merge_fields_to_avoid_obj = array(
        "photo",
    );

    /**
     * MERGE_FIELDS - get_labels_merge_fields.
     *
     * @return array
     */
    function get_labels_merge_fields() {
        $labels = parent::get_labels_merge_fields();
        //
        $labels["emplacement"]["emplacement.defunts"] = __("liste des défunts (format paragraphe par ordre alphabétique : PRENOM NOM D'USAGE né(e) NOM DE NAISSANCE décédé(e) le DATE DE DÉCÈS à LIEU DE DÉCÈS), ...");
        $labels["emplacement"]["emplacement.defunts_liste_tiret"] = __("liste à tiret qui affiche les défunts de l'emplacement (format paragraphe par ordre alphabétique : - PRENOM NOM D'USAGE né(e) NOM DE NAISSANCE décédé(e) le DATE DE DÉCÈS à LIEU DE DÉCÈS) ...");
        $labels["emplacement"]["emplacement.concessionnaires"] = __("liste des concessionnaires (format paragraphe par ordre alphabétique : PRÉNOM NOM D'USAGE né(e) NOM DE NAISSANCE, ...)");
        $labels["emplacement"]["emplacement.concessionnaires_avec_mention_deces"] = __("liste des concessionnaires (format paragraphe par ordre alphabétique : PRÉNOM NOM D'USAGE né(e) NOM DE NAISSANCE (concessionnaire décédé(e)), ...)");
        $labels["emplacement"]["emplacement.concessionnaires_avec_civilites"] = __("liste des concessionnaires (format paragraphe par ordre alphabétique : CIVILITE PRÉNOM NOM D'USAGE né(e) NOM DE NAISSANCE");
        $labels["emplacement"]["emplacement.concessionnaires_avec_titre_et_adresse"] = __("liste des concessionnaires (format paragraphe par ordre alphabétique : CIVILITE PRÉNOM NOM D'USAGE né(e) NOM DE NAISSANCE demeurant au ADRESSE1 ADRESSE2 CP VILLE");
        //
        $date_fields_to_format = array("dateacte", "datevente", "daterenouvellement", "dateterme", "date_abandon", "dateconstat", );
        foreach ($date_fields_to_format as $date_field_to_format) {
            $labels[$this->table][$this->table.".".$date_field_to_format."_format_jj_mois_aaaa"] = $labels[$this->table][$this->table.".".$date_field_to_format]." (Format : 14 janvier 1978)";
        }
        $labels["emplacement"]["emplacement.duree_lettre"] = __("durée en lettres");
        $labels["emplacement"]["emplacement.sepulturetype"]= _("type de sépulture");
        $labels["emplacement"]["emplacement.cimetierelib"]= _("libellé du cimetière lié à l'emplacement");
        $labels["emplacement"]["emplacement.cimetiereadresse"]= _("adresse du cimetière lié à l'emplacement");
        $labels["emplacement"]["emplacement.zone"]= _("libellé de la zone où se situe l'emplacement");
        //
        return $labels;
    }

    /**
     * MERGE_FIELDS - get_values_merge_fields.
     *
     * @return array
     */
    function get_values_merge_fields() {
        $values = parent::get_values_merge_fields();
        //
        $values["emplacement.defunts"] = "-";
        $values["emplacement.defunts_liste_tiret"] = "-";
        foreach ($this->get_defunts() as $key => $value) {
            if ($key == 0) {
                $values["emplacement.defunts"] = "";
                $values["emplacement.defunts_liste_tiret"] = "- ";
            } elseif ($key != 0) {
                $values["emplacement.defunts"] .= ", ";
                $values["emplacement.defunts_liste_tiret"] .= "<br />- ";
            }
            $display = "";
            $display .= $value["prenom"]." ";
            if (trim($value["marital"]) != "") {
                $display .= $value["marital"]." né(e) ";
            }
            $display .= $value["nom"]." ";
            if ($value["datedeces"] != "" || trim($value["lieudeces"]) != "") {
                $display .= "décédé(e) ";
                if ($value["datedeces"] != "") {
                    $date_value_formated = "-";
                    $date_value_as_string = $value["datedeces"];
                    if (!empty($date_value_as_string)
                        && preg_match('|^[0-9]{4}-[0-9]{2}-[0-9]{2}$|', $date_value_as_string)) {
                        //
                        $date_value_as_object = DateTime::createFromFormat('Y-m-d', $date_value_as_string);
                        $date_value_formated = strftime('%d %B %Y', $date_value_as_object->getTimestamp());
                    }
                    $display .= "le ".$date_value_formated." ";
                }
                if (trim($value["lieudeces"]) != "") {
                    $display .= "à ".$value["lieudeces"]." ";
                }
            }
            $values["emplacement.defunts"] .= trim($display);
            $values["emplacement.defunts_liste_tiret"] .= trim($display);
        }
        $values["emplacement.concessionnaires"] = "-";
        $values["emplacement.concessionnaires_avec_mention_deces"] = "-";
        $values["emplacement.concessionnaires_avec_civilites"] = "-";
        $values["emplacement.concessionnaires_avec_titre_et_adresse"] = "-";
        foreach ($this->get_concessionnaires() as $key => $value) {
            if ($key == 0) {
                $values["emplacement.concessionnaires"] = "";
                $values["emplacement.concessionnaires_avec_mention_deces"] = "";
                $values["emplacement.concessionnaires_avec_civilites"] = "";
                $values["emplacement.concessionnaires_avec_titre_et_adresse"] = "";
            } elseif ($key != 0) {
                $values["emplacement.concessionnaires"] .= ", ";
                $values["emplacement.concessionnaires_avec_mention_deces"] .= ", ";
                $values["emplacement.concessionnaires_avec_civilites"] .= ", ";
                $values["emplacement.concessionnaires_avec_titre_et_adresse"] .= ",<br/>";
            }
            $display = "";
            $display .= $value["prenom"]." ";
            if (trim($value["marital"]) != "") {
                $display .= $value["marital"]." né(e) ";
            }
            $display .= $value["nom"]." ";
            $values["emplacement.concessionnaires"] .= trim($display);
            $values["emplacement.concessionnaires_avec_civilites"] .= trim($value['titre_de_civilite'].' '.$display);
            if ($value["dcd"] == "t") {
                $display .= "(concessionnaire décédé(e)) ";
            }
            $values["emplacement.concessionnaires_avec_mention_deces"] .= trim($display);
            $display = trim($value['titre_de_civilite'].' '.$display);
            $display .= " demeurant au ";
            $display .= $value["adresse1"]." ";
            $display .= $value["adresse2"]." ";
            $display .= $value["cp"]." ";
            $display .= $value["ville"];
            $values["emplacement.concessionnaires_avec_titre_et_adresse"] .= trim($display);
        }
        //
        $date_fields_to_format = array("dateacte", "datevente", "daterenouvellement", "dateterme", "date_abandon", "dateconstat", );
        foreach ($date_fields_to_format as $date_field_to_format) {
            $values[$this->table.".".$date_field_to_format."_format_jj_mois_aaaa"] = '';
            $date_value_as_string = $this->getVal($date_field_to_format);
            if (!empty($date_value_as_string)
                && preg_match('|^[0-9]{4}-[0-9]{2}-[0-9]{2}$|', $date_value_as_string)) {
                //
                $date_value_as_object = DateTime::createFromFormat('Y-m-d', $date_value_as_string);
                $values[$this->table.".".$date_field_to_format."_format_jj_mois_aaaa"] = strftime('%d %B %Y', $date_value_as_object->getTimestamp());
            }
        }
        $inst_sepulturetype = $this->f->get_inst__om_dbform(array(
            "obj" => "sepulture_type",
            "idx" => $this->getVal("sepulturetype"),
        ));
        $values["emplacement.sepulturetype"] = $inst_sepulturetype->getVal("libelle");
        if ($inst_sepulturetype->getVal("libelle_edition") != null && $inst_sepulturetype->getVal("libelle_edition") != '') {
            $values["emplacement.sepulturetype"] = $inst_sepulturetype->getVal("libelle_edition");
        }
        //
        require_once "../app/php/misc/chiffreenlettre.class.php";
        $lettre = new ChiffreEnLettre();
        $lettre->init();
        $values["emplacement.duree_lettre"] = trim(strtolower($lettre->Conversion($this->getVal("duree"))));
        //
        $values["emplacement.observation"] = str_replace("\n", "<br/>", $values["emplacement.observation"]);

        $values["emplacement.cimetierelib"] = $this->get_cimetierelib();
        $values["emplacement.cimetiereadresse"] = $this->get_cimetiere_adresse();
        $values["emplacement.zonelib"] = $this->get_zonelib();

        return $values;
    }

    /**
     * MERGE_FIELDS - get_all_merge_fields.
     *
     * @return array
     */
    function get_all_merge_fields($type) {
        //
        $all = array(
        );
        //
        switch ($type) {
            case 'values':
                //
                $values = $this->get_values_legacy_merge_fields();
                foreach ($all as $table => $field) {
                    $elem = $this->f->get_inst__om_dbform(array(
                        "obj" => $table,
                        "idx" => $this->getVal($field),
                    ));
                    $elem_values = $elem->get_merge_fields($type);
                    $values = array_merge($values, $elem_values);
                }
                return $values;
                break;
            case 'labels':
                //
                $labels = $this->get_labels_legacy_merge_fields();
                foreach ($all as $table => $field) {
                    $elem = $this->f->get_inst__om_dbform(array(
                        "obj" => $table,
                        "idx" => 0,
                    ));
                    $elem_labels = $elem->get_merge_fields($type);
                    $labels = array_merge($labels, $elem_labels);
                }
                return $labels;
                break;
            default:
                return array();
                break;
        }
    }

    /**
     * MERGE_FIELDS - get_values_legacy_merge_fields.
     *
     * @return array
     */
    function get_values_legacy_merge_fields() {
        $sql = sprintf(
            'SELECT
                emplacement,
                famille,
                numero,
                complement,
                voie_type.libelle as type_de_voie,
                voielib,
                zone_type.libelle as type_de_zone,
                zonelib,
                cimetierelib,
                typeconcession,
                placeconstat,
                to_char(dateconstat,\'DD/MM/YYYY\') as dateconstat,
                nombreplace,
                placeoccupe,
                superficie

            FROM
                %1$semplacement
                LEFT JOIN %1$svoie on emplacement.voie = voie.voie
                LEFT JOIN %1$svoie_type on voie.voietype = voie_type.voie_type
                LEFT JOIN %1$szone on voie.zone = zone.zone
                LEFT JOIN %1$szone_type on zone.zonetype = zone_type.zone_type
                LEFT JOIN %1$scimetiere on zone.cimetiere = cimetiere.cimetiere

            WHERE
                emplacement=%2$s',
            DB_PREFIXE,
            intval($this->getVal($this->clePrimaire))
        );
        $res = $this->f->db->query($sql);
        $this->f->isDatabaseError($res);
        while ($row =& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
            return $row;
        }
        return array();
    }

    /**
     * MERGE_FIELDS - get_labels_legacy_merge_fields.
     *
     * @return array
     */
    function get_labels_legacy_merge_fields() {
        return array(
            "legacy" => array(
                //
                "emplacement" => "",
                "famille" => "",
                "numero" => "",
                "complement" => "",
                "typeconcession" => "",
                "placeconstat" => "",
                "dateconstat" => "",
                "nombreplace" => "",
                "placeoccupe" => "",
                "superficie" => "",
                //
                "type_de_voie" => "",
                "voielib" => "",
                //
                "type_de_zone" => "",
                "zonelib" => "",
                //
                "cimetierelib" => "",
            ),
        );
    }


    /**
     * VIEW - view_plan_en_coupe
     *
     * Permet d'afficher le plan en coupe de l'emplacement.
     *
     * @return void
     */
    function view_plan_en_coupe() {
        $this->f->displaySubTitle(" -> ".__("Plan en coupe de l'emplacement"));
        // Paramétrage des champs du formulaire
        $champs = array();
        // Création d'un nouvel objet de type formulaire
        $form = $this->f->get_inst__om_formulaire(array(
            "validation" => 0,
            "maj" => 0,
            "champs" => $champs,
        ));

        $inst_sepulturetype = $this->f->get_inst__om_dbform(array(
            "obj" => "sepulture_type",
            "idx" => $this->getVal("sepulturetype"),
        ));

        $colonnes = $inst_sepulturetype->getVal('colonne');
        $lignes = $this->getVal('videsanitaire') == "Oui" ? $inst_sepulturetype->getVal('ligne') + 1 : $inst_sepulturetype->getVal('ligne');

        // Instanciation de l'objet défunt afin de récupérer le tableau
        // de traduction des natures d'enveloppes mortuaires
        $inst_defunt = $this->f->get_inst__om_dbform(array(
            "obj" => "defunt",
            "idx" => "]",
        ));

        // Début d'affichage de la vue plan en coupe
        $this->f->layout->display__form_container__begin(array(
            "id" => "plan_en_coupe",
            "action" => $this->getDataSubmit()
        ));
        $this->retour();
        $this->f->displayDescription($inst_sepulturetype->getVal('libelle')."<br />".$this->getVal('description'));

        $this->view_maj_etat_case_pec($colonnes, $lignes);

        // Requête qui récupère les coordonnées de chaque défunt et les champs :
        // IDENTIFIANT - NOM NOM-USAGE PRENOM
        $sql = sprintf("
            SELECT
                defunt, x, y, nom, marital, prenom, nature
            FROM
                %sdefunt
            WHERE
                emplacement = %s
            ",
            DB_PREFIXE,
            $this->getVal($this->clePrimaire)
        );

        $defunts = $this->f->get_all_results_from_db_query($sql);
        // Gérer le message d'erreur

        // Affichage de l'entête du formulaire
        $form->entete();

        $card_defunt_template = '
        <div class="widget ui-widget ui-widget-content defunt_card defunt-nature--%3$s" onmouseup="maj_pos_defunt(this);" id="widget_%1$s">
            <div class="card-header widget-header-move ui-widget-header">
            <!-- IDENTIFIANT - NOM NOM USAGE PRENOM -->
                <h3 id="defunt_card-name"> %2$s </h3>
                <p class="defunt_card-nature "> %3$s </p>
            </div>
            <!-- Start Widget Content -->
            <div class="widget-content ">
                <a onclick="overlay_defunt(%1$s);" class="link_defunt lienFormulaire ">
                    Voir plus
                </a>
            </div>
        </div>';

        // Pour chaque défunt on construit une carte
        // Initialisation du tableau des cartes de défunt
        // Récupération des coordonnées de chaque défunt dans un tableau
        /**  array(
         *    <identifiant de défunt> =>
         *     'card' => <code html de la carte de défunt>,
         *     'coordonnees' => array(
         *       'x' => <valeur>,
         *       'y' => <valeur>,
         *     ),
         *    ),
         *   )
         */
        $liste_carte_defunts = array();
        // Liste des défunts non placés
        $defunts_non_place = array();
        // On boucle sur chaque défunt
        foreach ($defunts['result'] as $defunt) {
            // Pour chaque défunt, création et stockage de la carte et des coordonnées
            $liste_carte_defunts[$defunt['defunt']]['card'] = sprintf(
                $card_defunt_template,
                $defunt['defunt'],
                $defunt['defunt'].' - '.$defunt['nom'].' '.$defunt['marital'].' '.$defunt['prenom'],
                __($inst_defunt->mapping_nature_defunt[$defunt['nature']]['trad'])
            );
            $liste_carte_defunts[$defunt['defunt']]['coordonnees'] = array(
                'x' => $defunt['x'],
                'y' => $defunt['y'],
            );
            // Si x et y sont null alors on récupère l'identifiant du défunt
            // dans le tableau defunt_non_place
            if ($defunt['x'] == NULL && $defunt['y'] == NULL) {
                $defunts_non_place[] = $defunt['defunt'];
            }
        }

        // On vérifie que l'utilisateur peux positionner des défunt
        $class_column_locked = "column";
        if ($this->f->isAccredited("defunt_positionner") == false) {
            $class_column_locked = "column_locked";
        }

        // Balise permettant de mettre en place le fonctionnement js
        // similaire à la composition du tableau de bord pour les widget
        echo'<div id="dashboard"><div id="plan-en-coupe-container">';
        // Ouverture de la liste des défunts non placés
        echo '<div id="column" class="liste_defunt '.$class_column_locked.' ui-sortable">';
        // Pour chaque identifiant de défunt non placé on affiche la carte correspondante
        foreach ($defunts_non_place as $defunt_np) {
            echo $liste_carte_defunts[$defunt_np]['card'];
        }
        // Fermeture de la liste des défunts
        echo "</div>";

        $this->create_grille($liste_carte_defunts, $colonnes, $lignes);
        echo "</div>";

        printf(
                '<a id="plancoupe-href-base" href="%s" style="display:none">&nbsp;</a>',
                OM_ROUTE_FORM."&obj=emplacement&idx=".$this->getVal('emplacement')."&action=41"
            );
        $form->enpied();
        // Fermeture du fomulaire
        $this->f->layout->display__form_controls_container__end();
        $this->retour();
        $this->f->layout->display__form_container__end();
    }


    /**
     * Permet de créer la grille du plan en coupe et de placer les défunts dans les cases
     * si il y en a
     *
     * @param array $liste_carte_defunts Contient les coordonnées des défunt placés
     * @param int $colonnes Permet de déterminer le nombre de colonnes
     * @param int $lignes Permet de déterminer le nombre de lignes
     *
     * @return void
     */
    function create_grille($liste_carte_defunts, $colonnes, $lignes) {
        // On vérifie si le vide sanitaire existe afin d'ajouter une classe 'vide-sanitaire'
        // au container de la grille, et on passe des attributs personnalisés pour  avoir
        // facilement accès à la valeur du nombre de lignes et au nombre de colonnes
        $is_videsanitaire = $this->getVal('videsanitaire') === 'Oui' ? 'vide-sanitaire' : '';
        echo '<div id="grid_defunt_container" class="'. $is_videsanitaire .'" data-plan-coupe-colonnes="'.$colonnes.'" data-plan-coupe-lignes="'.$lignes.'">';

        $inst_emplacement = $this->f->get_inst__om_dbform(array(
            "obj" => "emplacement",
            "idx" => $this->getVal('emplacement'),
        ));

        $etat_case_pec = json_decode(str_replace("'", '"', $inst_emplacement->getVal('etat_case_plan_en_coupe')), true);

        // Début du template cellule tableau plan en coupe
        $template_grille_begin = '
            <div class="column_%s col%s line%s grid_defunt %s ui-sortable %s %s">
        ';

        $class_hide_button = "";
        if ($this->f->isAccredited('emplacement_verrouiller') == false) {
            $class_hide_button = "hide_button";
        }

        // On boucle sur chaque colonne
        for ($col=1; $col <= $colonnes; $col++) {
            // On boucle sur chaque ligne
            for ($line=1; $line <= $lignes; $line++) {
                $is_locked = true;
                if (empty($etat_case_pec) || $etat_case_pec["$col;$line"]['etat'] == 'nv') {
                    $is_locked = false;
                }

                // Si l'utilisateur n'as pas le droit de positionner des défunts
                // alors on bloque les cases
                $class_locked_by_right = "column";
                if ($this->f->isAccredited("defunt_positionner") == false) {
                    $class_locked_by_right = "column_locked";
                }

                $lockCellClass = $is_locked ? "cellLocked" : "cellUnlocked";

                // Début de la case
                printf(
                    $template_grille_begin,
                    $col.'_'.$line,
                    $col,
                    $line,
                    $class_locked_by_right,
                    $lockCellClass,
                    $class_hide_button
                );

                $iconClass = $is_locked ? "./img/lock/lock.svg#ri-lock-fill" : "./img/lock/unlock.svg#ri-lock-unlock-fill";

                if ($is_locked == true) {
                    echo    "
                            <span>Emplacement verrouillé</span>
                            ";
                }

                $is_filled = false;
                foreach ($liste_carte_defunts as $defunt) {
                    if ($defunt['coordonnees']['x'] !== ""
                        && $defunt['coordonnees']['y'] !== ""
                        && $defunt['coordonnees']['x'] == $col
                        && $defunt['coordonnees']['y'] == $line) {
                        echo $defunt['card'];
                    }
                }

                echo '
                    <button type="button" id="but_case_'.$col."_".$line.'" onclick="maj_etat_case(this, \''.$col.';'.$line.'\');lock_unlock_field(this)">
                        <svg class="remix">
                            <use xlink:href="'.$iconClass.'">
                            </use>
                        </svg>
                    </button>
                    ';
                // fin de la case
                echo '</div>';
            }
        }
        echo '</div>';
    }


    /**
     * view_maj_etat_case_pec
     *
     * Permet de mettre à jour le champ contenant les états
     * de chaque case du plan en coupe
     *
     * @param int $colonnes Permet de déterminer le nombre de colonnes
     * @param int $lignes Permet de déterminer le nombre de lignes
     *
     * @return void
     */

    function view_maj_etat_case_pec($colonnes = null, $lignes = null) {
        $etat_case_pec = $this->getVal('etat_case_plan_en_coupe');

        $coordonnees = $this->f->get_submitted_get_value("coordonnees");

        $valF = array();

        $valF['etat_case_plan_en_coupe'] = $this->compose_schema_pec($colonnes, $lignes);

        // Si le champ n'est pas vide
        if (! empty($etat_case_pec) && ! empty($coordonnees)) {
            $etat_case_pec_decoded = json_decode(str_replace("'", '"', $etat_case_pec), true);

            if ($etat_case_pec_decoded[$coordonnees]['etat'] == 'v') {
                $etat_case_pec_decoded[$coordonnees]['etat'] = 'nv';
            } else if ($etat_case_pec_decoded[$coordonnees]['etat'] == 'nv') {
                $etat_case_pec_decoded[$coordonnees]['etat'] = 'v';
            }

            $valF['etat_case_plan_en_coupe'] = json_encode($etat_case_pec_decoded);
        }

        if (! empty($valF)) {
            $cle = " emplacement = ".$this->getVal($this->clePrimaire);
            $res = $this->f->db->autoExecute(
                DB_PREFIXE.'emplacement',
                $valF,
                DB_AUTOQUERY_UPDATE,
                $cle
            );

            // On log l'autoExecute
            $this->f->addToLog(__METHOD__."(): db->autoExecute(\"".DB_PREFIXE."emplacement\", ".print_r($valF, true).", DB_AUTOQUERY_UPDATE, \"".$cle."\");", VERBOSE_MODE);
        }
    }

    /**
     * compose_schema_pec
     *
     * Permet de construire le schema du plan en coupe
     * retourné en chaîne de caractère, la structure de
     * cette chaîne doit être en json.
     *
     * @param int $colonnes Permet de déterminer le nombre de colonnes
     * @param int $lignes Permet de déterminer le nombre de lignes
     *
     * v=vérouillé
     * nv= non-vérouillé
     *
     *  Structure json :
     * {
     *  "x,y" => {
     *            "etat" : "v"/"nv"
     *         },
     *  "x,y" => {
     *            "etat" : "v"/"nv"
     *         }
     * }
     * @return string|NULL
     */
    function compose_schema_pec($colonnes, $lignes) {
        $tab_etat_case = array();
        $tab_etat_case_before = json_decode(str_replace("'", '"', $this->getVal('etat_case_plan_en_coupe')), true);
        // On boucle sur chaque colonne
        for ($col=1; $col <= $colonnes; $col++) {
            // On boucle sur chaque ligne
            for ($line=1; $line <= $lignes; $line++) {
                $tab_etat_case["$col;$line"] = array("etat" => "nv");
                // On gère les cases déjà verouillées si il y a un ancien pec
                if (! empty($tab_etat_case_before) && isset($tab_etat_case_before["$col;$line"])) {
                    $tab_etat_case["$col;$line"] = $tab_etat_case_before["$col;$line"];
                }
            }
        }

        return empty($tab_etat_case) ? NULL : json_encode($tab_etat_case);
    }

    /**
     * METHOD get_nb_mort_pour_la_france
     *
     * Permet de récupérer le nombre de défunts
     * morts pour la france
     *
     * @return int
     */
    function get_nb_mort_pour_la_france() {
        $qres = $this->f->get_one_result_from_db_query(sprintf(
            'SELECT
                count(*)
            FROM
                %1$sdefunt
            WHERE
                mort_pour_la_france = \'Oui\'
                AND emplacement = %2$s',
            DB_PREFIXE,
            $this->getVal('emplacement')
        ));

        return $qres['result'];
    }
}
