<?php
/**
 * DBFORM - 'demande_nouveau_dossier' - Surcharge obj.
 *
 * Ce script permet de définir la classe 'demande_nouveau_dossier'.
 *
 * @package openads
 * @version SVN : $Id: demande_nouveau_dossier.class.php 5984 2016-02-19 08:41:12Z fmichon $
 */

require_once "../obj/demande.class.php";

/**
 * Définition de la classe 'demande_nouveau_dossier'.
 *
 * Cette classe permet d'interfacer l'ajout de demande concernant un nouveau
 * dossier.
 */
class demande_nouveau_dossier extends demande {

    /**
     *
     */
    protected $_absolute_class_name = "demande_nouveau_dossier";

    /**
     * Surcharge du bouton retour afin de retourner sur le dashboard
     */
    function retour($premier = 0, $recherche = "", $tricol = "") {

        echo "\n<a class=\"retour\" ";
        echo "href=\"".OM_ROUTE_DASHBOARD;
        //
        echo "\"";
        echo ">";
        //
        echo __("Retour");
        //
        echo "</a>\n";

    }

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

        // ACTION - 140 - Récupération du code du type de DA
        $this->class_actions[140] = array(
            "identifier" => "get_code_type_da",
            "view" => "view_get_code_type_da",
            "permission_suffix" => "ajouter"
        );

        // ACTION - 141 - Récupération du code département et commune de la collectivité
        $this->class_actions[141] = array(
            "identifier" => "get_code_depcom",
            "view" => "view_get_code_depcom",
            "permission_suffix" => "ajouter"
        );

        // ACTION - 142 - Récupération de la prochaine séquence du numéro de dossier
        $this->class_actions[142] = array(
            "identifier" => "get_dossier_seq_currval",
            "view" => "view_get_dossier_seq_currval",
            "permission_suffix" => "ajouter"
        );

        // ACTION - 143 - Récupération de la division depuis l'instructeur
        // affecté automatiquement
        $this->class_actions[143] = array(
            "identifier" => "get_dossier_division",
            "view" => "view_get_dossier_division",
            "permission_suffix" => "ajouter"
        );

        // ACTION - 150 - Récupération de l'affectation automatique
        // affecté automatiquement
        $this->class_actions[150] = array(
            "identifier" => "get_affectation_auto",
            "view" => "view_get_affectation_auto",
            "permission_suffix" => "ajouter"
        );

        $this->class_actions[160] = array(
            "identifier" => "verifier_numerotation_urbanisme",
            "view" => "view_verifier_numerotation_urbanisme",
            "permission_suffix" => "ajouter"
        );

        // ACTION - 170 - Récupération d'un text traduisible
        $this->class_actions[170] = array(
            "identifier" => "get_translatable_text",
            "view" => "view_get_translatable_text",
            "permission_suffix" => "ajouter"
        );

