# -*- coding: UTF-8 -*-
###########################################################################
# Eole NG - 2007
# Copyright Pole de Competence Eole  (Ministere Education - Academie Dijon)
# Licence CeCill  cf /root/LicenceEole.txt
# eole@ac-dijon.fr
#
# etabs.py
#
# pages web concernant la gestion des établissements
#
###########################################################################
from twisted.web import static
from twisted.web.resource import Resource
from zephir.web.template.design import Design, proxy, get_user
from zephir.web.config import Navigation, ilike_syntax, etabs_sort_keys

import sys, traceback, os
from zephir.eolerpclib import xmlrpclib
from html import escape
from zephir.rapports import rapport
from zephir.web.html.erreur import *

def get_type(request,liste_etab):
    """Transforme la clef du type en son libellé
    """
    types = backend(proxy(request).etabs.get_types())[0]
    for etab in liste_etab:
        etab['type'] = types[str(etab['type'])]
    return liste_etab


class Etab(Design):
    """Ressource conteneur établissement
    """
    def __init__(self, *args, **kwargs):
        self.entites = {
            # ajout d'un etablissement
            'add' : AddEtab,
            'add2' : AddEtab2,
            'add3' : AddEtab3,
            'import' : ImportEtabDesc,
            'import_res':ImportEtabRes,
            # affichage d'un etablissement
            'rech':RechEtab,
            'get' :GetEtab,
            'aff':AfficheEtab,
            # 'get2' : GetEtab2(),
            # modification
            'edit': EditEtabDesc,
            'edit2': EditEtabIns,
            # suppression
            'del': DelEtab,
            'deleted':DeletedEtab,
            # ajout d'un type d'établissement
            'type': AddType,
            'type2': AddType2,
            'rapport':RapportEtab,
            'gen_rapport':RapportGenerique
            }
        super().__init__(*args, **kwargs)

    def getChild(self, name, request):


        if static.isDangerous(name):
            return static.dangerousPathError
        name = name.decode()
        if name in self.entites:
            return self.entites[name]()
        return self

    def wmfactory_menu(self, request):
        return Navigation(aide="page4.html").menu()

    def wmfactory_title(self,request):
        return "Gestion des établissements"

    def wmfactory_content(self, request):
        return """
<h1>Gestion des établissements</h1>
<p>
<a href="/etab/rech">Recherche d'un établissement</a><br />
<a href="/etab/add">Ajout d'un établissement</a><br />
<a href="/etab/type">Gestion des types d'établissement</a><br />
<a href="/etab/import">Importer des établissements</a><br />
</p>
"""

class RapportEtab(Design):
    """Liste d'un étab en pdf
    """
    isLeaf = True

    def getChild(self, name, request):
        if static.isDangerous(name):
            return static.dangerousPathError
        if name == b"rapport" :
            return self
        return Etab()

    def wmfactory_title(self,request):
        return "(%s) Rapport Étab" % get_user(request)

    def wmfactory_content(self, request):
        return self.content

    def renderView(self, request):
        try:
            try:
                self.rne = escape(request.args[b'rne'][0].decode())
                assert not self.rne == ""
            except Exception:
                raise FrontendError("identifiant")
            try:
                nom_pdf = rapport.Rapport(proxy(request),self.rne).pdf("detail_etab", "'"+self.rne+"'")

                self.content = """<p>
                <a href="/tmp/%s">Télécharger le rapport <img src="/images/pdf.png"></a><br/>
		</p><p>
                <a href="javascript:history.back()">Retour</a><br/>
                </p>""" % os.path.basename(nom_pdf)
            except xmlrpclib.ProtocolError:
                raise BackendError("""Vous n'êtes pas autorisé à effectuer cette action""")
            except:
                traceback.print_exc()
                raise BackendError

        except (FrontendError, BackendError) as e:
            self.content = e

        return self.content

class RapportGenerique(Design):
    """Bilan pdf de zephir
    """
    isLeaf = True

    def getChild(self, name, request):
        if static.isDangerous(name):
            return static.dangerousPathError
        if name == b"gen_rapport" :
            return self
        return Etab()

    def wmfactory_title(self,request):
        return "Rapport Générique"

    def wmfactory_content(self, request):
        return self.content

    def renderView(self, request):
        try:
            try:
                # FIXME --
                self.content = """<p>
                Rapport généré</p>
                <p><a href="/">Retour</a>
                </p>"""
                # génération du rapport
                r=rapport.Rapport(proxy(request))
                r.rapport_global()
            except:
                raise BackendError

        except (FrontendError, BackendError) as e:
            self.content = e

        return self.content

class ImportEtabDesc(Design):
    """Importation d'établissements dans la base
    """
    isLeaf = True

    def getChild(self, name, request):
        if static.isDangerous(name):
            return static.dangerousPathError
        if name == b"import" :
            return self
        return Etab()

    def wmfactory_menu(self, request):
        return Navigation(aide="page4.html#section6").menu()

    def wmfactory_title(self,request):
        return "(%s) Importation Étab" % get_user(request)

    def wmfactory_content(self, request):
        return self.content

    def _dump_html(self):
        return """
    <h1>Importation d'établissements</h1>
    <p>Les établissements existants seront mis à jour</p>
<table cellpadding="15" cellspacing="0" align="center" valign="middle" >
<FORM METHOD=POST ACTION="import_res" enctype="multipart/form-data">
<tr><td>
<INPUT NAME="fichier" TYPE="file"/>
</td></tr><tr><td align="center">
<INPUT type=SUBMIT value="importer">
</td></tr>
</form>
</table>
<br/>"""

    def renderView(self, request):
        try:
            try:
                self.content = self._dump_html()
            except xmlrpclib.ProtocolError:
                raise BackendError("""Vous n'êtes pas autorisé à effectuer cette action""")
            except:
                raise BackendError

        except (FrontendError, BackendError) as e:
            self.content = e

        return self.content

