<?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"
        );
    }

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

    /**
     *
     * @return array
     */
    function get_var_sql_forminc__champs() {
        $champs = parent::get_var_sql_forminc__champs();

        if ($this->f->is_option_dossier_saisie_numero_enabled() === true) {
            // Ajoute les "faux" champs composant le numéro de dossier.
            // Seul les champs 'num_doss_division' et 'num_doss_sequence' seront effectivement utilisés,
            // les autres n'ont que pour but de fournir un affichage indicatif à l'utilisateur.
            $date_demande_pos = array_search('demande.date_demande', $champs);
            if ($date_demande_pos !== false) {
                array_splice($champs, $date_demande_pos + 1, 0, array(
                    "'' as num_doss_manuel",
                    "'' as num_doss_type_da",
                    "'' as num_doss_code_depcom",
                    "'' as num_doss_annee",
                    "'' as num_doss_division",
                    "'' as num_doss_sequence",
                ));
            }
            else {
                // handle the error
                $error_message = sprintf(__("Missing field '%s' in '%s'"), "demande.date_demande", __METHOD__."()");
                $this->addToLog(__METHOD__."(): $error_message", DEBUG_MODE);
                $this->f->displayMessage("error", $error_message);
            }
        }

        return $champs;
    }

    /**
     * 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 = $collectivite_parameters['departement'];
                $code_commune = $collectivite_parameters['commune'];
                if(!is_numeric($code_departement)) {
                    $error_msg = sprintf(__("om_parametre '%s' invalide (%s). Doit être numérique."),
                                         '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
            $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
                    $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();

        // id de la collectivite
        $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 = $this->f->get_submitted_get_value('om_collectivite');
        // Type détaillé du dossier d'autorisation
        $datd = $this->f->get_submitted_get_value('datd');
        // Références cadastrales
        $ref_cadas = $this->f->get_submitted_get_value('ref_cadas');

        // 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, $ref_cadas);

        printf(json_encode($response));
    }

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

        if ($maj == 0
            && $this->f->is_option_dossier_saisie_numero_enabled() === true) {
            //
            $form->setOnchange("date_demande", "update_num_dossier_annee($(this));");
            $form->setOnchange("dossier_autorisation_type_detaille", "changeDemandeType(); update_num_dossier_type_da(this);");
            $form->setOnchange("om_collectivite", "update_num_dossier_code_depcom(this);");
            $form->setOnchange("num_doss_manuel", "toggle_num_dossier_manuel(this);");
            $form->setOnchange("num_doss_division", "this.value=this.value.toUpperCase(); check_input_is_alpha_num(this);");
        }
    }

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

        // Par défaut les champs sont tous cachés
        $form->setType('num_doss_type_da', 'hidden');
        $form->setType('num_doss_code_depcom', 'hidden');
        $form->setType('num_doss_annee', 'hidden');
        $form->setType('num_doss_division', 'hidden');
        $form->setType('num_doss_sequence', 'hidden');
        $form->setType('num_doss_manuel', 'hidden');

        //
        if ($maj == 0
            && $this->f->is_option_dossier_saisie_numero_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', 'textreadonlynolabel');
            $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');
        }
    }

    /**
     *
     */
    function setLib(&$form,$maj) {
        parent::setLib($form,$maj);
        //libelle des champs
        
        $form->setLib('num_doss_manuel', __('Saisir le numéro de dossier'));
    }

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

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

    /**
     * Vérifie si un dossier d'autorisation avec cette numérotation existe déjà.
     *
     * @return boolean
     */
    function existsDAWithNumeroDossierSeq($idDAdt, $date_demande, $collectivite_id, $num_doss_seq) {

        if (empty($idDAdt) || empty($date_demande) || empty($collectivite_id) || empty($num_doss_seq)) {
            return null;
        }

        // code du type de DA
        $sql = "SELECT da_t.code
        FROM ".DB_PREFIXE."dossier_autorisation_type as da_t
        INNER JOIN ".DB_PREFIXE."dossier_autorisation_type_detaille as da_t_d
        ON da_t.dossier_autorisation_type=da_t_d.dossier_autorisation_type
        WHERE da_t_d.dossier_autorisation_type_detaille=".$idDAdt.";";
        $code_type_da = $this->f->db->getone($sql);
        $this->addToLog("setValFAjout(): db->getone(\"".$sql."\")", VERBOSE_MODE);
        database::isError($code_type_da);

        // annee date demande
        $annee = date('y', strtotime($date_demande));

        // code département et commune
        $collectivite_parameters = $this->f->getCollectivite($collectivite_id);
        if (!isset($collectivite_parameters['departement'])) {
            $this->f->addToLog(__METHOD__."(): ERROR om_parametre 'departement' inexistant.",
                               DEBUG_MODE);
            return false;
        }
        if (!isset($collectivite_parameters['commune'])) {
            $this->f->addToLog(__METHOD__."(): ERROR om_parametre 'commune' inexistant.",
                               DEBUG_MODE);
            return false;
        }
        $departement = $collectivite_parameters['departement'];
        $commune = $collectivite_parameters['commune'];

        // construction de la requête
        $num_dossier = str_pad($num_doss_seq, 4, '0', STR_PAD_LEFT);
        $clePrimaire = $code_type_da.$departement.$commune.$annee.'%'.$num_dossier;
        $sql = sprintf("SELECT
                            dossier_autorisation
                        FROM
                            %sdossier_autorisation
                        WHERE
                            dossier_autorisation LIKE '%s'",
                        DB_PREFIXE, $clePrimaire);
        $DA = $this->f->db->getone($sql);
        $this->f->addToLog(__METHOD__.'(): db->getone("'.$sql.'");', VERBOSE_MODE);
        return $DA !== null;
    }

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

        // 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
            && 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->existsDAWithNumeroDossierSeq(
                        $this->valF['dossier_autorisation_type_detaille'],
                        $this->valF["date_demande"],
                        $this->valF['om_collectivite'],
                        intval($val['num_doss_sequence'])) === 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) {
                if (empty($val['num_doss_division']) === true) {
                    $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']) > 1 && 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;
                }
            }
        }
    }

    /**
    * 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) {
            // 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];
                }
            }
            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) {
            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]);
                }
            }
        }
        return parent::triggerajouter($id, $dnu1, $val, $dnu2);
    }
}