        // ACTION - 180 - Récupération des données du demandeur en lien
        // avec le DI courant
        $this->class_actions[180] = array(
            "identifier" => "message_DI_exist_on_demande_nouveau_dossier",
            "view" => "view_message_DI_exist_on_demande_nouveau_dossier",
            "permission_suffix" => "ajouter"
        );
    }

    /**
     * Indique si la redirection vers le lien de retour est activée ou non.
     *
     * L'objectif de cette méthode est de permettre d'activer ou de désactiver
     * la redirection dans certains contextes.
     *
     * @return boolean
     */
    function is_back_link_redirect_activated() {
        //
        return false;
    }

    /**
     * Concatenation du code département et du code commune
     * obtenus à partir de la collectivité (collectivité par défaut si aucun id fourni).
     * Renvoie un tuple (code_depcom, error_msg).
     */
    function getCodeDepartementCommuneFromCollectivite($collectivite_id)
    {
        $code_depcom = null;
        $error_msg = null;
        if (!empty($collectivite_id)) {
            $collectivite_parameters = $this->f->getCollectivite($collectivite_id);
        }
        else {
            $collectivite_parameters = $this->f->getCollectivite();
        }
        if (!empty($collectivite_parameters)) {
            if (!isset($collectivite_parameters['departement'])) {
                $error_msg = sprintf(__("om_parametre '%s' inexistant"), 'departement');
            }
            else if (!isset($collectivite_parameters['commune'])) {
                $error_msg = sprintf(__("om_parametre '%s' inexistant"), 'commune');
            }
            else {
                $code_departement = strtoupper($collectivite_parameters['departement']);
                $code_commune = $collectivite_parameters['commune'];
                if(!is_numeric($code_departement) && ! in_array($code_departement, array('02A', '02B'))) {
                    $error_msg = sprintf(__("om_parametre '%s' invalide (%s). Doit être numérique ou 02A|02B."),
                                         'departement', $code_departement);
                }
                else if (!is_numeric($code_commune)) {
                    $error_msg = sprintf(__("om_parametre '%s' invalide (%s). Doit être numérique."),
                                         'commune', $code_commune);
                }
                else {
                    $code_depcom = $code_departement . $code_commune;
                }
            }
        }
        else {
            $error_msg = sprintf(__("Aucun om_parametre pour la collectivité '%s'."),
                                 $collectivite_id ? $collectivite_id : 'par défaut');
        }
        if (!empty($error_msg)) {
            $this->f->addToLog(__METHOD__."(): ERROR $error_msg", DEBUG_MODE);
        }
        return array($code_depcom, $error_msg);
    }

    /**
     * Code du Type de DA
     * obtenu à partir de l'id du DAdt.
     * Renvoie un tuple (code_type_da, error_msg).
     */
    function getCodeTypeDA($dadt_id)
    {
        $code_type_da = null;
        $error_msg = null;
        if (!empty($dadt_id)) {
            // instance du DAdt
            // TODO: replace with '$this->f->findObjectById' ?
            $inst_datd = $this->get_inst_common("dossier_autorisation_type_detaille", $dadt_id);
            if (!empty($inst_datd)) {
                // id du type DA
                $type_da = $inst_datd->getVal('dossier_autorisation_type');
                if (!empty($type_da)) {
                    // instance du DA
                    // TODO: replace with '$this->f->findObjectById' ?
                    $inst_da = $this->get_inst_common("dossier_autorisation_type", $type_da);
                    if (!empty($inst_da)) {
                        // code du DA
                        $code_type_da = $inst_da->getVal('code');
                        if (empty($code_type_da)) {
                            $error_msg = sprintf(__("Empty code for type DA '%s'"), $type_da);
                        }
                    }
                    else {
                        $error_msg = sprintf(__("Type DA '%s' not found"), $type_da);
                    }
                }
                else {
                    $error_msg = sprintf(__("Empty type DA for DAdt '%'"), $dadt_id);
                }
            }
            else {
                $error_msg = sprintf(__("Type DAdt '%s' not found"), $dadt_id);
            }
        }
        else {
            $error_msg = __("Empty type DAdt");
        }
        if (!empty($error_msg)) {
            $this->f->addToLog(__METHOD__."(): ERROR $error_msg", DEBUG_MODE);
        }
        return array($code_type_da, $error_msg);
    }

    /**
     * Récupère la valeur courante de la séquence.
     *
     * @return array
     */
    function getNumeroDossierSequenceCurrval($code_type_da, $annee, $departement, $commune) {
        $seq_currval = null;
        $error_msg = null;
        foreach(array('code_type_da', 'annee', 'departement', 'commune') as $varname) {
            if(empty($$varname)) {
                $error_msg = sprintf(__("Argument '%s' vide non permis"), $varname);
                $this->f->addToLog(__METHOD__."(): ERROR $error_msg", DEBUG_MODE);
                return array($seq_currval, $error_msg);
            }
        }
        // obliger d'instancier un DA pour accéder à la méthode 'getMaxDANumeroDossier()'
        $empty_da = $this->f->get_inst__om_dbform(array(
            "obj" => "dossier_autorisation",
            "idx" => 0,
        ));
        $seq_currval = $empty_da->getMaxDANumeroDossier(
            $code_type_da,
            $annee,
            $departement,
            $commune
        );
        if ($seq_currval === null) {
            $error_msg = sprintf(__("Failed to get current value of sequence '%s'"),
                                    $seq_name);
        }
        if (!empty($error_msg)) {
            $this->f->addToLog(__METHOD__."(): ERROR $error_msg", DEBUG_MODE);
        }
        return array($seq_currval, $error_msg);
    }

    /**
     * VIEW - view_get_code_depcom
     *
     * Vue pour récupérer en json le code du département et le code commune de
     * la collectivité passée dans l'URL.
     *
     * @return void
     */
    function view_get_code_depcom() {
        $this->f->disableLog();
        $response = array();

        // si l'option dossier_commune est activée et qu'on a l'ID de la commune
        $commune_id = $this->f->get_submitted_get_value('commune_id');
        if ($this->f->is_option_dossier_commune_enabled() && !empty($commune_id)) {
            list($code_depcom, $err_msg) = $this->getCodeDepartementCommuneFromCommune(
                intval($commune_id));
        }
        // pas d'option dossier_commune : infos à partir des paramètres de la collectivité
        else {
            $collectivite_id = $this->f->get_submitted_get_value('collectivite_id');
            list($code_depcom, $err_msg) = $this->getCodeDepartementCommuneFromCollectivite(
                $collectivite_id);
        }
        if (!empty($code_depcom) && empty($err_msg)) {
            $response = array('code_depcom' => $code_depcom);
        }
        else if (!empty($err_msg)) {
            $response = array('error' => $err_msg);
        }
        printf(json_encode($response));
    }

    /**
     * VIEW - view_get_code_type_da
     *
     * Vue pour récupérer en json le code du type de dossier d'autorisation du
     * type de DAdt passé dans l'URL.
     *
     * @return void
     */
    function view_get_code_type_da() {
        $this->f->disableLog();
        $response = array();

        // id du type de DAdt
        $dadt = $this->f->get_submitted_get_value('type_dadt');
        list($code_type_da, $err_msg) = $this->getCodeTypeDA($dadt);
        if(!empty($err_msg)) {
            $response = array('error' => $err_msg);
        }
        else {
            $response = array('code_type_da' => $code_type_da,);
        }
        printf(json_encode($response));
    }

    /**
     * VIEW - view_get_dossier_seq_currval
     *
     * Vue pour récupérer la valeur courante de la séquence en json.
     * Le type du DA, l'année de la date de la demande, le code département et
     * le code commune composant la séquence sont passés dans l'URL.
     *
     * @return void
     */
    function view_get_dossier_seq_currval() {
        $this->f->disableLog();
        $response = array();

        // code du type de DA
        $code_type_da = $this->f->get_submitted_get_value('type_da');
        // annee date demande
        $annee = $this->f->get_submitted_get_value('date_demande_annee');
        // code département et commune (concaténés)
        $code_depcom = $this->f->get_submitted_get_value('code_depcom');

        $departement = $code_depcom ? substr($code_depcom, 0, 3) : null;
        $commune = $code_depcom ? substr($code_depcom, 3) : null;

        list($seq_currval, $err_msg) = $this->getNumeroDossierSequenceCurrval(
            $code_type_da, $annee, $departement, $commune);
        if (!empty($err_msg)) {
            $response = array('error' => $err_msg);
        }
        else {
            $response = array('seq_currval' => $seq_currval,);
        }

        printf(json_encode($response));
    }

    /**
     * VIEW - view_get_dossier_division
     *
     * Vue pour récupérer la valeur courante de la séquence en json.
     * Le type du DA, l'année de la date de la demande, le code département et
     * le code commune composant la séquence sont passés dans l'URL.
     *
     * @return void
     */
    function view_get_dossier_division() {
        $this->f->disableLog();
        $response = array();

        // Identifiant de la collectivité
        $om_collectivite = intval($this->f->get_submitted_get_value('om_collectivite'));

        // Identifiant de la commune
        $commune_id = 0;
        if ($this->f->is_option_dossier_commune_enabled()) {
            $commune_id = intval($this->f->get_submitted_get_value('commune'));
        }
        // Type détaillé du dossier d'autorisation
        $datd = intval($this->f->get_submitted_get_value('datd'));

        // Références cadastrales
        $ref_cadas = strval($this->f->get_submitted_get_value('ref_cadas'));

        // Type de demande
        $demande_type = intval($this->f->get_submitted_get_value('demande_type'));

        // Instanciation de la classe dossier_autorisation pour récupérer la
        // division de l'instructeur affecté autoamtiquement
        $empty_da = $this->f->get_inst__om_dbform(array(
            "obj" => "dossier_autorisation",
            "idx" => 0,
        ));
        $response['code_division'] = $empty_da->get_instructeur_division_for_numero_dossier(
            $datd, $om_collectivite, $commune_id, $ref_cadas, $demande_type);

        printf(json_encode($response));
    }


     /**
     * VIEW - view_load_select_datd
     *
     * Vue pour récupérer la valeur proposé du type de dossier en fonction 
     * du numéro de dossier renséigner par le formulaire
     *
     * @return void
     */
    function view_load_select_datd(&$form, $maj) {
        $num_doss_complet = "";
        if ($this->f->get_submitted_post_value('num_doss_complet') !== null) {
            $num_doss_complet = $this->f->get_submitted_post_value('num_doss_complet');
        } elseif ($this->getParameter('num_doss_complet') != "") {
            $num_doss_complet = $this->getParameter('num_doss_complet');
        } elseif (isset($form->val['num_doss_complet'])) {
            $num_doss_complet = $form->val['num_doss_complet'];
        }

        // Initialisation du select
        $contenu = array( 0 => array( 0 => ''), 1 => array( 0 => '') );

        // Initialisation du SQL
        $sql = $this->get_var_sql_forminc__sql_dossier_autorisation_type_detaille();
        
        // si on a un numéro de dossier 
        if (!empty($num_doss_complet)) {
            // Contrôle numérotation respecte format urbanisme
            $num_doss_split = $this->f->numerotation_urbanisme($num_doss_complet);
            $doss_type = null;
            if (empty($num_doss_split['di']) === FALSE) {
                $doss_type = strtoupper($num_doss_split['di']['type']);
            } else if (empty($num_doss_split['da']) === FALSE) {
                $doss_type = strtoupper($num_doss_split['da']['type']);
            }

            // Si le type de demande est détéctable dans le numéro de dossier
            if (empty($doss_type) === FALSE) {
                // Ajoute une condition après les conditions de la requête de récupération des numéros de dossier
                $sql_suggestion = str_replace('ORDER BY', "AND dossier_autorisation_type.code LIKE '$doss_type'\n ORDER BY\n", $sql);

                // Gestion de la requête
                $res_sugggestion = $this->f->get_all_results_from_db_query(
                    $sql_suggestion,
                    array(
                        'origin' => __METHOD__,
                        'mode' => DB_FETCHMODE_ORDERED
                    )
                );

                $sub_contenu = array();
                foreach ($res_sugggestion['result'] as $row) {
                    $sub_contenu[0][] = $row[0];
                    $sub_contenu[1][] = $row[1];
                }

                // Si on a des résultats, on construit le groupe des suggestions et la requête
                // est modifiée pour ne pas re-afficher les valeurs suggérées
                if (! empty($sub_contenu)) {
                    $contenu[0][]= $sub_contenu;
                    $contenu[1][]= __('💡 Suggestions');;

                    // Modification de la requête pour exclure les résultats suggéré.
                    $sql = str_replace('ORDER BY', "AND dossier_autorisation_type.code NOT LIKE '$doss_type'\n ORDER BY\n", $sql);
                }
            }
        }

        // Exécution de la requête
        $res = $this->f->get_all_results_from_db_query(
            $sql,
            array(
                'origin' => __METHOD__,
                'mode' => DB_FETCHMODE_ORDERED
            )
        );
        // Vérification d'une éventuelle erreur de base de données
        $this->f->isDatabaseError($res);

        foreach ($res['result'] as $row) {
            $contenu[0][] = $row[0];
            $contenu[1][] = $row[1];
        }

        // Retourne les réponses
        return $contenu;
    }


     /**
     * VIEW - view_load_select_commune
     *
     * Vue pour récupérer la valeur de la commune en fonction 
     * du numéro de dossier renséigner par le formulaire
     * s'inspirant de la méthode demande::loadSelectDemandeType().
     * Cette méthode doit :
         * Identifier quelle commune correspond à celle du numéro de dossier et récupérer son id et son libellé
         * Récupérer (à l'aide de la requête permettant de remplir le select) la liste des communes
         * Remplir le contenu du select en mettant en premier les suggestions et en deuxième le reste du select
     *
     * @return 
     */
    function view_load_select_commune(&$form, $maj, $value = NULL, $triggered_load = false) {
        // Récupération du numéro de dossier consulté :
        // (par ordre de priorité)
        // - si une valeur est postée : c'est le cas lors du rechargement d'un
        //   formulaire et que le select doit être peuplé par rapport aux
        //   données saisies dans le formulaire,
        // - si la valeur est passée en paramètre : c'est le cas lors d'un
        //   appel via le snippet filterselect qui effectue un
        //   $object->setParameter($linkedField, $idx); lors d'un appel ajax
        //   depuis le formulaire,
        // - si la valeur est dans l'enregistrement de la consultation sur laquelle on se
        //   trouve : c'est le cas lors de la première ouverture du formulaire
        //   en modification par exemple.
        // Initialisation du select
        $contenu = array( 0 => array( 0 => ''), 1 => array( 0 => '') );

        if (!$triggered_load && $this->getParameter('triggered_load') != "") {
            $triggered_load = $this->getParameter('triggered_load');
        }
        if ($triggered_load) {
            // Initialisation du SQL
            $sql = "SELECT commune, CONCAT(com, ' - ', libelle) AS libelle_long FROM ".DB_PREFIXE."commune WHERE ";
            $sql_order = "ORDER BY com";

            // Exclusion des communes dont la date est invalide
            $date_demande = "";
            if ($this->getParameter('date_demande') != "") {
                $date_demande = $this->getParameter('date_demande');
            } elseif (isset($form->val['date_demande'])) {
                $date_demande = $form->val['date_demande'];
            }

            $d_match = array();
            // si elle est valide on la transforme en date anglaise (pour Postgres)
            if (empty($date_demande)
                    || ! preg_match('/^([0-9]{2})\/([0-9]{2})\/([0-9]{4})$/', $date_demande, $d_match)) {
                $date_demande = date('Y-m-d');
            }
            // sinon on prend la date du jour (courant)
            else {
                $date_demande = $d_match[3].'-'.$d_match[2].'-'.$d_match[1];
            }
            $sql .= sprintf("
                (
                    commune.om_validite_debut IS NULL
                    OR commune.om_validite_debut <= TO_DATE('%s', 'YYYY-MM-DD')
                )
                AND (
                    commune.om_validite_fin IS NULL
                    OR commune.om_validite_fin > TO_DATE('%s', 'YYYY-MM-DD')
                )",
                $this->f->escape_string_for_db_query($date_demande),
                $this->f->escape_string_for_db_query($date_demande)
            );

            // 
            if (!is_null($value)) $sql .= " AND commune.commune = '$value'";

            $om_collectivite = "";
            if ($this->getParameter('om_collectivite') != "") {
                $om_collectivite = $this->getParameter('om_collectivite');
            } elseif (isset($form->val['om_collectivite'])) {
                $om_collectivite = $form->val['om_collectivite'];
            }
            $filter_om_collectivite = '';
            if ( !empty($om_collectivite) ) {

                // si identifiant de la collectivite valide
                // récupère les paramètres de la collectivité
                $params = $this->f->getCollectivite($om_collectivite);
                // si le paramètre 'param_communes' est défini et valide
                if(!empty($params) && isset($params['param_communes']) && preg_match(
                    '/^([0-9]{2,3}|[0-9]{5})(,([0-9]{2,3}|[0-9]{5}))*$/',
                    $params['param_communes'])) {

                    // on ajoute autant de conditions à la clause WHERE de la requête SQL
                    // qu'il y a d'élément dans la liste du paramètre
                    $filter_om_collectivite .= ' AND ( ';
                    $communes_filter_tokens = explode(',', $params['param_communes']);
                    foreach ($communes_filter_tokens as $communes_filter_token) {

                        // champ de la commune à comparer (par défaut: code INSEE commune)
                        $commune_filter_field = 'com';

                        // département
                        if (strlen($communes_filter_token) <= 3) {
                            $commune_filter_field = 'dep';
                        }

                        // ajoute le filtre à la requête SQL
                        $filter_om_collectivite .= sprintf(
                            "commune.%s = '%s' OR ", $commune_filter_field, $communes_filter_token);
                    }
                    $filter_om_collectivite = preg_replace('/ OR $/', ')', $filter_om_collectivite);
                }
                $sql .=  $filter_om_collectivite;
            }

            $num_doss_complet = "";
            if ($this->f->get_submitted_post_value('num_doss_complet') !== null) {
                $num_doss_complet = $this->f->get_submitted_post_value('num_doss_complet');
            } elseif ($this->getParameter('num_doss_complet') != "") {
                $num_doss_complet = $this->getParameter('num_doss_complet');
            } elseif (isset($form->val['num_doss_complet'])) {
                $num_doss_complet = $form->val['num_doss_complet'];
            }
            $sql_suggestion_complet = "";
            if ( !empty($num_doss_complet) ) {
                // Contrôle numérotation respecte format urbanisme
                $num_doss_split = $this->f->numerotation_urbanisme($num_doss_complet);
                $departement = null;
                $commune = null;
                if (empty($num_doss_split['di']) === FALSE) {
                    $departement = strtolower($num_doss_split['di']['departement']);
                    $commune = strtolower($num_doss_split['di']['commune']);
                } else if ( empty($num_doss_split['da']) === FALSE) {
                    $departement = strtolower($num_doss_split['da']['departement']);
                    $commune = strtolower($num_doss_split['da']['commune']);
                }

                // Le filtre des suggestions ne doit pas être appliqué si la commune et le département lié
                // au numéro de dossier saisis n'ont pas été récuếré
                if (empty($departement) === FALSE && empty($commune) === FALSE) {
                    $trim_length = 3;
                    if (empty($departement) === FALSE) {
                    $sql_suggestion_complet .= " AND dep LIKE LTRIM('".$departement."','0')";
                    if(strlen(trim($departement, '0')) == 3) $trim_length = 2 ;
                    } 
                    if (empty($commune) === FALSE) {
                        $sql_suggestion_complet .= " AND RIGHT(com,$trim_length) LIKE RIGHT('$commune',$trim_length)";
                    }

                    // Exécution de la requête
                    $res_suggestion = $this->f->get_all_results_from_db_query(
                        $sql.$sql_suggestion_complet.$sql_order,
                        array(
                            'origin' => __METHOD__,
                            'force_result' => false,
                            'mode' => DB_FETCHMODE_ORDERED
                        )
                    );

                    $sub_contenu = array();
                    $suggestion_ids = array();
                    foreach ($res_suggestion['result'] as $row){
                        $suggestion_ids[] = $row[0];
                        $sub_contenu[0][] = $row[0];
                        $sub_contenu[1][] = $row[1];
                    }
                    if (sizeof($suggestion_ids)) {
                        $contenu[0][]=$sub_contenu;
                        $contenu[1][]=__('💡 Suggestions');;
                        $sql .= " AND commune NOT IN ('".implode("','", $suggestion_ids)."')";
                    }
                }

            }

            // Exécution de la requête
            $res = $this->f->get_all_results_from_db_query(
                $sql.$sql_order,
                array(
                    'origin' => __METHOD__,
                    'force_result' => false,
                    'mode' => DB_FETCHMODE_ORDERED
                )
            );
            // Vérification d'une éventuelle erreur de base de données
            $this->f->isDatabaseError($res);

            foreach ($res['result'] as $row){
                $contenu[0][] = $row[0];
                $contenu[1][] = $row[1];
            }
        }
        // Retourne les réponses
        return $contenu;
    }


    /**
     * VIEW - view_get_affectation_auto
     *
     * Vue pour récupérer la valeur courante des affectations automatiques possibles, en json.
     *
     * @return void
     */
    function view_get_affectation_auto() {
        $this->f->disableLog();
        $response = array('affectations_auto' => array());

        // Identifiant de la collectivité
        $om_collectivite = intval($this->f->get_submitted_get_value('om_collectivite'));
        // Identifiant de la commune
        $commune_id = 0;
        if ($this->f->is_option_dossier_commune_enabled()) {
            $commune_id = intval($this->f->get_submitted_get_value('commune'));
        }
        // Type détaillé du dossier d'autorisation
        $datd = intval($this->f->get_submitted_get_value('datd'));
        // Type de demande (ID)
        $demande_type = intval($this->f->get_submitted_get_value('demande_type'));

        // récupère la liste des affectations automatiques qui correspondent
        $aff_auto = $this->f->get_inst__om_dbform(array(
            "obj" => "affectation_automatique",
            "idx" => 0,
        ));
        $response['affectations_auto'] = $aff_auto->get_matching_affectations(
            $om_collectivite, $commune_id, $datd, $demande_type);

        // affiche le tableau en JSON
        printf(json_encode($response));
    }

    /**
     * VIEW - view_get_translatable_text
     *
     * Vue permettant au JavaScript de récupérer un texte traduisible.
     *
     * @return void
     */
    function view_get_translatable_text() {
        $this->f->disableLog();
        $texts = array(
            'commune_change_selection' => __("Les données saisies ne permettent pas de rattacher la demande à la commune sélectionnée."),
        );
        $text_choice = $this->f->get_submitted_get_value('text_choice');

        if ($text_choice !== null
            && array_key_exists($text_choice, $texts) === true) {
            //
            printf($texts[$this->f->get_submitted_get_value('text_choice')]);
        }
    }

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

        if ($maj == 0) {
            if ( $this->f->is_option_dossier_saisie_numero_complet_enabled() === true) {
                //
                $form->setOnchange("num_doss_complet", "this.value=this.value.toUpperCase(); checkInputNumDossierComplet(this); verifier_numerotation_urbanisme(this);");
                // Gère l'affichage et désaffichage du message d'information sur l'existence d'un DI de même
                // collectivité et de même numéro de dossier (infos obligatoires), en fonction de si l'on peux 
                // saisir manuellement ou non un numéro de dossier
                $form->addOnchange("num_doss_complet", "toggleDisplayMessageDIExistOnDemandeNouveauDossier();");
                // Gere la suggestion des types de dossier et des communes 
                $form->addOnchange("num_doss_complet", "suggestCommuneDatdFromNumDossier();");
                $form->setOnchange("om_collectivite", "toggleDisplayMessageDIExistOnDemandeNouveauDossier();");
                // Gere l'affichage, dèsaffichage et remplissage des champs numéro de dossier
                $form->setOnchange("no_num_doss_complet", "toggleNoNumDossComplet(this);resetCommuneDADTFromNoNumDossComplet(this);");
                $form->addOnchange("no_num_doss_complet", "toggleDisplayMessageDIExistOnDemandeNouveauDossier();");
            }

            if (
                $this->f->is_option_dossier_saisie_numero_enabled() === true
                || $this->f->is_option_dossier_saisie_numero_complet_enabled() === true
            ) {
                $form->addOnchange("date_demande", "update_num_dossier_annee($(this));");
                $form->addOnchange("dossier_autorisation_type_detaille",
                    "update_num_dossier_type_da(this); update_num_dossier_division();", 'prepend');
                $form->addOnchange("om_collectivite",
                    "update_num_dossier_code_depcom(this); update_num_dossier_division();");
                if ($this->f->is_option_dossier_commune_enabled()) {
                    $form->addOnchange("commune", "update_num_dossier_code_depcom(this);");
                }
                $form->addOnchange("num_doss_manuel", "toggleNumDossierManuel(this);");
                $form->addOnchange("num_doss_division",
                    "checkInputIsAlphaNum(this.value.toUpperCase());");

                // mise à jour du numéro de séquence
                $form->setOnchange('num_doss_type_da', 'update_num_dossier_seq();');
                $form->setOnchange('num_doss_code_depcom', 'update_num_dossier_seq();');
                $form->setOnchange('num_doss_annee', 'update_num_dossier_seq();');

            }

            // mise à jour du champ 'affectation_automatique'
            $form->addOnchange("om_collectivite",
                "update_affectation_auto();",
                'prepend');
            $form->setOnchange("dossier_autorisation_type_detaille",
                $form->onchange["dossier_autorisation_type_detaille"]."; ".
                "update_affectation_auto(this, function(_this) { ".
                    "afficheFormDemandeDAtd(500); ".
                "}, 500);");
            // En cas de changement du champ type demande, appel
            // la méthode javascript filterSelect qui utilise (via l'URL) le
            // snippet__filterselect. Le snippet renvoie ensuite un json contenant la valeur du champ.
            // Cette valeur est ensuite utilisée pour récupèrer la liste des
            // nature de travaux liées au type de dossier sélectionné.
            $form->setOnchange("demande_type",
                "update_affectation_auto(this, function(_this) { ".
                    "manage_document_checklist(_this); ".
                    "afficheFormDemandeDT(500); ".
                "}, 500);".
                "filterSelect(this.value, 'nature_travaux', 'demande_type', 'demande_nouveau_dossier')"
            );

            if ($this->f->is_option_dossier_commune_enabled()) {
                $form->addOnchange("commune", "update_affectation_auto();", 'prepend');
                // mise à jour des valeurs de la select de la commune en fonction de la collectivité ou de la date
                $form->addOnchange("om_collectivite", "updateCommuneSelect();");
                $form->addOnchange("date_demande", "updateCommuneSelect();");
            }
        }
    }
    
    
    /**
     * SURCHARGE
     * Configuration du formulaire (VIEW formulaire et VIEW sousformulaire).
     *
     * Permet d'effectuer des appels aux mutateurs spécifiques sur le formulaire
     * de manière fonctionnelle et non en fonction du mutateur. Exemple : au lieu
     * de gérer le champ service dans les méthodes setType, setSelect, le setLib,
     * ... Nous allons les gérer dans cette méthode et appeler tous les mutateurs
     * à la suite.
     *
     * @param formulaire $form Instance formulaire.
     * @param integer $maj Identifant numérique de l'action.
     *
     * @return void
     */
    function set_form_specificity(&$form, $maj) {
        parent::set_form_specificity($form, $maj);

        // Gestion du remplissage du select commune
        // Code posée ici pour être lancée avant $this->form->recupererPostvar mais
        // après $this->setSelect($this->form, $maj, $dbnu1, null);
        // si on est dans un chargement de la page avec une valeur à affecter
        $post_vars = $this->getParameter("postvar");
        if (
            $this->getParameter("validation") > 0
            && isset($post_vars['commune'])
            && !empty($post_vars['commune'])
        ){
            //
            $encodages = array("UTF-8", "ASCII", "Windows-1252", "ISO-8859-15", "ISO-8859-1");
            // Compatibilité Windows ? iconv sur la valeur "UTF8" au lieu de
            // "UTF-8" renvoi une erreur.
            $dbcharset = (DBCHARSET == "UTF8" ? "UTF-8" : DBCHARSET);

            // récupération de l'ID de la commun séléctionnée
            $value = $post_vars['commune'];
            // On remplace les doubles quotes par des simples quotes ?
            $value = strtr($value, chr(34), "'");
            // On encode les valeurs reçues dans l'encodage de la
            // base de données
            $value = iconv(
                mb_detect_encoding($value, $encodages),
                $dbcharset,
                $value
            );
            
            // On remplis le select uniquement avec la ligne du qui contien cette commune
            $form->setSelect(
                'commune', $this->view_load_select_commune($form, $maj, $value, true )
            );
        }

        $this->display_notification_info($maj);
    }

    /**
     * En creation de nouveau dossier,
     * si l'option communes as été activée et
     * que l'utilisateur n'as pas les params_communes de remplis
     * alors un message d'information a destination de l'utilisateur est affiché
     * car dans ce cas le front charge les 35 000 communes francaise.
     *
     * @param string $maj
     *
     * @return void
     */
    public function display_notification_info($maj) {
        if ($this->f->is_option_dossier_commune_enabled() === true) {
            $om_collectivite = NULL;
            if ($_SESSION['collectivite'] != "") {
                $om_collectivite = $_SESSION['collectivite'];
            if ($this->getParameter('om_collectivite') != "") {
                $om_collectivite = $this->getParameter('om_collectivite');
            }
            $params = $this->f->getCollectivite($om_collectivite);
            // si le paramètre 'param_communes' est défini et valide
            if (
                ( !empty($maj) || $maj == 0)
                &&(
                    empty($params)
                    || !isset($params['param_communes'])
                )
            ) {
                    $class = 'text-info ui-state-highlight ui-state-info';
                    $message = __("Le temps de chargement de la page peut être dégradé en raison du profil et du paramétrage liés à votre utilisateur.");
                    $this->f->display_panel_information(
                        $class,
                        $message
                    );
                }
            }
        }
    }

    /**
     * Méthode permettant de récupérer et construire le message d'information qui sera
     * affiché lors d'une nouvelle demande de dossier du demandeur, si les conditions suivantes
     * sont respectées : 
     * - L'option option_dossier_saisie_numero_complet à true et sur la collectivité concerné
     * - Un DI existe avec le même numéro de dossier
     * - La collectivité saisie par l'utilisateur est lié au DI recherché
     * 
     * Filtre : 
     *  - sur le DI ayant la date de dépôt la plus récente
     *  - même collectivité
     *  - exclusion des DI de type sous dossiers
     * 
     * @return boolean
     */
    function view_message_DI_exist_on_demande_nouveau_dossier() {
        //
        // Récupération des données saisies par l'utilisateur
        $om_collectivite_id = $this->f->get_submitted_get_value("om_collectivite_id");
        $num_dossier = $this->f->get_submitted_get_value("numero_dossier");

        // Récupération des données du demandeur, en lien avec le DI saisit par l'utilisateur.
        // La requête permet de récupérer toutes les data sur le demandeur en lien avec le DI courant.
        // Elle permet également de récupérer quelques data sur le dernier DI déposé (dernière date_depot) en lien avec le DA,
        // lui même en lien avec le DI saisie par l'utilisateur initialement.
        // DI recherché -> DA -> dernier DI déposé (date_depot)
        //
        // Le numéro de dossier recherché, doit être existant, ne pas être un sous-dossier, en lien avec le DA et avoir la
        // même collectivité que celle recherché.
        if(!empty($num_dossier) &&
            !empty($om_collectivite_id)){
            $qres = $this->f->get_all_results_from_db_query(
                sprintf(
                    'SELECT
                        dernier_dossier.dossier,
                        dernier_dossier.dossier_libelle,
                        demandeur.*
                    FROM
                        (SELECT
                            dossier.dossier,
                            dossier.dossier_libelle
                        FROM
                            %1$som_collectivite
                        LEFT JOIN %1$sdossier 
                            ON dossier.om_collectivite = om_collectivite.om_collectivite
                        WHERE
                            dossier.dossier LIKE \'%2$s%%\'
                            AND om_collectivite.om_collectivite = \'%3$s\'
                            AND dossier.dossier_parent IS NULL
                        ORDER BY
                            dossier.date_depot DESC,
                            dossier.version DESC
                            LIMIT 1
                        ) AS dernier_dossier
                    LEFT JOIN %1$slien_dossier_demandeur
                        ON dernier_dossier.dossier = lien_dossier_demandeur.dossier
                    LEFT JOIN %1$sdemandeur
                        ON lien_dossier_demandeur.demandeur = demandeur.demandeur
                    WHERE
                        lien_dossier_demandeur.petitionnaire_principal IS TRUE
                    ORDER BY
                        lien_dossier_demandeur.demandeur DESC
                ',
                DB_PREFIXE,
                $this->f->escape_string_for_db_query($num_dossier),
                intval($om_collectivite_id)
            ),
                array(
                    "origin" => __METHOD__,
                )
            );
        }

        if ($qres['code'] === 'KO') {
            return false;
        }

        // Si résultats, construction du message et insertion des données dans le template 
        // pour envoyer le tout à traitement Js qui gére son affichage, l'emplacement exacte, et 
        // certains triggers qui toggle le message
        if (!empty($qres["result"])) {
            // Initialisation des variables
            $dossier_id = $qres["result"][0]["dossier"];
            $dossier = $qres["result"][0]["dossier_libelle"];

            // Initialisation des tableaux qui seront dynamiquement renseignés
            $list_id_demandeur_and_type = [];
            $list_demandeur = [];
            // Liste des demandeurs principaux
            $list_type_demandeur_princ = array(
                "petitionnaire" =>  "Demandeur principal",
                "contrevenant" =>  "Contrevenant principal",
                "bailleur" =>  "Bailleur principal",
                "avocat" =>  "Avocat principal",
                "requerant" =>  "Requérant principal",
                "plaignant" => "Plaignant principal"
            );

            // On boucle pour renseigner un tableau pour récupérer le label du demandeur, 
            // ainsi que le label de son type
            // Ce tableau sera traité dans la méthode 'template_message_DI_exist()' pour afficher le message 
            // d'information avec les bon demandeurs et correctement renseigné
            foreach ($qres["result"] as $key) {
                // On part du principe qu'un demandeur peut être soit une 'personne morale' soit un 'particulier'
                $demandeur_label_fields = array(
                    $key["particulier_nom"],
                    $key["particulier_prenom"],
                    $key["personne_morale_denomination"],
                    $key["personne_morale_raison_sociale"],
                    $key["personne_morale_nom"],
                    $key["personne_morale_prenom"]
                );
                // On supprime les valeurs vides, nous permetttant de savoir quel est le type du 
                // demandeur (personne morale/particulier) et on concatène les données demandeur séparé par un espace.
                $demandeur_label = implode(' ', array_filter($demandeur_label_fields));

                // Récupération du type de demandeur pour l'affichage
                $type_demandeur = $key["type_demandeur"];

                // Si le type de demandeur existe dans le tableau list_type_demandeur_princ
                // on injecte les données dans le tableau qui sera utilisé pour l'affichage
                // des demandeurs dans le message d'information sur l'existence d'un DI
                if(!empty($type_demandeur) && 
                    array_key_exists($type_demandeur, $list_type_demandeur_princ) === TRUE){
                    //
                    $list_demandeur[$type_demandeur]['demandeur_type'] = $list_type_demandeur_princ[$type_demandeur];
                    // On ajoute les renseignements sur l'idendité du demandeur
                    $list_demandeur[$type_demandeur]['demandeur_label'] = $demandeur_label;

                    // On stock l'ensemble des id des différents demandeur pour le bouton de copie des données
                    // Sous cette forme -> "id,type:id,type:..."
                    // On ajoute '_principal' car les ids dans le DOM qui font référence à l'ajout d'un demandeur principal
                    // sont  suffixé par '_principal' (ce qui permettra l'ajout)
                    $list_id_demandeur_and_type[] = $key["demandeur"];
                    $index = array_search($key["demandeur"], $list_id_demandeur_and_type);
                    $list_id_demandeur_and_type[$index] .= ",".$type_demandeur."_principal";
                }
            }

            // On fusionne le tableau pour faciliter le traitement par la suite
            $list_id_demandeur_and_type = implode(":", $list_id_demandeur_and_type);

            // Récupération de l'url du dossier
            $urlAcces = $this->f->get_parametre_notification_url_acces($om_collectivite_id);

            $link_url = 
                sprintf(
                    '%1$sapp/index.php?module=form&obj=dossier_instruction&action=3&idx=%2$s',
                    $urlAcces,
                    $dossier_id
                );

            // Appelle de la méthode de remplissage et de formatage du template du message d'information
            $message = $this->template_message_DI_exist($demandeur_label, $dossier, $link_url, $list_demandeur, $list_id_demandeur_and_type);
            // On envoie le message finalisé (renseigné et formaté) pour être afficher ou non en JS
            echo $message;
            return true;
        }
    }

    /**
     * Méthode permettant de renseigner et formater le message d'information
     * à l'attention de l'utilisateur lorsqu'un DI (en lien avec le numéro de dossier et la collectivité saisie)
     * existe.
     * Elle permet également de bien renseigné les ids des demandeurs ainsi que leurs types
     * pour traitement JS permettant de lister les demandeurs principaux dans le message d'information,
     * ainsi que de pouvoir copier
     * les informations des demandeurs et de les ajouter automatiquement si l'ajout de ce type
     * de demandeur est possible et qu'un demandeur avec l'id correspondant existe bien.
     * 
     * @return string (élement html renseigné et formaté)
     */
    function template_message_DI_exist($demandeur_label, $dossier, $link_url, $list_demandeur, $list_id_demandeur_and_type){
        // Initialisation des variables
        $message = __("Un dossier avec le même numéro de dossier a été trouvé");
        $message_button = __("UTILISER LES INFORMATIONS DE CE DOSSIER");
        $message_link_DI = __("Ouvrir dans un nouvel onglet");

        // Séparation pour aérer la section infos sur le dossier et listing des demandeurs
        $demandeur = (count($list_demandeur) > 1) ? "Demandeurs" : "Demandeur";
        $list_demandeur_to_display = $demandeur." : <ul>";

        // Concaténation de l'identité du demandeur ainsi que de son type (ex => "Bernard Durand (Contrevenant principal)")
        // Liste qui sera injecté dans le template d'affichage du message d'information
        foreach ($list_demandeur as $demandeur_type) {
            $list_demandeur_to_display .= "<li><b>".$demandeur_type["demandeur_label"]."</b> (".$demandeur_type["demandeur_type"].")"."</li>";
        }
        $list_demandeur_to_display .= "</ul>";

        // Template pour le remplissage des données du DI dans le message qui sera affiché à l'utilisateur
        $template_message_demande =
        sprintf(
            '<div id="display_message_di_exist" class="panel_information ui-corner-all ui-state-highlight ui-state-text-info">
                <span class="ui-icon ui-icon-info"><!-- --></span>
                <span class="message_content_head">%1$s</span>
                <div class="message_content_body">
                    <span class="text">
                        <b>%2$s</b>
                        <a href="%4$s" id="link_to_di" target="_blank" rel="noopener noreferrer">
                            <i class="ri-external-link-line"></i> %5$s
                        </a></br>
                        %3$s
                    </span>
                    <button class="button-primary button_copy_data_demandeur" type="button" onclick="copy_dossier_demandeurs_principaux_to_new_demande(\'%6$s\');">
                        <i class="ri-file-copy-2-line"></i> %7$s
                    </button>
                </div>
            </div>',
            $message,
            $dossier,
            $list_demandeur_to_display,
            $link_url,
            $message_link_DI,
            $list_id_demandeur_and_type,
            $message_button
        );

        // On stock la forme et le contenu du message, et on le retourne
        $message = $template_message_demande;
        return $message;
    }

    function view_verifier_numerotation_urbanisme() {
        $this->f->disableLog();
        $response = array();

        //
        $num_doss_comp = $this->f->get_submitted_get_value('num_doss_complet');
        $datd_id = $this->f->get_submitted_get_value('datd_id');
        $demande_type_id = $this->f->get_submitted_get_value('demande_type_id');

        // Contrôle numérotation respecte format urbanisme
        if ( empty($num_doss_comp) === false ) {
            $num_urba = $this->f->numerotation_urbanisme($num_doss_comp);
            if (empty($num_urba['di']) === true
                || empty($num_urba['da']) === true) {
                //
                $response['info_msg'][] = __("Le numéro saisie ne respecte pas le format imposé par le code de l'urbanisme, les vérifications imposées ne seront donc pas réalisées.");
                printf(json_encode($response));
                return;
            }

            if ( empty($datd_id) === false ) {
                // Contrôle du code du type de DA
                list($code_type_da, $err_msg) = $this->getCodeTypeDA($datd_id);
                if(empty($err_msg) === true) {
                    if (strtolower($code_type_da) !== strtolower($num_urba['di']['type'])) {
                        $response['info_msg'][] = __("Le code du type de dossier d'autorisation saisie ne correspond pas au type de dossier d'autorisation détaillé sélectionné.");
                        return;
                    }
                }
            } else {
                $response['info_msg'][] = __("Aucun type de dossier d'autorisation détaillé sélectionné vérification impossible du code du type de dossier d'autorisation saisie.");
                return;
            }

            if ( empty($demande_type_id) === false ) {
                // Contrôle du suffixe
                $query = str_replace(
                    '<idx>',
                    $demande_type_id,
                    $this->get_var_sql_forminc__sql("demande_type_details_by_id")
                );
                $res = $this->f->get_all_results_from_db_query(
                    $query,
                    array(
                        "origin" => __METHOD__,
                        "force_return" => true,
                    )
                );
                if ($res['code'] === 'KO') {
                    return false;
                }
                $empty_di = $this->f->get_inst__om_dbform(array(
                    "obj" => "dossier",
                    "idx" => 0,
                ));
                foreach ($res['result'] as $value) {
                    if ($empty_di->getSuffixe($value['dossier_instruction_type']) === 't'
                        && (isset($num_urba['di']['suffixe']) === false
                            || isset($num_urba['di']['num_suffixe']) === false)) {
                        //
                        $response['info_msg'][] = __("Le numéro saisie doit comporter un suffixe.");
                    }
                    if ($empty_di->getSuffixe($value['dossier_instruction_type']) === 'f'
                        && (isset($num_urba['di']['suffixe']) === true
                            || isset($num_urba['di']['num_suffixe']) === true)) {
                        //
                        $response['info_msg'][] = __("Le numéro saisie ne doit pas comporter de suffixe.");
                    }
                    if ($empty_di->getSuffixe($value['dossier_instruction_type']) === 't'
                        && isset($num_urba['di']['suffixe']) === true) {
                        //
                        $code = $empty_di->getCode($value['dossier_instruction_type']);
                        if (strtolower($code) !== strtolower($num_urba['di']['suffixe'])) {
                            $response['info_msg'][] = sprintf(
                                __("Le suffixe du numéro saisie doit être %s."),
                                sprintf("<b>%s</b>", strtoupper($code))
                            );
                        }
                    }
                }
            }else{
                $response['info_msg'][] = __("Aucune type de demande liée au type de dossier d'autorisation détaillé sélectionné vérification impossible du code du type de dossier d'autorisation saisie.");
            }
        }
        printf(json_encode($response));
    }

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

        if ($maj == 0
            && ((
                $this->f->is_option_dossier_saisie_numero_enabled() === true
                || $this->f->is_option_dossier_saisie_numero_complet_enabled() === true
            ))
        ) {
            // Checkbox pour passer en numérotation forcée
            $form->setType('num_doss_manuel', 'checkboxlabelafter');
            // Champs non modifiables avec valeur informative
            $form->setType('num_doss_type_da', 'textreadonly');
            $form->setType('num_doss_code_depcom', 'textreadonlynolabel');
            $form->setType('num_doss_annee', 'textreadonlynolabel');
            // Champs modifiables pré-saisie
            $form->setType('num_doss_division', 'textnolabel');
            $form->setType('num_doss_sequence', 'textnolabel');
        }

        if ($maj == 0
            && $this->f->is_option_dossier_saisie_numero_complet_enabled() === true
        ) {
            // Checkbox pour désactiver numérotation forcée
            $form->setType('no_num_doss_complet', 'checkboxlabelafter');
            // Champs modifiables
            $form->setType('num_doss_complet', 'text');
        }

        if ($this->f->is_option_dossier_commune_enabled() === true) {
            if (($maj == 0 || $maj == 1) &&
                    ! $this->is_in_context_of_foreign_key("commune", $this->retourformulaire)) {
                $form->setType("commune", "select");
            }
        }
        if ($maj == 0) {
            $form->setType('affectation_automatique', 'select');
            $form->setType('nature_travaux', 'select_multiple');
        }
    }

    /**
     *
     */
    function setLib(&$form,$maj) {
        parent::setLib($form,$maj);
        //libelle des champs
        
        $form->setLib('date_depot_mairie', __('Date de Dépôt'));
        $form->setLib('num_doss_complet', __('N° de dossier'));
        $form->setLib('no_num_doss_complet', __("Je n'ai pas de numéro de dossier"));
        $form->setLib('dossier_autorisation_type_detaille', __('Type de dossier'));
        $form->setLib('num_doss_manuel', __('Compléter la numérotation'));
        $form->setLib('num_doss_type_da', __('N° de dossier généré'));
        $form->setLib('affectation_automatique', __("Affectation manuelle de l'instructeur"));
        if ($this->f->is_option_mode_service_consulte_enabled() === true) {
            $form->setLib('date_demande', __('Réception en service'));
            $form->setLib('date_depot_mairie', __('Dépôt en mairie'));
        }
    }

    /**
     *
     */
    function setTaille(&$form, $maj) {
        parent::setTaille($form,$maj);

        $form->setTaille('num_doss_type_da', 3);
        $form->setTaille('num_doss_code_depcom', 6);
        $form->setTaille('num_doss_annee', 2);
        $form->setTaille('num_doss_division', 1);
        $form->setTaille('num_doss_sequence', 4);
        $form->setTaille('num_doss_complet', 16);
        $form->setTaille('date_depot_mairie', 10);
    }

    /**
     *
     */
    function setMax(&$form, $maj) {
        parent::setMax($form,$maj);

        $form->setMax('num_doss_type_da', 3);
        $form->setMax('num_doss_code_depcom', 6);
        $form->setMax('num_doss_annee', 2);
        $form->setMax('num_doss_division', 1);
        $form->setMax('num_doss_sequence', 4);
        $form->setMax('num_doss_complet', 255);
    }


    /**
     * Charge le select du champ nature_travaux
     *
     * @param  object $form  Formulaire
     * @param  string $champ champ activant le filtre
     * @return array         Contenu du select
     */
    function loadSelectNatureTravaux($form, $champ) {
        $contenu = array();
        //Récupère l'id du type de dossier d'autorisation détaillé 
        $id_demande_type = "";
        if ($this->f->get_submitted_post_value($champ) !== null) {
            $id_demande_type = $this->f->get_submitted_post_value($champ);
        } elseif($this->getParameter($champ) != "") {
            $id_demande_type = $this->getParameter($champ);
        } elseif(isset($form->val[$champ])) {
            $id_demande_type = $form->val[$champ];
        }
        if ($id_demande_type === '') {
            return $contenu;
        }

        // Requête de récupération de la nature des travaux selon le type de DI
        $qres = $this->f->get_all_results_from_db_query(
            sprintf(
                $this->get_var_sql_forminc__sql_nature_travaux(),
                DB_PREFIXE,
                intval($id_demande_type)
            ),
            array(
                'origin' => __METHOD__,
                'mode' => DB_FETCHMODE_ORDERED
            )
        );
        // Les résultats de la requête sont stocké dans un tableau permettant
        // au format voulu pour le remplissage des selects
        foreach ($qres['result'] as $row) {
            $contenu[0][] = $row[0];
            $contenu[1][] = $row[1];
        }
        return $contenu;
    }

    /**
     *
     */
    function verifierAjout($val = array(), &$dnu1 = NULL) {
        $num_doss_sequence = null;

        // Si l'option des communes est activée
        if ($this->f->is_option_dossier_commune_enabled()) {

            // La commune doit être définie
            if (! array_key_exists("commune", $val) || empty($val["commune"])) {
                $this->addToMessage(__("La <b>commune</b> doit être <b>définie</b>."));
                $this->correct = false;
            }
            else {
                // récupération de la date de demande
                $date_demande = 'NOW';
                $d_match = array();
                if (isset($this->valF["date_demande"])
                        && preg_match('/^([0-9]{2})\/([0-9]{2})\/([0-9]{4})$/',
                                      $this->valF["date_demande"], $d_match)) {
                    $date_demande = $d_match[3].'-'.$d_match[2].'-'.$d_match[1];
                }
                $date_demande = new DateTime($date_demande);

                // La commune doit exister
                $commune = $this->f->findObjectById("commune", $val["commune"]);
                if (empty($commune) === true) {
                    $this->addToMessage(sprintf(__("La <b>commune</b> '%s' <b>n'existe pas</b>."),
                                                $val["commune"]));
                    $this->correct = false;
                }
                // La commune doit être valide à la date de ma demande
                elseif (! $commune->valid($date_demande)) {
                    $this->addToMessage(sprintf(
                        __("La <b>commune</b> '%s' n'est <b>pas valide</b> à la date du '%s'."),
                        $commune->getVal('libelle'), $date_demande->format('d/m/Y')
                    ));
                    $this->correct = false;
                }
            }
        }

        // Si l'option de numérotation forcée est activée et que la saisie est
        // en numérotation forcée
        if ((
                $this->f->is_option_dossier_saisie_numero_enabled() === true
                || $this->f->is_option_dossier_saisie_numero_complet_enabled() === true
            )
            && isset($val['num_doss_manuel']) === true
            && $val['num_doss_manuel'] === 'Oui') {

            // Vérification de la séquence du numéro de dossier
            if (isset($val['num_doss_sequence']) === false || empty($val['num_doss_sequence']) === true) {
                $this->addToMessage(__("Numéro de dossier : le <b>numéro</b> est obligatoire."));
                $this->correct = false;
            }
            else if (preg_match('/^[0-9]{1,4}$/', $val['num_doss_sequence']) == false) {
                $this->addToMessage(sprintf(
                    __("Numéro de dossier : le <b>numéro</b> %s est invalide."),
                    sprintf("<b>%s</b>", $val['num_doss_sequence'])
                ));
                $this->correct = false;
            }
            else if (isset($this->valF["date_demande"]) === true
                && empty($this->valF["date_demande"]) === false) {
                // Vérifie si un DA avec cette séquence existe déjà
                if($this->f->is_option_om_collectivite_entity_enabled($this->valF['om_collectivite']) === false
                    && $this->existsDAWithNumeroDossierSeq(
                        $this->valF['dossier_autorisation_type_detaille'],
                        $this->valF["date_demande"],
                        $this->valF['om_collectivite'],
                        intval($val['num_doss_sequence']),
                        empty($val["commune"]) === false ? $val["commune"] : null) === true) {
                    //
                    $this->addToMessage(sprintf(
                        __("Numéro de dossier : le <b>numéro</b> %s est déjà atttribué à un autre dossier, veuillez en choisir un autre."),
                        sprintf("<b>%s</b>", $val['num_doss_sequence'])
                    ));
                    $this->correct = false;
                }
                // Cas particulier du dernier numéro de séquence possible (valide)
                else if (intval($val['num_doss_sequence']) == 9999) {
                    $this->addToMessage(sprintf(
                        "%s%s",
                        __("Attention vous avez atteint le dernier numéro de dossier possible pour ce type de dossier d'autorisation de cette collectivité pour l'année sélectionnée."),
                        $this->correct === false ? "" : "<br/>"
                    ));
                }
            }

            // Vérification de la division du numéro de dossier
            if (isset($val['num_doss_division']) === true) {

                // Correction car la division peut-être = 0
                if ($val['num_doss_division'] === null || $val['num_doss_division'] === '') {
                    $this->addToMessage(sprintf(__("Numéro de dossier : le caractère réservé au service instructeur (<b>division</b>) est obligatoire.")));
                    $this->correct = false;
                }
                if (strlen($val['num_doss_division']) > 2 && ctype_alnum($val['num_doss_division']) === false) {
                    $this->addToMessage(sprintf(
                        __("Numéro de dossier : le caractère réservé au service instructeur (<b>division</b>) %s est invalide."),
                        sprintf("<b>%s</b>", $val['num_doss_division'])
                    ));
                    $this->correct = false;
                }
            }
        }

        // Vérification de l'affectation automatique de l'instructeur
        if (isset($val['affectation_automatique']) === true
            && empty($val['affectation_automatique']) === false) {
            //
            if (ctype_digit($val['affectation_automatique']) === false) {
                $this->addToMessage(sprintf(__("Affectation automatique : l'identifiant est invalide (doit être un entier).")));
                $this->correct = false;
            }
            else {
                $aff = $this->f->get_inst__om_dbform(array(
                    "obj" => "affectation_automatique",
                    "idx" => intval($val['affectation_automatique'])
                ));
                if (empty($aff) === true) {
                    $this->addToMessage(sprintf(__("Affectation automatique : non-trouvée (identifiant incorrecte).")));
                    $this->correct = false;
                }
            }
        }
    }

    /**
    * Méthode permettant de définir des valeurs à envoyer en base après
    * validation du formulaire d'ajout.
    *
    * @param array $val tableau des valeurs retournées par le formulaire
    *
    * @return void
    */
    function setValFAjout($val = array()) {

        if (
            $this->f->is_option_dossier_saisie_numero_enabled() === true
            || $this->f->is_option_dossier_saisie_numero_complet_enabled() === true
        ) {
            // ajoute les valeurs des champs fictifs à '$this->valF'
            // (la classe générée parente n'appelant pas la méthode parente qui fait ça pour tous les
            // champs, par défaut).
            foreach(array(
                    'num_doss_type_da',
                    'num_doss_code_depcom',
                    'num_doss_annee',
                    'num_doss_division',
                    'num_doss_sequence',
                    'num_doss_manuel'
                    ) as $key) {
                if (isset($val[$key])) {
                    $this->valF[$key] = $val[$key];
                }
            }
        } 
        if (
            $this->f->is_option_dossier_saisie_numero_complet_enabled() === true) {
            // ajoute les valeurs des champs fictifs à '$this->valF'
            // (la classe générée parente n'appelant pas la méthode parente qui fait ça pour tous les
            // champs, par défaut).
            foreach(array(
                    'num_doss_complet'
                    ) as $key) {
                if (isset($val[$key])) {
                    $this->valF[$key] = $val[$key];
                }
            }
        }

        if (isset($val['affectation_automatique']) === true) {
            $this->valF['affectation_automatique'] = $val['affectation_automatique'];
        }

        parent::setValFAjout($val);
    }

    /**
     * Surcharge pour retirer les champs fictifs
     *
     * @return boolean
     */
    function triggerajouter($id, &$dnu1 = null, $val = array(), $dnu2 = null) {
        if (
            $this->f->is_option_dossier_saisie_numero_enabled() === true
            || $this->f->is_option_dossier_saisie_numero_complet_enabled() === true
        ) {
            foreach(array(
                    'num_doss_type_da',
                    'num_doss_code_depcom',
                    'num_doss_annee',
                    'num_doss_division',
                    'num_doss_sequence',
                    'num_doss_manuel'
                    ) as $key) {
                //
                if (isset($this->valF[$key]) === true) {
                    unset($this->valF[$key]);
                }
            }
        }

        if ($this->f->is_option_dossier_saisie_numero_complet_enabled() === true) {
            foreach(array(
                    'num_doss_complet',
                    'no_num_doss_complet'
                    ) as $key) {
                //
                if (isset($this->valF[$key]) === true) {
                    unset($this->valF[$key]);
                }
            }
        }

        $ret = parent::triggerajouter($id, $dnu1, $val, $dnu2);

        if (isset($val['affectation_automatique']) === true) {
            unset($val['affectation_automatique']);
        }
        if (isset($this->valF['affectation_automatique']) === true) {
            unset($this->valF['affectation_automatique']);
        }

        return $ret;
    }

    /**
     * Surcharge pour passer le champ commune et dossier_autorisation_type_detaille en chosen
     *
     */
    function setSelect(&$form, $maj, &$dnu1 = null, $dnu2 = null) {
        parent::setSelect($form, $maj, $dnu1, $dnu2);

        // dossier_autorisation_type_detaille
        $form->setSelect(
            'dossier_autorisation_type_detaille', $this->view_load_select_datd($form, $maj)
        );

        if ($this->f->is_option_dossier_commune_enabled()) {
            $form->setSelect(
                'commune', $this->view_load_select_commune($form, $maj)
            );
        }

        // affectation_automatique
        $this->init_select(
            $form,
            $dbnu1,
            $maj,
            null,
            "affectation_automatique",
            $this->get_var_sql_forminc__sql("affectation_automatique"),
            $this->get_var_sql_forminc__sql("affectation_automatique_by_id"),
            false
        );

        // nature des travaux
        $form->setSelect(
            'nature_travaux',
            $this->loadSelectNatureTravaux($form, "demande_type")
        );
    }

    /**
     *
     * @return string
     */
    function get_var_sql_forminc__sql_affectation_automatique() {
        return "
            SELECT
                affectation_automatique.affectation_automatique,
                affectation_automatique.affectation_manuelle
            FROM
                ".DB_PREFIXE."affectation_automatique
            WHERE
                affectation_automatique.affectation_manuelle IS NOT NULL
                AND affectation_automatique.affectation_manuelle != ''
                AND affectation_automatique.instructeur IS NOT NULL
            ORDER BY
                affectation_automatique.affectation_automatique ASC NULLS LAST";
    }

    /**
     *
     * @return string
     */
    function get_var_sql_forminc__sql_affectation_automatique_by_id() {
        return "
            SELECT
                affectation_automatique.affectation_automatique,
                affectation_automatique.affectation_manuelle
            FROM
                ".DB_PREFIXE."affectation_automatique
            WHERE
                affectation_automatique.affectation_automatique = <idx>";
    }
}