class ImportEtabRes(Design):
    """Importation effective d'établissements dans la base
    """
    isLeaf = True

    def getChild(self, name, request):
        if static.isDangerous(name):
            return static.dangerousPathError
        if name == b"import_res" :
            return self
        return Etab()

    def wmfactory_menu(self, request):
        return Navigation(aide="page4.html").menu()

    def wmfactory_title(self,request):
        return "(%s) Importation Étab" % get_user(request)

    def wmfactory_content(self, request):
        return self.content

    def renderView(self, request):
        try:
            try:
                fichier = request.args[b'fichier'][0].decode()
                assert fichier != ""
            except:
                raise FrontendError('fichier')
            self.content = """
            <p>Le fichier a bien été importé</p>
            """
            data=[]
            for line in fichier.split('\n'):
                if not ( line.startswith('#') or line == "" ):
                    # on découpe sur le délimiteur '|'
                    # on enlève les espace/tabs en début/fin de champ (Fixes #9165)
                    data.append([field.strip() for field in line.split('|')])
            try:
                not_found, new_etabs , errors = backend(proxy(request).etabs.import_etab(u(data)))
                not_found_info = new_infos = error_infos = ""
                if not_found:
                    not_found_info = "<p>Les établissements suivants ne sont \
pas référencés dans le fichier : <select><option>%s</option></select></p>" % "</option><option>".join(not_found)
                if new_etabs:
                    new_etabs = [ "%s : %s" % tuple(infos) for infos in new_etabs ]
                    new_infos = "<p>Les établissements suivants ont été \
créés :<select><option>%s</option></select></p>" % "</option><option>".join(new_etabs)
                if errors:
                    error_infos = """<font color="red">Erreurs d'import</font> : <select><option>%s</option></select></p>""" % "</option><option>".join(errors)
                self.content = """<b>Import des établissements terminés</b>
                <p>%s%s</p><p>%s</p><a href="/etab">retour au menu des &eacute;tablissements</a>""" % (new_infos, error_infos, not_found_info)
            except xmlrpclib.ProtocolError:
                raise BackendError("""Vous n'êtes pas autorisé à effectuer cette action""")
            except Exception as e :
                traceback.print_exc()
                raise BackendError


        except (FrontendError, BackendError) as e:
            self.content = e

        return self.content

class AddEtab(Design):
    """Creation d'un etablissement
    """

    isLeaf = True

    def getChild(self, name, request):
        if static.isDangerous(name):
            return static.dangerousPathError
        if name == b"add" :
            return self
        return Etab()

    def wmfactory_menu(self, request):
        return Navigation(aide="page4.html#section5").menu()

    def wmfactory_title(self,request):
        return "(%s) Nouvel Établissement" % get_user(request)

    def wmfactory_content(self, request):
        return """
<h1>Entrez l'identifiant du nouvel établissement</h1><br>

<script LANGUAGE="JavaScript"><!--
function validfields(form)
{
    //getting the values:
    if (form.rne.value.length > 8)
    {
        alert("RNE : 8 caractères maximum !");
        form.rne.focus();
        return false;
    }
    else
    {
        return true;
    }
}
//--></script>

<FORM METHOD=POST ACTION="add2" onSubmit="return validfields(this)">
<table cellpadding="15" cellspacing="0" align="center" valign="middle" >
<tr><td>Identifiant</td><td>
<input type=text size=8 name="rne" value=""></td></tr>
<tr><td algin="right">
<INPUT type="submit" value="Valider">
</td>
</td>
<td><input name="initialiser" value="Initialiser" type="reset" /></td>
</tr>
<tr><td colspan="2"><a href="/etab">Retour à la gestion des établissements</a></td></tr>
</tr>
</table>
</form>
"""

