<?php
/**
 * DBFORM - 'instruction_notification_manuelle' - Surcharge instruction.
 *
 * @package openads
 * @version SVN : $Id$
 */

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

//
class instruction_notification_manuelle extends instruction {

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

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

        // ACTION - 411 - view_notification_manuelle
        $this->class_actions[411] = array(
            "identifier" => "notification_manuelle",
            "view" => "view_notification_manuelle",
            "permission_suffix" => "modifier",
        );

        // ACTION - 420 - view_notification_service_consulte
        $this->class_actions[420] = array(
            "identifier" => "notification_service_consulte",
            "view" => "view_notification_service_consulte",
            "permission_suffix" => "modifier",
        );

        // ACTION - 430 - view_notification_tiers_consulte
        $this->class_actions[430] = array(
            "identifier" => "notification_tiers_consulte",
            "view" => "view_notification_tiers_consulte",
            "permission_suffix" => "modifier",
        );
    }

    /**
     * VIEW - view_notification_manuelle.
     *
     * Ouvre le sous-formulaire en ajaxIt dans un overlay.
     * Cette action est bindée pour utiliser la fonction popUpIt.
     *
     * @return void
     */
    function view_notification_manuelle() {
        // TODO : refactoriser ce code en utilisant les méthodes créées pour le formualire de notif des services consultés
        // Vérification de l'accessibilité sur l'élément
        $this->checkAccessibility();
        // Préparation du type de message de retour
        $message_class = "valid";
        // Non affichage du fil d'ariane
        $this->getSubFormTitle('');

        // Vérification que le paramétrage nécessaire pour l'envoi des notifications existe
        $dossier = $this->getVal('dossier');
        $collectivite_di = $this->get_dossier_instruction_om_collectivite($dossier);
        
        // Récupération de la catégorie et notification des demandeurs choisis
        $categorie = $this->f->get_param_option_notification($collectivite_di);
        // Récupération de la liste des demandeurs notifiables
        if ($categorie == null || $categorie == '' || $categorie == 'portal') {
            // Pour une notification par portail récupère uniquement le pétitionnaire principal
            $demandeurs = $this->get_demandeurs_notifiable($this->getVal('dossier'), true);
        } else {
            $demandeurs = $this->get_demandeurs_notifiable();
        }

        // TODO : a améliorer
        // Récupération de l'id du pétitionnaire principal
        $sql = sprintf(
            'SELECT
                demandeur
            FROM
                %1$slien_demande_demandeur
                INNER JOIN %1$sdemande ON lien_demande_demandeur.demande = demande.demande
            WHERE
                demande.dossier_instruction = \'%2$s\' AND
                petitionnaire_principal = TRUE',
            DB_PREFIXE,
            $this->getVal('dossier')
        );
        $idPetitioPrinc = $this->f->db->getOne($sql);
        $this->f->addToLog(__METHOD__."(): db->getOne(\"".$sql."\")", VERBOSE_MODE);
        if ($this->f->isDatabaseError($idPetitioPrinc, true)){
            $this->f->addToLog(__METHOD__."(): ERROR db->getOne(\"".$sql."\")", DEBUG_MODE);
            $idPetitioPrinc = '';
        }


        //
        // Traitement des données du formulaire
        //
        // Si des données ont été envoyées par le formulaire
        $postValues = $this->f->get_submitted_post_value();
        if ($postValues != null && is_array($postValues) && $postValues != array()) {
            // Récupération de la liste des demandeurs à notifier
            $nbDemChoisis = 0;
            // Dans le cas d'une notification via le portail web seul le pétitionnaire
            // principale est notifiable. Dans le formulaire la liste des pétitionnaire
            // notifiable ne sera pas affiché.
            // Pour pouvoir réutiliser le traitement des autres modes de notification
            // l'id du demandeur est récupéré et ajouté aux valeurs récupéré du POST
            // en faisant comme si il s'agissait d'une case cochée dans le formulaire.
            if ($categorie == null || $categorie == '' || $categorie === 'portal') {
                $idPetiPrinc = array_keys($demandeurs);
                $postValues[$idPetiPrinc[0]] = 'Oui';
            }
            // Création d'une notification et d'une tâche pour chaque demandeur à notifier
            $idInstructionAnnexe = null;
            // Récupération de l'id de l'instruction du doc choisi comme annexe
            if (array_key_exists('instruction_signee_finalisee', $postValues)) {
                $idInstructionAnnexe = $postValues['instruction_signee_finalisee'];
            }
            foreach ($postValues as $idChamps => $valeur) {
                if ($valeur == 'Oui' && is_numeric($idChamps)) {
                    $idDemandeur = $idChamps;
                    $nbDemChoisis++;
                    // Ajout de la notif et récupération de son id
                    $idNotif = $this->ajouter_notification(
                        $this->getVal($this->clePrimaire),
                        $this->f->get_connected_user_login_name(),
                        $demandeurs[$idDemandeur],
                        $collectivite_di,
                        false,
                        $idInstructionAnnexe
                    );
                    if ($idNotif === false) {
                            $message_class = "error";
                            $message = __("Erreur lors de la génération de la notification au(x) pétitionnaire(s).");
                            $this->f->displayMessage($message_class, $message);
                            // quitte la boucle si l'ajout de la notification échoue
                            break;
                    }
                    // Création de la tache en lui donnant l'id de la notification
                    $notification_by_task = $this->notification_by_task(
                        $idNotif,
                        $this->getVal('dossier'),
                        $categorie
                    );
                    if ($notification_by_task === false) {
                        $message_class = "error";
                        $message = __("Erreur lors de la génération de la notification au(x) pétitionnaire(s).").'<br/>';
                        $this->f->displayMessage($message_class, $message);
                        // quitte la boucle si l'ajout de la tache de notification échoue
                        break;
                    }
                }
            }
            if ($nbDemChoisis === 0) {
                $message = __("Aucun pétitionnaire n'a été sélectionné.").'<br/>';
                $this->f->displayMessage($message_class, $message);
            } elseif ($message_class === 'valid') {
                // Message de valisation si il n'y a pas eu d'erreur au cours du traitement
                $message = sprintf('%s<br/>%s', __("La notification a été générée."), __("Le suivi de la notification est disponible depuis l'instruction."));
                $this->f->displayMessage($message_class, $message);
            }
        }

        //
        // Affichage du formulaire
        //
        // Récupération du paramétrage d'affichage de la vue
        $evenement = $this->get_inst_evenement($this->getVal('evenement'));
        $moyenNotification = $this->f->get_param_option_notification($collectivite_di);
        $selectionPetitio = $moyenNotification != null && $moyenNotification != 'portal' ?
            true : false;
        $typeNotif = $evenement->getVal('notification');
        $selectAnnexe = $typeNotif == 'notification_manuelle_annexe' || $typeNotif == 'notification_manuelle_annexe_signature_requise' ?
            true : false;

        $champs = array();
        // Préparation des champs de sélection des demandeurs
        if ($selectionPetitio === true) {
            if ($demandeurs === array()) {
                // Affiche un message d'erreur si aucun demandeur ne peut être notifié
                $message_class = "error";
                $message = _("Aucun demandeur notifiable");
                $this->f->displayMessage($message_class, $message);
                return;
            }
            // Préparation de l'instanciation de l'objet formulaire avec 1 champs par demandeur
            $champs = array_keys($demandeurs);
        }

        // Vérification du paramétrage de la notification
        if (! $this->is_parametrage_notification_correct($collectivite_di)) {
            $message_class = "error";
            $message = __("Attention l'url d'accès au(x) document(s) notifié(s) n'est pas paramétrée.");
            $this->f->displayMessage($message_class, $message);
        }

        // Préparation du champs de sélection de l'annexe
        if ($selectAnnexe === true) {
            // Préparation du champs de select de l'annexe
            $champs[] = "instruction_signee_finalisee";
            // Recupération du contenu du select. Seul les instruction, du dossier, ayant une édition
            // finalisé et signé doivent pouvoir être sélectionnées.
            $sql = sprintf(
                'SELECT
                    evenement.libelle,
                    instruction.instruction
                FROM
                    %1$sevenement
                    INNER JOIN %1$sinstruction ON instruction.evenement=evenement.evenement 
                WHERE
                    instruction.date_retour_signature is not null
                    and om_final_instruction=true
                    and instruction.instruction != %2$s
                    and instruction.dossier=\'%3$s\'',
                DB_PREFIXE,
                $this->getVal($this->clePrimaire),
                $this->getVal("dossier")
            );
            
            $res = $this->f->db->query($sql);
            $this->addToLog(__METHOD__." : db->query(\"".$sql."\");", VERBOSE_MODE);
            $this->f->isDatabaseError($res);

            // Remplissage du tableau du select 
            $contenu = array(
                0 => array(""),
                1 => array(_('choisir')." "._('evenement'))
            );
            while ($row=& $res->fetchRow(DB_FETCHMODE_ASSOC)) {
                $contenu[0][] = $row['instruction'];
                $contenu[1][] = $row['libelle'];
            }
        }

        // Affichage du formulaire, si il y a des élements à afficher
        if ($champs != array()) {
            // Instanciation du formulaire avec les champs voulus
            $form = $this->f->get_inst__om_formulaire(array(
                "validation" => 0,
                "maj" => $this->getParameter("maj"),
                "champs" => $champs
            ));
            $listIdDemandeurs = array_keys($demandeurs);
            $premierChamps = isset($listIdDemandeurs[0]) ? $listIdDemandeurs[0] : null;
            $dernierChamps = null;

            // Paramétrage des champs correspondant aux différents demandeurs
            if ($selectionPetitio === true) {
                foreach ($listIdDemandeurs as $idDemandeur) {
                    $dernierChamps = $idDemandeur;
                    // Paramétrage des champs du formulaire
                    $form->setType($idDemandeur, 'checkbox');
                    $form->setTaille($idDemandeur, 1);
                    $form->setMax($idDemandeur, 1);
                    $form->setVal($idDemandeur, 'f');
    
                    // Récupération des informations du demandeur
                    $demandeur = $this->f->get_inst__om_dbform(array(
                        "obj" => 'demandeur',
                        "idx" => $idDemandeur,
                    ));
                    // TODO : optimiser la récuépration du nom du demandeur ou écrire une méthode servant
                    // à la récupérer
                    // Comme il ne peut y avoir de nom que pour une personne morale ou un particulier
                    // en utilisant tous les champs et en faisant un trim l'intitulé peut être récupéré
                    $intituleDem =
                        $demandeur->getVal('particulier_nom').
                        ' '.
                        $demandeur->getVal('particulier_prenom').
                        ' '.
                        $demandeur->getVal('personne_morale_denomination').
                        ' '.
                        $demandeur->getVal('personne_morale_raison_sociale');

                    if ($demandeur->getVal('personne_morale_nom') != '' &&
                        $demandeur->getVal('personne_morale_prenom') != '') {
                        $intituleDem .= sprintf(
                            ' représenté par %1$s %2$s',
                            $demandeur->getVal('personne_morale_nom'),
                            $demandeur->getVal('personne_morale_prenom')
                        );
                    }
                    // Récupération du type de pétitionnaire à partir des infos de la demande
                    $typeDemandeur = $idPetitioPrinc == $demandeur->getVal('demandeur') ?
                        __('pétitionnaire principal') :
                        __($demandeur->getVal('type_demandeur'));

                    $lib = sprintf(
                        '%1$s | %2$s | %3$s',
                        $intituleDem,
                        $demandeur->getVal('courriel'),
                        $typeDemandeur
                    );
                    $form->setLib($idDemandeur, trim($lib));
                }
            }

            // Parmétrage du champs annexe dans le formulaire
            if ($selectAnnexe === true) {
                $form->setType('instruction_signee_finalisee', 'select');
                $form->setLib('instruction_signee_finalisee', 'pièce à joindre');
                $form->setSelect("instruction_signee_finalisee", $contenu);
                $form->setVal("instruction_signee_finalisee", '');
            }

            if ($premierChamps != null) {
                $form->setBloc($premierChamps, 'D', _("Sélection des pétitionnaires à notifier"), "alignFormSpec");
                $form->setBloc($dernierChamps, 'F', "", "alignFormSpec");
            }
            $form->setBloc('instruction_signee_finalisee','D', _("Sélection d'une annexe"), "alignFormSpec");
            $form->setBloc('instruction_signee_finalisee','F', "", "alignFormSpec");

            // Ouverture du formulaire de sélection des demandeurs
            $this->f->layout->display__form_container__begin(array(
                "action" => '',
                "onsubmit" => "affichersform('instruction_notification_manuelle', '".
                    $this->getDataSubmit().
                    "', this); validation_formulaire_notification_manuelle(); return false;",
                "name" => "f2",
            ));
            // Ouverture du conteneur de formulaire
            $form->entete();
            // affichage des champs
            $form->afficher($champs, 0, false, false);
            // Fermeture du conteneur de formulaire
            $form->enpied();
            $this->f->layout->display__form_controls_container__begin(array(
                "controls" => "bottom",
            ));
            // Affichage du bouton valider
            $this->f->layout->display__form_input_submit(array(
                "name" => "submit-directory",
                "value" => __("Valider"),
                "class" => "boutonFormulaire",
            ));
            $this->f->layout->display__form_controls_container__end();
            $this->f->layout->display__form_container__end();
        }
    }

    /**
     * VIEW - view_notification_service_consulte.
     *
     * Formulaire de paramétrage de la notification de l'instruction au
     * service consulte.
     * Ce formulaire est divisé en deux parties :
     *  1) Sélection des services consultés parmis la liste des services
     *     ayant une adresse mail (minimum) et pouvant être notifier par
     *     mail
     *  2) Sélection des pièces à transmettre dans la notification parmis
     *     la liste des documents d'instruction validé et signé et la
     *     liste des retours d'avis
     *
     * A la validation de ce formulaire le traitement d'envoi des mails est
     * déclenché et le suivi des notifications envoyées est réalisé.
     *
     * @return void
     */
    function view_notification_service_consulte() {
        // Vérification de l'accessibilité sur l'élément
        $this->checkAccessibility();
        // Non affichage du fil d'ariane
        $this->getSubFormTitle('');


        //
        // Traitement des données du formulaire
        //
        // Si des données ont été envoyées par le formulaire
        $postValues = $this->f->get_submitted_post_value();
        if ($postValues != null && is_array($postValues) && $postValues != array()) {
            // Récupèration de la liste des mails a envoyer
            $mails = array();
            foreach ($postValues as $idService => $isChecked) {
                if ($isChecked == 'Oui' && is_numeric($idService)) {
                    // Récupération de la liste des adresses mail du service
                    $mails = array_merge($mails, $this->get_liste_destinataires_service($idService));
                }
            }
            if ($mails === array()) {
                $this->f->displayMessage(
                    "error",
                    __("Erreur, il n'y a aucun destinataire pour la notification.")
                );
                return;
            }

            // Préparation du paramétrage des annexes a envoyer
            $paramNotifAnnexe = array();
            if (is_array($postValues['annexes']) && $postValues['annexes'] != array()) {
                // Pour chaque annexe récupération du type de document et de son id
                foreach ($postValues['annexes'] as $annexe) {
                    // Gestion du cas ou la première ligne du select multiple est sélectionnée
                    if ($annexe == '') {
                        continue;
                    }
                    // Sépare le nom de la table de l'identifiant du document.
                    // ex : consultation_1 => $paramAnnexe[0] = consultation et $paramAnnexe[0] = 1
                    $paramAnnexe = explode('_', $annexe);
                    // Paramètre la notification du document avec les valeurs récupérées
                    if (! (is_array($paramAnnexe) && $paramAnnexe[0] != null && $paramAnnexe[1] != null)) {
                        $this->f->displayMessage(
                            "error",
                            __("Erreur, le format des données récupérées est invalide.")
                        );
                        return;
                    }
                    $paramNotifAnnexe[$paramAnnexe[1]] = array(
                        'tableDocument' => $paramAnnexe[0],
                        'isAnnexe' => true
                    );
                }
            }

            // Préparation des notifications pour chacune des adresses mails de la liste
            foreach ($mails as $mail) {
                // Ajout de la notif et récupération de son id
                $idNotif = $this->ajouter_notification_sans_annexe(
                    $this->getVal($this->clePrimaire),
                    $this->f->get_connected_user_login_name(),
                    $mail
                );
                if ($idNotif === false) {
                    $this->f->displayMessage(
                        "error",
                        __("Erreur lors de la génération de la notification au(x) service(s).")
                    );
                    return;
                }
                
                // Ajout d'un élément par annexes dans la table instruction_notification_document
                if (! $this->ajouter_notification_document_multiple($idNotif, $paramNotifAnnexe)) {
                    $message = __("Erreur lors de la génération de la notification du(des) document(s) au(x) service(s).");
                    $this->f->displayMessage("error", $message);
                    return;
                }

                // Création de la tache en lui donnant l'id de la notification
                $notification_by_task = $this->notification_by_task(
                    $idNotif,
                    $this->getVal('dossier'),
                    'mail',
                    'notification_service_consulte'
                );
                if ($notification_by_task === false) {
                    $this->f->displayMessage(
                        'error',
                        __("Erreur lors de la génération de la notification au(x) service(s).")
                    );
                    return;
                }
            }
            $this->f->displayMessage(
                'valid',
                __("La notification a été générée.")
            );
        }

        //
        // Affichage du formulaire
        //

        // Vérification du paramétrage de la notification
        $dossier = $this->getVal('dossier');
        $collectivite_di = $this->get_dossier_instruction_om_collectivite($dossier);
        $urlAccesNotif = $this->f->get_parametre_notification_url_acces($collectivite_di);
        if ($urlAccesNotif == null) {
            $this->f->displayMessage(
                'error',
                __("Attention l'url d'accès au(x) document(s) notifié(s) n'est pas paramétrée.")
            );
            return;
        }
        // Récupération de la liste des champs du formulaire
        $champs = array();
        
        // Si il n'existe pas de service pouvant être notifié affiche
        // uniquement un message d'erreur pour prévenir l'utilisateur.
        $listeService = $this->get_liste_service_notifiable();
        if ($listeService === array()) {
            $this->f->displayMessage("error", _("Aucun service notifiable"));
            return;
        }
        // Sinon on ajoute un champs par service pouvant être notifié
        $champs = array_keys($listeService);
        // Ajout du champs de sélection des documents a annexé
        $champs[] = 'annexes';

        // Paramétrage du formulaire
        // Instanciation du formulaire
        $form = $this->f->get_inst__om_formulaire(array(
            "validation" => 0,
            "maj" => $this->getParameter("maj"),
            "champs" => $champs
        ));
        
        // Paramétrage des champs
        // Paramétrage des cases a cocher servant a choisir les services à notifier
        foreach ($listeService as $idService => $nomService) {
            $form->setType($idService, 'checkbox');
            $form->setLib($idService, $nomService);
            $form->setTaille($idService, 1);
            $form->setMax($idService, 1);
            $form->setVal($idService, 'f');
        }
        // Paramétrage du select multiple servant a choisir les annexes
        $form->setType('annexes', 'select_multiple');
        $form->setLib('annexes', __('pièce(s) à joindre'));
        $form->setTaille('annexes', 10);
        $form->setMax('annexes', 10);
        // Paramétrage du select du champs annexe avec la liste des documents
        // pouvant être transmis
        $listeDocumentInstruction = $this->get_liste_document_instruction();
        $listeAvisConsultation = $this->get_liste_avis_consultation();
        $listeDocument = array_merge($listeDocumentInstruction, $listeAvisConsultation);
        $contenu = array(
            array_merge(array(''), array_keys($listeDocument)),
            array_merge(array(_('sélectionner annexe(s)')), array_values($listeDocument))
        );
        $form->setSelect("annexes", $contenu);
        $form->setVal("annexes", '');

        // Mise en forme des blocs du formulaire
        reset($listeService);
        $form->setBloc(key($listeService), 'D', _("Sélection des services à notifier"), "alignFormSpec");
        end($listeService);
        $form->setBloc(key($listeService), 'F', "", "alignFormSpec");
        $form->setBloc('annexes', 'D', _("Sélection des annexes"), "alignFormSpec");
        $form->setBloc('annexes', 'F', "", "alignFormSpec");

        // Affichage du formulaire
        $onsubmit = sprintf(
            "affichersform('instruction_notification_manuelle', '%1\$s', this);
            validation_formulaire_notification_manuelle();
            return false;",
            $this->getDataSubmit()
        );
        $this->afficher_formulaire_notification($form, $champs, $onsubmit);
    }

    /**
     * VIEW - view_notification_tiers_consulte.
     *
     * Formulaire de paramétrage de la notification de l'instruction au
     * tiers consulte.
     * Ce formulaire est divisé en deux parties :
     *  1) Sélection des tiers consultés parmis la liste des tiers
     *     ayant une adresse mail (minimum) et pouvant être notifier par
     *     mail.
     *  2) Sélection des pièces à transmettre dans la notification parmis
     *     la liste des documents d'instruction validé et signé et la
     *     liste des retours d'avis
     *
     * A la validation de ce formulaire le traitement d'envoi des mails est
     * déclenché et le suivi des notifications envoyées est réalisé.
     *
     * @return void
     */
    function view_notification_tiers_consulte() {
        // Vérification de l'accessibilité sur l'élément
        $this->checkAccessibility();
        // Non affichage du fil d'ariane
        $this->getSubFormTitle('');

        //
        // Traitement des données du formulaire
        //
        // Si des données ont été envoyées par le formulaire
        $postValues = $this->f->get_submitted_post_value();
        if ($postValues != null && is_array($postValues) && $postValues != array()) {
            // Récupèration de la liste des mails a envoyer
            $mails = array();
            foreach ($postValues['tiers_consulte'] as $idTiers) {
                if ($idTiers != '') {
                    // Récupération de la liste des adresses mail des tiers consulté
                    $mails = array_merge($mails, $this->get_liste_destinataires_tiers($idTiers));
                }
            }
            if ($mails === array()) {
                $this->f->displayMessage(
                    "error",
                    __("Erreur, il n'y a aucun destinataire pour la notification.")
                );
                return;
            }

            // Préparation du paramétrage des annexes a envoyer
            $paramNotifAnnexe = array();
            // Pour chaque annexe récupération du type de document et de son id
            foreach ($postValues['annexes'] as $annexe) {
                // Gestion du cas ou la première ligne du select multiple est sélectionnée
                if ($annexe == '') {
                    continue;
                }
                // Sépare le nom de la table de l'identifiant du document.
                // ex : consultation_1 => $paramAnnexe[0] = consultation et $paramAnnexe[0] = 1
                $paramAnnexe = explode('_', $annexe);
                // Paramètre la notification du document avec les valeurs récupérées
                if (! (is_array($paramAnnexe) && $paramAnnexe[0] != null && $paramAnnexe[1] != null)) {
                    $this->f->displayMessage(
                        "error",
                        __("Erreur, le format des données récupérées est invalide.")
                    );
                    return;
                }
                $paramNotifAnnexe[$paramAnnexe[1]] = array(
                    'tableDocument' => $paramAnnexe[0],
                    'isAnnexe' => true
                );
            }

            // Préparation des notifications pour chacune des adresses mails de la liste
            foreach ($mails as $mail) {
                // Ajout de la notif et récupération de son id
                $idNotif = $this->ajouter_notification_sans_annexe(
                    $this->getVal($this->clePrimaire),
                    $this->f->get_connected_user_login_name(),
                    $mail
                );
                if ($idNotif === false) {
                    $this->f->displayMessage(
                        "error",
                        __("Erreur lors de la génération de la notification au(x) tier(s).")
                    );
                    return;
                }
                
                // Ajout d'un élément par annexes dans la table instruction_notification_document
                if (! $this->ajouter_notification_document_multiple($idNotif, $paramNotifAnnexe)) {
                    $message = __("Erreur lors de la génération de la notification du(des) document(s) au(x) service(s).");
                    $this->f->displayMessage("error", $message);
                    return;
                }

                // Création de la tache en lui donnant l'id de la notification
                $notification_by_task = $this->notification_by_task(
                    $idNotif,
                    $this->getVal('dossier'),
                    'mail',
                    'notification_tiers_consulte'
                );
                if ($notification_by_task === false) {
                    $this->f->displayMessage(
                        'error',
                        __("Erreur lors de la génération de la notification au(x) tier(s).")
                    );
                    return;
                }
            }
            $this->f->displayMessage(
                'valid',
                __("La notification a été générée.")
            );
        }

        //
        // Affichage du formulaire
        //

        // Vérification du paramétrage de la notification
        $dossier = $this->getVal('dossier');
        $collectivite_di = $this->get_dossier_instruction_om_collectivite($dossier);
        $urlAccesNotif = $this->f->get_parametre_notification_url_acces($collectivite_di);
        if ($urlAccesNotif == null) {
            $this->f->displayMessage(
                'error',
                __("Attention l'url d'accès au(x) document(s) notifié(s) n'est pas paramétrée.")
            );
            return;
        }
        
        // Si il n'existe pas de tiers pouvant être notifié affiche
        // uniquement un message d'erreur pour prévenir l'utilisateur.
        $listeService = $this->get_liste_tiers_notifiable();
        if ($listeService === array()) {
            $this->f->displayMessage("error", _("Aucun tiers notifiable"));
            return;
        }

        // Paramétrage du formulaire
        // Instanciation du formulaire
        $champs = array('tiers_consulte', 'annexes');
        $form = $this->f->get_inst__om_formulaire(array(
            "validation" => 0,
            "maj" => $this->getParameter("maj"),
            "champs" => $champs
        ));
        
        // Paramétrage du select multiple servant a choisir les tiers
        $contenu = array(
            array_merge(array(''), array_keys($listeService)),
            array_merge(array(_('sélectionner tier(s)')), array_values($listeService))
        );
        $form->setType('tiers_consulte', 'select_multiple');
        $form->setLib('tiers_consulte', __('Tiers à notifier'));
        $form->setTaille('tiers_consulte', 20);
        $form->setMax('tiers_consulte', 20);
        $form->setSelect("tiers_consulte", $contenu);
        $form->setVal('tiers_consulte', '');
        
        // Paramétrage du select multiple servant a choisir les annexes
        $form->setType('annexes', 'select_multiple');
        $form->setLib('annexes', __('pièce(s) à joindre'));
        $form->setTaille('annexes', 10);
        $form->setMax('annexes', 10);
        // Paramétrage du select du champs annexe avec la liste des documents
        // pouvant être transmis
        $listeDocumentInstruction = $this->get_liste_document_instruction();
        $listeAvisConsultation = $this->get_liste_avis_consultation();
        $listeDocument = array_merge($listeDocumentInstruction, $listeAvisConsultation);
        $contenu = array(
            array_merge(array(''), array_keys($listeDocument)),
            array_merge(array(_('sélectionner annexe(s)')), array_values($listeDocument))
        );
        $form->setSelect("annexes", $contenu);
        $form->setVal("annexes", '');

        // Mise en forme des blocs du formulaire
        $form->setBloc('tiers_consulte', 'D', _("Sélection des tiers à notifier"), "alignFormSpec");
        $form->setBloc('tiers_consulte', 'F', "", "alignFormSpec");
        $form->setBloc('annexes', 'D', _("Sélection des annexes"), "alignFormSpec");
        $form->setBloc('annexes', 'F', "", "alignFormSpec");

        // Affichage du formulaire
        $onsubmit = sprintf(
            "affichersform('instruction_notification_manuelle', '%1\$s', this);
            validation_formulaire_notification_manuelle();
            return false;",
            $this->getDataSubmit()
        );
        $this->afficher_formulaire_notification($form, $champs, $onsubmit);
    }

    protected function afficher_formulaire_notification(
        $form,
        $champs,
        $formOnsubmit = '',
        $valueBoutonValidation = 'Valider',
        $formAction = '',
        $formName = 'f2',
        $nameBoutonValidation = "submit-directory",
        $classBoutonValidation = "boutonFormulaire"
    ) {
        // Ouverture du formulaire
        $this->f->layout->display__form_container__begin(array(
            "action" => $formAction,
            "onsubmit" => $formOnsubmit,
            "name" => $formName,
        ));
        // Ouverture du conteneur de formulaire
        $form->entete();
        // affichage des champs
        $form->afficher($champs, 0, false, false);
        // Fermeture du conteneur de formulaire
        $form->enpied();
        // Ouverture de la zone contenant le bouton de validation
        $this->f->layout->display__form_controls_container__begin(array(
            "controls" => "bottom",
        ));
        // Affichage du bouton valider
        $this->f->layout->display__form_input_submit(array(
            "name" => $nameBoutonValidation,
            "value" => $valueBoutonValidation,
            "class" => $classBoutonValidation,
        ));
        // Fermeture de la zone contenant le bouton de validation
        $this->f->layout->display__form_controls_container__end();
        // Fermeture du formulaire
        $this->f->layout->display__form_container__end();
    }

    /**
     * TODO : faire en sorte que cette méthode permettent de récupérer les
     * doc pour la notif des demandeurs et celle des service
     */
    protected function get_liste_document_instruction() {
        $listeDocument = array();
        // Requête pour récupérer la liste des services consultés pouvant être notifiés
        $sql = sprintf(
            'SELECT
                evenement.libelle,
                instruction.instruction
            FROM
                %1$sevenement
                INNER JOIN %1$sinstruction ON instruction.evenement=evenement.evenement 
            WHERE
                instruction.date_retour_signature is not null
                and om_final_instruction=true
                and instruction.instruction != %2$s
                and instruction.dossier=\'%3$s\'
            ORDER BY
                evenement.libelle ASC',
            DB_PREFIXE,
            $this->getVal($this->clePrimaire),
            $this->getVal("dossier")
        );
        $res = $this->f->db->query($sql);
        // Gestion des erreurs de base de données
        $this->f->addToLog(__METHOD__."(): db->query(\"".$sql."\")", VERBOSE_MODE);
        if ($this->f->isDatabaseError($res, true)){
            $this->f->addToLog(__METHOD__."(): ERROR db->query(\"".$sql."\")", DEBUG_MODE);
            return $listeDocument;
        }
        // Rempli le tableau contenant la liste des services notifiables
        while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
            $listeDocument['instruction_'.$row['instruction']] = $row['libelle'];
        }
        return $listeDocument;
    }
    
    /**
     * TODO : faire en sorte que cette méthode permettent de récupérer les
     * doc pour la notif des demandeurs et celle des service
     */
    protected function get_liste_avis_consultation() {
        $listeDocument = array();
        // Requête pour récupérer la liste des services consultés pouvant être notifiés
        $sql = sprintf(
            'SELECT
                CONCAT(\'Avis - \', service.libelle) AS libelle,
                consultation.consultation
            FROM
                %1$sconsultation
                JOIN %1$sservice
                    ON consultation.service = service.service
            WHERE
                consultation.fichier IS NOT NULL
                AND consultation.date_retour is not null
                AND consultation.dossier=\'%3$s\'
            ORDER BY
                libelle ASC ',
            DB_PREFIXE,
            $this->getVal($this->clePrimaire),
            $this->getVal("dossier")
        );
        $res = $this->f->db->query($sql);
        // Gestion des erreurs de base de données
        $this->f->addToLog(__METHOD__."(): db->query(\"".$sql."\")", VERBOSE_MODE);
        if ($this->f->isDatabaseError($res, true)){
            $this->f->addToLog(__METHOD__."(): ERROR db->query(\"".$sql."\")", DEBUG_MODE);
            return $listeDocument;
        }
        // Rempli le tableau contenant la liste des services notifiables
        while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
            $listeDocument['consultation_'.$row['consultation']] = $row['libelle'];
        }
        return $listeDocument;
    }

    protected function get_liste_service_notifiable() {
        $listeService = array();
        // Requête pour récupérer la liste des services consultés pouvant être notifiés
        $sql = sprintf(
            'SELECT
                service.service,
                service.libelle
            FROM
                %1$sservice
            WHERE
                service.accepte_notification_email = TRUE
                AND email IS NOT NULL
            ORDER BY
                service.libelle ASC',
            DB_PREFIXE
        );
        $res = $this->f->db->query($sql);
        // Gestion des erreurs de base de données
        $this->f->addToLog(__METHOD__."(): db->query(\"".$sql."\")", VERBOSE_MODE);
        if ($this->f->isDatabaseError($res, true)){
            $this->f->addToLog(__METHOD__."(): ERROR db->query(\"".$sql."\")", DEBUG_MODE);
            return $listeService;
        }
        // Rempli le tableau contenant la liste des services notifiables
        while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
            $listeService[$row['service']] = $row['libelle'];
        }
        return $listeService;
    }

    /**
     * Récupère à l'aide d'une requête sql tous les tiers consulté
     * étant notifiable et ayant au moins une adresse mail enregistrée.
     *
     * Renvoie cette liset sous la forme d'un tableau dont les clés sont
     * les identifiants des tiers et les valeurs leur libellé.
     *
     * @return array
     */
    protected function get_liste_tiers_notifiable() {
        $listeTiers = array();
        // Requête pour récupérer la liste des tiers consultés pouvant être notifiés
        $sql = sprintf(
            'SELECT
                tiers_consulte.tiers_consulte,
                tiers_consulte.libelle
            FROM
                %1$stiers_consulte
            WHERE
                tiers_consulte.accepte_notification_email = TRUE
                AND liste_diffusion IS NOT NULL
            ORDER BY
                tiers_consulte.libelle ASC',
            DB_PREFIXE
        );
        $res = $this->f->db->query($sql);
        // Gestion des erreurs de base de données
        $this->f->addToLog(__METHOD__."(): db->query(\"".$sql."\")", VERBOSE_MODE);
        if ($this->f->isDatabaseError($res, true)){
            $this->f->addToLog(__METHOD__."(): ERROR db->query(\"".$sql."\")", DEBUG_MODE);
            return $listeTiers;
        }
        // Rempli le tableau contenant la liste des tiers notifiables
        while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
            $listeTiers[$row['tiers_consulte']] = $row['libelle'];
        }
        return $listeTiers;
    }

    /**
     * Récupère sous la forme d'un tableau la liste de
     * tous les mails du service dont l'identifiant est
     * passé en paramètre.
     *
     * @param integer identifiant du service dont on souhaite récupérer
     * les adresses mails
     * @return array tableau contenant les adresses mails
     */
    protected function get_liste_destinataires_service($idService) {
        $listeDestinataires = array();
        // Instanciation du service avec l'adresse mail fournie
        $service = $this->f->get_inst__om_dbform(array(
            "obj" => "service",
            "idx" => $idService,
        ));
        $mails = explode("\n", $service->getVal('email'));
        foreach ($mails as $mail) {
            $listeDestinataires[] = array(
                "destinataire" => $service->getVal('libelle').' - '.$mail,
                "courriel" => $mail
            );
        }
        return $listeDestinataires;
    }

    /**
     * Récupère sous la forme d'un tableau la liste de
     * tous les mails du tiers dont l'identifiant est
     * passé en paramètre.
     *
     * @param integer dentifiants du tiers dont on souhaite obtenir les adresses mails
     * @return array tableau contenant les adresses mails
     */
    protected function get_liste_destinataires_tiers($idTiers) {
        $listeDestinataires = array();
        // Instanciation du service avec l'adresse mail fournie
        $tiers = $this->f->get_inst__om_dbform(array(
            "obj" => "tiers_consulte",
            "idx" => $idTiers,
        ));
        $mails = explode("\n", $tiers->getVal('liste_diffusion'));
        foreach ($mails as $mail) {
            $listeDestinataires[] = array(
                "destinataire" => $tiers->getVal('libelle').' - '.$mail,
                "courriel" => $mail
            );
        }
        return $listeDestinataires;
    }

}// fin classe