class AddEtab2(Design):
    """Formulaire de renseignement sur l'etab
    """
    isLeaf = True
    def getChild(self, name, request):
        if static.isDangerous(name):
            return static.dangerousPathError
        if name == b"add2" :
            return self
        return Etab()

    def _options(self,request):
        # récupération des types d'établissement existants
        dico = backend(proxy(request).etabs.get_types())[0]
        l = []

        dico_inv = {}

        for clef, valeur in list(dico.items()):
            dico_inv[valeur] = clef

        liste = list(dico_inv.keys())
        liste.sort()

        for clef in liste:
            s = """<OPTION VALUE="%s">%s</OPTION>""" % (dico_inv[clef],clef)
            l.append(s)

        return "\n".join(l)

    def _hidden(self, rne):
        return """<input type="hidden" name="rne" value="%s"/> """ % rne

    def formulaire(self, rne, rne_form, option_list):
        return """

<script LANGUAGE="JavaScript"><!--
function is_numeric(obj)
{
    var charpos = obj.value.search("[^0-9]");
    if(obj.value.length > 0 &&  charpos >= 0)
    {
        strError = obj.name+": valeur numérique";
        alert(strError);
        return false;
    }
    else
    {
        return true;
    }
}
function validfields(form)
{
    //getting the values:
    if (form.libelle.value.length > 200){
        alert("libelle : 200 caractères maximum !");
        form.libelle.focus();
        return false;
    }
    if (form.ville.value.length > 50){
        alert("ville : 50 caractères maximum !");
        form.ville.focus();
        return false;
    }
    if (form.adresse.value.length > 100){
        alert("adresse : 100 caractères maximum !");
        form.adresse.focus();
        return false;
    }
    if(!is_numeric(form.cp))
    {
        form.cp.focus();
        return false;
    }
    if (form.cp.value.length > 5){
        alert("code postal : 5 caractères maximum !");
        form.cp.focus();
        return false;
    }
    if (form.mail.value.length > 100){
        alert("mail : 100 caractères maximum !");
        form.mail.focus();
        return false;
    }
    if (form.telephone.value.length > 20){
        alert("telephone : 20 caractères maximum !");
        form.telephone.focus();
        return false;
    }
    if (form.fax.value.length > 20){
        alert("fax : 20 caractères maximum !");
        form.fax.focus();
        return false;
    }
    if (form.responsable.value.length > 30){
        alert("responsable : 30 caractères maximum !");
        form.responsable.focus();
        return false;
    }
    else{
        return true;
    }
}
//--></script>

<h1>Remplissez les champs décrivant l'établissement</h1>
<FORM METHOD=POST ACTION="add3" onSubmit="return validfields(this)">
<table cellpadding="5" cellspacing="0" align="center" valign="middle"
width="80%"><tr><td>RNE </td><td>""" + rne +  """</td></tr>""" + rne_form + """<tr><td>Nom du site *</td><td><input type="text" size=30 name="libelle" value=""></td></tr>
<tr><td>Adresse</td><td><input type="text" size="30" name="adresse" value=""></td></tr>
<tr><td>Ville *</td><td><input type="text" size="30" name="ville" value=""></td></tr>
<tr><td>Code postal *</td><td><input type="text" size="5" name="cp" value=""></td></tr>
<tr><td>Téléphone</td><td><input type="text" size="12" name="telephone" value=""></td></tr>
<tr><td>Fax</td><td><input type="text" size="12" name="fax" value=""></td></tr>
<tr><td>Adresse électronique</td><td><input type="text" size="20" name="mail" value=""></td></tr>
<tr><td>Responsable</td><td><input type="text" size="20" name="responsable" value=""></td></tr>
<tr><td>Remarques</td><td><textarea rows="3" cols="30" name="remarques"></textarea></td></tr>
<tr><td>Type d'établissement *</td><td>
<SELECT NAME="type">""" + option_list + """</SELECT>
</td></tr>
<tr><td align="right"><INPUT type="submit" value="Ok"></td>
<td align="right"><input name="initialiser" value="Initialiser" type="reset" /></td>
</tr>
<tr><td colspan="2" align="center"><a href="/etab">Retour à la gestion des établissements</a></td></tr>
</tr>
</table>
</form>
"""


    def wmfactory_title(self,request):
        return "(%s) Nouvel Étab" % get_user(request)

    def wmfactory_content(self, request):
        return self.content

    def renderView(self, request):
        try:
            try:
                self.rne = escape(request.args[b'rne'][0].decode())
                assert not self.rne == ""
            except Exception:
                raise FrontendError("identifiant")
            if len(self.rne) > 8:
                raise FrontendError("8 caractères maximum pour le numéro RNE")
            try:
                resultat = backend(proxy(request).etabs.get_etab(u(self.rne)))
                assert resultat == []
                self.content = self.formulaire(self.rne, self._hidden(self.rne), self._options(request))
            except xmlrpclib.ProtocolError:
                raise BackendError("""Vous n'êtes pas autorisé à effectuer cette action""")
            except Exception as e :
                raise BackendError("<p>Attention : l'identifiant que vous avez choisi existe déjà</p>")

        except Exception as e:
            self.content = e

        return self.content

class AddEtab3(Design):
    """Insertion de l'établissement dans la base
    """
    isLeaf = True
    def getChild(self, name, request):
        if static.isDangerous(name):
            return static.dangerousPathError
        if name == b"add3" :
            return self
        return Etab()

    def wmfactory_title(self,request):
        return "(%s) Nouvel Étab (Description)" % get_user(request)

    def wmfactory_content(self, request):
        return self.content

    def _dump_html(self,rne, libelle, adresse, ville, cp, telephone, fax, mail, responsable, remarques):
        return """<table cellpadding="5" cellspacing="0" align="center" valign="middle" width="70%">
<tr><td>Identifiant de l'établissement</td><td align=left>:</td><td>""" + rne + """</td>
</tr><tr><td width="30%">nom du site</td><td> : </td><td>""" + libelle + """</td></tr>
<tr><td width="30%">adresse</td><td> : </td><td>""" + adresse + """</td></tr>
<tr><td width="30%">ville</td><td> : </td><td>""" + ville + """ </td></tr>
<tr><td width="30%">code postal</td><td> : </td><td>""" + cp + """ </td></tr>
<tr><td width="30%">téléphone</td><td> : </td><td>""" + telephone + """ </td></tr>
<tr><td width="30%">fax</td><td> : </td><td>""" + fax + """</td></tr>
<tr><td width="30%">adresse mail</td><td> : </td><td><a href="mailto:""" + mail + """">
<font color=grey>""" + mail + """</a></td></tr>
<tr><td width="30%">responsable</td><td> : </td><td>""" + responsable + """</td></tr>
<tr><td width="30%">remarques</td><td> : </td><td>""" + remarques + """</td></tr>
</table>"""


    def renderView(self, request):
        try:
            # réception des variables de formulaire
            try:
                self.libelle= escape(request.args[b'libelle'][0].decode())
            except:
                self.libelle = ''
            try:
                self.adresse = escape(request.args[b'adresse'][0].decode())
            except:
                self.adresse = ''
            try:
                self.telephone = escape(request.args[b'telephone'][0].decode())
            except:
                self.telephone = ''
            try:
                self.fax = escape(request.args[b'fax'][0].decode())
            except:
                self.fax = ''
            try:
                self.mail = escape(request.args[b'mail'][0].decode())
            except:
                self.mail = ''
            try:
                self.responsable = escape(request.args[b'responsable'][0].decode())
            except:
                self.responsable = ''
            try:
                self.remarques = escape(request.args[b'remarques'][0].decode())
            except:
                self.remarques = ''
            for item in [b'rne', b'ville', b'cp', b'type']:
                if item not in request.args:
                    raise FrontendError(item.decode())
            self.rne = escape(request.args[b'rne'][0].decode())
            self.ville = escape(request.args[b'ville'][0].decode())
            self.cp = escape(request.args[b'cp'][0].decode())
            self.type = escape(request.args[b'type'][0].decode())
            if self.type == '':
                raise FrontendError('type')
            if self.ville == '':
                raise FrontendError('ville')
            if self.cp == '':
                raise FrontendError('code postal')
            try:
                assert self.rne and self.libelle
            except AssertionError:
                raise FrontendError("identifiant ou libellé")
            # insertion des données dans la base
            try:
                backend(proxy(request).etabs.add_etab(u(self.rne),u(self.libelle),u(self.adresse),u(self.ville),u(self.cp),u(self.telephone),u(self.fax), u(self.mail),u(self.responsable),u(self.remarques),u(self.type)))
                self.content = """
                <p><span id="message">L'établissement %s a bien été ajouté</span></p>
                <p><a href="/etab/get?rne=%s">Affichage du détail de l'établissement</a>
                </p>""" % (self.rne,self.rne)
            except xmlrpclib.ProtocolError:
                raise BackendError("""<p><span id="alerte">Vous n'êtes pas autorisé à effectuer cette action</span></p>""")
            except:
                raise BackendError

        except Exception as e :
            self.content = e

        return self.content


class RechEtab(Design):
    """Recherche d'un établissement, formulaire de saisie
    """
    isLeaf = True

    def getChild(self, name, request):
        if static.isDangerous(name):
            return static.dangerousPathError
        if name == b"rech" :
            return self
        return Etab()

    def wmfactory_title(self,request):
        return "Rechercher un établissement"

    def wmfactory_menu(self, request):
        return Navigation(aide="page4.html#section4").menu()

    def wmfactory_content(self, request):
        return self.content

    def _options(self,request):
        # récupération des types d'établissement existants
        dico = backend(proxy(request).etabs.get_types())[0]
        dico_inv = {}

        for clef, valeur in list(dico.items()):
            dico_inv[valeur] = clef

        l=[]
        liste = list(dico_inv.keys())
        liste.sort()
        for clef in liste:
            s = """<OPTION VALUE="%s">%s</OPTION>""" % (dico_inv[clef],clef)
            l.append(s)
        return "\n".join(l)

    def _options2(self,request):
        # récupération des types d'établissement existants
        listes = backend(proxy(request).etabs.get_libelle_etab())
        l=[]
        for libelle in listes[0]:
            s = """<OPTION VALUE="%s">%s</OPTION>""" % (libelle,libelle)
            l.append(s)
        l2=[]
        for ville in listes[1]:
            s = """<OPTION VALUE="%s">%s</OPTION>""" % (ville,ville)
            l2.append(s)

        return "\n".join(l),"\n".join(l2)

    def _dump_html(self, options,options2,options3) :
        """Formulaire d'édition de l'établissement
        """
        return """
<h1>Recherche d'un établissement</h1>
<FORM METHOD="POST" ACTION="aff">
<table cellpadding="5" cellspacing="0" align="center" valign="middle" width="80%%">
<tr><td colspan="2">%s</td></tr>
<tr><td>RNE</td><td><input type="text" size=30 name="rne" value=""/></td></tr>
<tr><td>Libellé de l'établissement</td><td><input type="text" size=50 name="libelle" value=""/></td></tr>
<tr><td>Ville</td><td><SELECT NAME="ville"><OPTION SELECTED="selected" VALUE=""></OPTION>%s</SELECT></td></tr>
<tr><td>Code postal</td><td><input type="text" size="5" name="cp" value=""/></td></tr>
<td>Type d'établissement</td><td>
<SELECT NAME="type"><OPTION SELECTED="selected" VALUE=""></OPTION>%s</SELECT></td></tr>
<tr><td align="right"><INPUT type=SUBMIT value="Ok"></td>
<td align="right"><input name="initialiser" value="Vider le formulaire" type="reset"/></td></tr>
<tr><td colspan="2" align="center"><a href="/etab">Retour à la page de gestion des établissements</a></td></tr>
</table></form><br/>
""" % (ilike_syntax, options3, options)

    def renderView(self, request):
        try:
            try:
                options2,options3 = self._options2(request)
                self.content = self._dump_html(self._options(request),options2,options3)
            except xmlrpclib.ProtocolError:
                raise BackendError("""Vous n'êtes pas autorisé à effectuer cette action""")
            except Exception as e:
                raise BackendError(e)

        except Exception as e :
            self.content = e

        return self.content


class AfficheEtab(Design):
    """affichage d'un établissement
    """

    isLeaf = True

    def getChild(self, name, request):
        if static.isDangerous(name):
            return static.dangerousPathError
        if name == b"aff" :
            return self
        return Etab()

    def wmfactory_title(self,request):
        return "(%s) Établissement - Résultats" % get_user(request)

    def wmfactory_content(self, request):
        return self.content

    def wmfactory_menu(self, request):
        return Navigation(aide="page4.html").menu()

    def _dump_html(self,liste_etab):
        """Mise en forme de la liste des résultats
        """
        sort_fields = ""
        for crit in ['rne', 'libelle', 'ville', 'cp', 'type']:
            sort_fields += """<td class="col"><table><tr><td>
            <a href="/etab/aff?sort_key=%s&reverse=1"><img border="0" src="/images/gnome_up.png" title="Tri décroissant"></a>
            </td><td><a href="/etab/aff?sort_key=%s"><img border="0" src="/images/gnome_down.png" title="Tri croissant"></a>
            </td><td>%s</td></tr></table></td>
            """ % (crit, crit, etabs_sort_keys[crit])

        s = """<h1>Liste des établissements sélectionnés</h1><br/>
        <table id="tab_etab" cellpadding="0" cellspacing="2"><tr>%s</tr>""" % sort_fields
        for etab in liste_etab :
            s += """<tr>
            <td><a href="get?rne=%(rne)s">%(rne)s</a></td>
            <td>%(libelle)s</td>
            <td>%(ville)s</td>
            <td>%(cp)s</td>
            <td>%(type)s</td>
            </tr>""" % etab

        s += """</table><p><a href="/etab">Retour à la page de gestion des établissements</a></p>"""
        return s

    def renderView(self, request):
        try:
            prefs = request.getSession()
            etabs = None
            sort_key = None
            reverse = False
            if b'sort_key' in request.args:
                sort_key = escape(request.args[b'sort_key'][0].decode())
            if b'reverse' in request.args and escape(brequest.args['reverse'][0].decode()) == "1":
                reverse = True
            try:
                d = {}
                d['rne'] = escape(request.args[b'rne'][0].decode())
                d['libelle'] = escape(request.args[b'libelle'][0].decode())
                d['ville'] = escape(request.args[b'ville'][0].decode()).upper()
                d['cp'] = escape(request.args[b'cp'][0].decode())
                d['type'] = escape(request.args[b'type'][0].decode())
                assert ''.join([str(crit) for crit in list(d.values())]) != ''
            except:
                # pas de critères : relecture de la liste en session
                if hasattr(prefs, 'liste_etabs'):
                    etabs = prefs.liste_etabs
                else:
                    raise FrontendError('critères de recherche')
            try:
                if etabs == None:
                    # récupération de la liste par xmlrpc
                    resultat = backend(proxy(request).etabs.rech_etab(u(d)))
                    if resultat == []:
                        self.content = """
                        <p>Aucun résultat ne correspond aux critères spécifiés<br/>
                        <a href="javascript:history.back()">Retour</a>
                        </p>
                        """
                        return self.content
                    else :
                        # dans le cas où il y a un seul etab, on redirige directement sur sa page
                        if len(resultat)==1:
                            self.content = """
                            <script language="javascript">
                            <!--

                            location.replace("get?rne=%s");

                            -->
                            </script>""" % resultat[0]['rne']
                            return self.content
                        else:
                            # sinon on affiche une liste
                            etabs = get_type(request,resultat)
                # tri de la liste suivant différents critères
                try:
                    if sort_key is not None and sort_key in etabs_sort_keys:
                        etabs.sort(key=lambda x:x[sort_key].lower(),reverse=reverse)
                except:
                    traceback.print_exc()

                prefs.liste_etabs = etabs
                # stockage de la liste dans la session
                self.content = self._dump_html(etabs)
            except xmlrpclib.ProtocolError:
                raise BackendError("""Vous n'êtes pas autorisé à effectuer cette action""")
            except Exception as e:
                traceback.print_exc()
                raise BackendError()

        except (FrontendError,BackendError) as e:
            self.content = e

        return self.content

class GetEtab(Design):
    """Listing des résultats établissements donnant le résultat de la recherche
    """

    isLeaf = True

    def getChild(self, name, request):
        if static.isDangerous(name):
            return static.dangerousPathError
        if name == b"get" :
            return self
        return Etab()

    def wmfactory_title(self,request):
        return "Liste des serveurs de l'établissement"

    def wmfactory_menu(self, request):
        return Navigation(aide="page4.html").menu()

    def wmfactory_content(self, request):
        return self.content

    def _dump_html(self,liste_etab):
        """Mise en forme de la liste des résultats
        """
        s = """<h1>Détails de l'établissement</h1><br>
        <table model="etab" view="List">"""
        for etab in liste_etab :
            s += """
            <tr><td>RNE</td><td>%(rne)s</td></tr>
            <tr><td>Libellé</td><td>%(libelle)s</td></tr>
            <tr><td>Ville</td><td>%(ville)s</td></tr>
            <tr><td>Adresse</td><td>%(adresse)s</td></tr>
            <tr><td>CP</td><td>%(cp)s</td></tr>
            <tr><td>Téléphone</td><td>%(tel)s</td></tr>
            <tr><td>Fax</td><td>%(fax)s</td></tr>
            <tr><td>Responsable</td><td>%(responsable)s</td></tr>
            <tr><td>Mail</td><td>%(mail)s</td></tr>
            <tr><td>Remarques</td><td>%(remarques)s</td></tr>
            <tr><td>Type</td><td>%(type)s</td></tr>
            """ % etab

        s += """</table>
        <p><a href="/etab/rapport?rne=%(rne)s">Générer un rapport <img src="/images/pdf.png"></a></p>
        <p><a href="edit?rne=%(rne)s">Modifier l'établissement</a> / <a href="del?rne=%(rne)s">Supprimer l'établissement</a></p>
        <p><a href="/etab">Retour à la gestion des établissements</a><br/><br/>
        """ % etab

        return s

    def _dump_serveurs(self,liste):
        """Affichage de la liste des serveurs pour un établissement
        """
        l = []
        l.append("""
            <a name="fin-liste"></a>
            <table cellpadding="1" cellspacing="2">
            <tr><td class="col">Identifiant</td><td class="col">Libellé</td><td class="col">Module</td></tr>
        """)
        for d in liste:
            l.append("""
            <tr><td align="center">%(id)s</td><td><a href="/serveur/etat?id=%(id)s">%(libelle)s</a></td><td>%(module_actuel)s</td></tr>
            """ % d)

        l.append("""</table>""")

        return "".join(l)

    def _get_module(self,serveur_list,mod_infos):
        """Filtre les clefs des modules
        """
        for serveur in serveur_list:
            if serveur['module_initial'] in mod_infos:
                serveur['module_initial'] = mod_infos[serveur['module_initial']][0]
            else:
                serveur['module_initial'] = "Module non autorisé"
            serveur['module_actuel'] = mod_infos[serveur['module_actuel']][0]

        return serveur_list

    def _get_variante(self,serveur,libelle):
        """Filtre les clefs des variantes
        """
        for s in serveur:
            s['variante'] = libelle[s['variante']]
        return serveur

    def renderView(self, request):
        rne = escape(request.args[b'rne'][0].decode())
        if (rne) :
            try:
                # récupération de l'étab
                etab = backend(proxy(request).etabs.get_etab(u(rne)))
                if etab == []:
                    self.content = """
                    <p>Aucun résultat ne correspond aux critères spécifiés<br/>
                    <a href="javascript:history.back()">Retour</a>
                    </p>
                    """
                else:
                    etab = get_type(request,etab)

                    liste = backend(proxy(request).serveurs.serveurs_etab(u(rne)))
                    liste = self._get_module(liste,self.get_module(proxy(request)))
                    liste = self._get_variante(liste,self.get_variante(proxy(request)))
                    if liste != [] :
                        self.content = """<h1>Liste des serveurs</h1>"""
                        self.content += self._dump_serveurs(liste)
                    else :
                        self.content = """
                        <p><span id="message">Aucun serveur accessible pour cet établissement</span></p>"""

                    self.content +="""<p><table border="0" cellspacing="5"><tr><td>
                        <FORM METHOD="POST" ACTION="/serveur/add">
                        <input type="hidden" name="rne" value="%s">
                        <input type="submit" value="Ajouter un serveur"></form></td><td>
                        <FORM METHOD="POST" ACTION="/serveur/aff_groupe">
                        <input type="hidden" name="rne" value="%s">
                        <input type="submit" value="Sélectionner comme groupe"></form></td></tr></table>
                        </p>
                        """ % (rne,rne)

                    self.content += self._dump_html(etab)

            except xmlrpclib.ProtocolError:
                self.content = """Vous n'êtes pas autorisé à effectuer cette action"""
            except BackendError:
                liste = sys.exc_info()
                self.content = """<p>Erreur lors de la recherche<br/>
            <a href="javascript:history.back()">Retour</a><br/>
            Détail de l'erreur :<br/> %s </p>
            """ % str(liste[1])
        else :
            self.content = """
        <p>vous n'avez pas renseigné de critère de recherche<br/>
        <a href="javascript:history.back()">Retour</a></p>
        """
        return self.content

class EditEtabDesc(Design):
    """Modification d'un établissement, formulaire de renseignements
    """
    isLeaf = True
    def getChild(self, name, request):
        if static.isDangerous(name):
            return static.dangerousPathError
        if name == b"edit" :
            return self
        return Etab()

    def wmfactory_title(self,request):
        return "Établissement (Modification)"

    def wmfactory_menu(self, request):
        return Navigation(aide="page4.html").menu()

    def wmfactory_content(self, request):
        return self.content

    def _options(self, selected,request):
        # récupération des types d'établissement existants
        l = []
        liste = backend(proxy(request).etabs.get_types())[0]
        for type_etab in list(liste.keys()):
            if str(selected) == type_etab:
                s = """<OPTION VALUE="%s" selected="selected">%s</OPTION>""" % (type_etab, liste[str(type_etab)])
            else:
                s = """<OPTION VALUE="%s">%s</OPTION>""" % (type_etab, liste[str(type_etab)])
            l.append(s)
        return "\n".join(l)


    def _dump_html(self,d) :
        """Formulaire édition
        """
        return """

<script LANGUAGE="JavaScript"><!--
function is_numeric(obj)
{
    var charpos = obj.value.search("[^0-9]");
    if(obj.value.length > 0 &&  charpos >= 0)
    {
        strError = obj.name+": valeur numérique";
        alert(strError);
        return false;
    }
    else
    {
        return true;
    }
}
function validfields(form)
{
    //getting the values:
    if (form.libelle.value.length > 200){
        alert("libelle : 200 caractères maximum !");
        form.libelle.focus();
        return false;
    }
    if (form.ville.value.length > 50){
        alert("ville : 50 caractères maximum !");
        form.ville.focus();
        return false;
    }
    if (form.adresse.value.length > 100){
        alert("adresse : 100 caractères maximum !");
        form.adresse.focus();
        return false;
    }
    if(!is_numeric(form.cp))
    {
        form.cp.focus();
        return false;
    }
    if (form.cp.value.length > 5){
        alert("code postal : 5 caractères maximum !");
        form.cp.focus();
        return false;
    }
    if (form.mail.value.length > 100){
        alert("mail : 100 caractères maximum !");
        form.mail.focus();
        return false;
    }
    if (form.tel.value.length > 20){
        alert("telephone : 20 caractères maximum !");
        form.tel.focus();
        return false;
    }
    if (form.fax.value.length > 20){
        alert("fax : 20 caractères maximum !");
        form.fax.focus();
        return false;
    }
    if (form.responsable.value.length > 30){
        alert("responsable : 30 caractères maximum !");
        form.responsable.focus();
        return false;
    }
    return true;
}
//--></script>

<h1>Modifiez les champs décrivant établissement</h1>
<FORM METHOD="POST" ACTION="edit2" onSubmit="return validfields(this)">
<table cellpadding="5" cellspacing="0" align="center" valign="middle" width="80%%">
<tr><td>RNE<input type="hidden" name="rne" value="%(rne)s"/></td><td>%(rne)s</td></tr>
<tr><td>Nom du site</td><td><input type="text" size=30 name="libelle" value="%(libelle)s"/></td></tr>
<tr><td>Adresse</td><td><textarea rows="2" cols="30" name="adresse">%(adresse)s</textarea></td></tr>
<tr><td>Ville</td><td><input type="text" size=30 name="ville" value="%(ville)s"/></td></tr>
<tr><td>Code postal</td><td><input type="text" size="5" name="cp" value="%(cp)s"/></td></tr>
<tr><td>Téléphone</td><td><input type="text" size="12" name="tel" value="%(tel)s"/></td></tr>
<tr><td>Fax</td><td><input type="text" size="12" name="fax" value="%(fax)s"/></td></tr>
<tr><td>Adresse électronique</td><td><input type="text" size="20" name="mail" value="%(mail)s"/></td></tr>
<tr><td>Responsable</td><td>
<input type="text" size="20" name="responsable" value="%(responsable)s"/></td></tr>
<tr><td>Remarques</td><td>
<textarea rows="3" cols="30" name="remarques">%(remarques)s</textarea></td></tr>
<tr><td>Type d'établissement</td><td>
<SELECT NAME="type">%(options)s</SELECT></td></tr>
<tr><td align="center"><INPUT type="SUBMIT" value="Ok"></td>
<td align="center"><input name="initialiser" value="Initialiser" type="reset"/></td>
</tr>
</table></form>""" % d

    def renderView(self, request):
        try:
            try:
                rne = escape(request.args[b'rne'][0].decode())
                assert rne
            except:
                raise FrontendError("identifiant")
            try:
                d = backend(proxy(request).etabs.get_etab(u(rne)))[0]
                d['options'] = self._options(d['type'],request)
                self.content = self._dump_html(d)
            except xmlrpclib.ProtocolError:
                raise BackendError("""Vous n'êtes pas autorisé à effectuer cette action""")

        except Exception as e:
            self.content = e

        return self.content

class EditEtabIns(Design):
    """Edition (modification) d'un établissement, update du backend
    """
    isLeaf = True

    def getChild(self, name, request):
        if static.isDangerous(name):
            return static.dangerousPathError
        if name == b"edit2" :
            return self
        return Etab()

    def wmfactory_title(self,request):
        return "(%s) Établissement (Édition)" % get_user(request)

    def wmfactory_content(self, request):
        return self.content


    def renderView(self, request):
        try:
            try:
                d = {}
                rne = escape(request.args[b'rne'][0].decode())
                d['libelle'] = escape(request.args[b'libelle'][0].decode())
                assert rne and d['libelle']

            except:
                raise FrontendError("identifiant ou libellé")

            for item in [b'adresse', b'ville', b'cp', b'tel', b'fax', b'mail', b'responsable', b'remarques', b'type']:
                if item not in request.args:
                    raise FrontendError(item.decode())
            d['adresse'] = escape(request.args[b'adresse'][0].decode())
            d['ville'] = escape(request.args[b'ville'][0].decode())
            d['cp'] = escape(request.args[b'cp'][0].decode())
            d['tel'] = escape(request.args[b'tel'][0].decode())
            d['fax'] = escape(request.args[b'fax'][0].decode())
            d['mail'] = escape(request.args[b'mail'][0].decode())
            d['responsable'] = escape(request.args[b'responsable'][0].decode())
            d['remarques'] = escape(request.args[b'remarques'][0].decode())
            d['type'] = escape(request.args[b'type'][0].decode())

            try:
                resultat = backend(proxy(request).etabs.edit_etab(u(rne),u(d)))
                self.content = """
                <p><span id="message">L'établissement %s a bien été modifié</span></p>
                <p><a href="/etab/get?rne=%s">Retour à l'affichage de l'établissement</a></p>
                """ % (rne,rne)
            except xmlrpclib.ProtocolError:
                raise BackendError("""Vous n'êtes pas autorisé à effectuer cette action""")
            except :
                raise BackendError

        except (FrontendError,BackendError) as e:
            self.content = e

        return self.content


class DelEtab(Design):
    """Demande de confirmation de suppression d'un établissement
    """
    isLeaf = True

    def getChild(self, name, request):
        if static.isDangerous(name):
            return static.dangerousPathError
        if name == b"del" :
            return self
        return Etab()

    def wmfactory_title(self,request):
        return "(%s) Étab (Suppression)" % get_user(request)

    def wmfactory_content(self, request):
        return self.content

    def renderView(self, request):
        try:
            try:
                rne = escape(request.args[b'rne'][0].decode())
                assert rne
            except:
                raise FrontendError("identifiant")

            self.content = """
            <p><span id="message">Voulez-vous réellement supprimer l'établissement %s ?</span></p>
            <p><a href="deleted?rne=%s">Supprimer</a></p>
            <p><a href="get?rne=%s">Retour aux détails de l'établissement</a></p>
            """ % (rne,rne,rne)

        except Exception as e:
            self.content = e

        return self.content

class DeletedEtab(Design):
    """Suppression effective d'un établissement
    """
    isLeaf = True

    def getChild(self, name, request):
        if static.isDangerous(name):
            return static.dangerousPathError
        if name == b"deleted" :
            return self
        return Etab()

    def wmfactory_title(self,request):
        return "(%s) Étab (Suppression)" % get_user(request)

    def wmfactory_content(self, request):
        return self.content

    def renderView(self, request):
        try:
            try:
                rne = escape(request.args[b'rne'][0].decode())
                assert rne
            except:
                raise FrontendError("identifiant")
            try:
                backend(proxy(request).etabs.del_etab(u(rne)))

                self.content = """
                <p>L'établissement a bien été supprimé</p>
                <p><a href="/etab">Retour à la gestion des établissements</a></p>
                """
            except DatabaseError as e:
                raise BackendError("Veuillez vérifier que l'établissement que vous essayez de supprimer n'est pas en cours d'utilisation <br/>")
            except xmlrpclib.ProtocolError:
                raise BackendError("""<p><span id="alerte">Vous n'êtes pas autorisé à effectuer cette action</span><p>""")

        except Exception as e:
            self.content = str(e)
            self.content += """<p><a href="/etab/get?rne=%s">Retour à l'affichage de l'établissement</a></p>""" % rne

        return self.content


class AddType(Design):
    """Ajout d'un type d'établissement
    """
    isLeaf = True
    def getChild(self, name, request):
        if static.isDangerous(name):
            return static.dangerousPathError
        if name == b"type" :
            return self
        return Etab()

    def wmfactory_title(self,request):
        return "Nouveau type d'établissement"

    def _options(self,request):
        # récupération des types d'établissement existants
        dico = backend(proxy(request).etabs.get_types())[0]
        l = []

        dico_inv = {}

        for clef, valeur in list(dico.items()):
            dico_inv[valeur] = clef

        liste = list(dico_inv.keys())
        liste.sort()

        for clef in liste:
            s = """<OPTION VALUE="%s">%s</OPTION>""" % (dico_inv[clef],clef)
            l.append(s)

        return "\n".join(l)

    def wmfactory_content(self, request):
        return self.content

    def renderView(self, request):
        try:
            if b'action' in request.args:
                if escape(request.args[b'action'][0].decode()) == 'delete':
                    type_to_del = int(escape(request.args[b'type'][0].decode()))
                    try:
                        backend(proxy(request).etabs.del_type(u(type_to_del)))
                    except DatabaseError as e:
                        raise BackendError("Erreur de supression du type %s <br/>" % type_to_del)
                    except xmlrpclib.ProtocolError:
                        raise BackendError("""Vous n'êtes pas autorisé à effectuer cette action""")

            self.content = """
<h1>Gestion des types d'établissement</h1>
<h2>Créer un nouveau type</h2>

<script LANGUAGE="JavaScript"><!--
function validfields4(form)
{
    //getting the values:
    if (form.type.value.length > 80){
        alert("type etablissement : 80 caractères maximum !");
        form.type.focus();
        return false;
    }
    else{
        return true;
    }
}
//--></script>



<FORM METHOD=POST ACTION="/etab/type2" onSubmit="return validfields4(this)">
            <table cellpadding="15" cellspacing="0" align="center" valign="middle" >
            <tr><td> Libellé :</td><td>
            <input type=text size=20 name="type" value=""><INPUT name="submit" type=SUBMIT value="Créer"></td></tr>
            </table>
            </form>
            <br/>
            <h2>Supprimer un type</h2>
            <FORM METHOD=POST ACTION="/etab/type">
            <input type="hidden" name="action" value="delete">
            <SELECT NAME="type"><OPTION SELECTED="selected" VALUE="0"></OPTION>""" + self._options(request) + """</SELECT>
            <INPUT name="submit" type=SUBMIT value="Supprimer">
            <br/><br/>
            <a href="/etab">Retour à la gestion des établissements</a>
            """

        except (FrontendError,BackendError) as e:
            self.content = e

        return self.content


class AddType2(Design):
    """Ajout d'un type d'établissement **page 2**
    """
    isLeaf = True

    def getChild(self, name, request):
        if static.isDangerous(name):
            return static.dangerousPathError
        if name == b"type2" :
            return self
        return Etab()

    def wmfactory_title(self,request):
        return "Ajout d'un nouveau type établissement"

    def wmfactory_content(self, request):
        return self.content

    def renderView(self, request):
        try:
            try:
                libelle = escape(request.args[b'type'][0].decode())
                assert libelle
            except:
                raise FrontendError('libelle')
            # insertion du type dans la base
            try:
                id = backend(proxy(request).etabs.add_type(u(libelle)))
                self.content = """<p><span id="message">Le nouveau type à bien été ajouté</span></p>
                <p><a href="/etab/type">Retour à la page de gestion des types d'établissement</a></p>"""

            except xmlrpclib.ProtocolError:
                raise BackendError("""Vous n'êtes pas autorisé à effectuer cette action""")
            except :
                raise BackendError

        except (FrontendError,BackendError) as e:
            self.content = e

        return self.content


