# -*- mode: python -*- # -*- coding: utf-8 -*- ############################################################################## # # Gestion scolarite IUT # # Copyright (c) 1999 - 2021 Emmanuel Viennet. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Emmanuel Viennet emmanuel.viennet@viennet.net # ############################################################################## """Recherche d'étudiants """ from types import ListType import xml.dom.minidom import sco_utils as scu import notesdb as ndb from notes_log import log from gen_tables import GenTable import scolars import sco_formsemestre import sco_groups from sco_permissions import ScoView def form_search_etud( context, REQUEST=None, dest_url=None, parameters=None, parameters_keys=None, title="Rechercher un étudiant par nom : ", add_headers=False, # complete page ): "form recherche par nom" H = [] if title: H.append("

%s

" % title) H.append( """
%s
(entrer une partie du nom) """ % title ) if dest_url: H.append('' % dest_url) if parameters: for param in parameters.keys(): H.append( '' % (param, parameters[param]) ) H.append( '' % (",".join(parameters.keys())) ) elif parameters_keys: for key in parameters_keys.split(","): v = REQUEST.form.get(key, False) if v: H.append('' % (key, v)) H.append( '' % parameters_keys ) H.append("
") if add_headers: return ( context.sco_header(REQUEST, page_title="Choix d'un étudiant") + "\n".join(H) + context.sco_footer(REQUEST) ) else: return "\n".join(H) def search_etud_in_dept(context, expnom="", REQUEST=None): """Page recherche d'un etudiant. Affiche la fiche de l'étudiant, ou, si la recherche donne plusieurs résultats, la liste des étudianst correspondants. Appelée par boite de recherche barre latérale gauche. Args: expnom: string, regexp sur le nom ou un code_nip ou un etudid """ dest_url = "ficheEtud" if len(expnom) > 1: etuds = context.getEtudInfo(filled=1, etudid=expnom, REQUEST=REQUEST) if len(etuds) != 1: if scu.is_valid_code_nip(expnom): etuds = search_etuds_infos(context, code_nip=expnom, REQUEST=REQUEST) else: etuds = search_etuds_infos(context, expnom=expnom, REQUEST=REQUEST) else: etuds = [] # si expnom est trop court, n'affiche rien if len(etuds) == 1: # va directement a la destination return context.ficheEtud(etudid=etuds[0]["etudid"], REQUEST=REQUEST) H = [ context.sco_header( page_title="Recherche d'un étudiant", no_side_bar=True, init_qtip=True, javascripts=["js/etud_info.js"], REQUEST=REQUEST, ), """

%d résultats pour "%s": choisissez un étudiant:

""" % (len(etuds), expnom), form_search_etud( context, dest_url=dest_url, REQUEST=REQUEST, title="Autre recherche", ), ] if len(etuds) > 0: # Choix dans la liste des résultats: for e in etuds: target = dest_url + "?etudid=%s&" % e["etudid"] e["_nomprenom_target"] = target e["inscription_target"] = target e["_nomprenom_td_attrs"] = 'id="%s" class="etudinfo"' % (e["etudid"]) sco_groups.etud_add_group_infos(context, e, e["cursem"]) tab = GenTable( columns_ids=("nomprenom", "code_nip", "inscription", "groupes"), titles={ "nomprenom": "Etudiant", "code_nip": "NIP", "inscription": "Inscription", "groupes": "Groupes", }, rows=etuds, html_sortable=True, html_class="table_leftalign", preferences=context.get_preferences(), ) H.append(tab.html()) if len(etuds) > 20: # si la page est grande H.append( form_search_etud( context, dest_url=dest_url, REQUEST=REQUEST, title="Autre recherche", ) ) else: H.append('

Aucun résultat pour "%s".

' % expnom) H.append( """

La recherche porte sur tout ou partie du NOM ou du NIP de l'étudiant

""" ) return "\n".join(H) + context.sco_footer(REQUEST) # Was chercheEtudsInfo() def search_etuds_infos(context, expnom=None, code_nip=None, REQUEST=None): """recherche les étudiants correspondants à expnom ou au code_nip et ramene liste de mappings utilisables en DTML. """ may_be_nip = scu.is_valid_code_nip(expnom) cnx = context.GetDBConnexion() if expnom and not may_be_nip: expnom = scu.strupper(expnom) # les noms dans la BD sont en uppercase etuds = scolars.etudident_list(cnx, args={"nom": expnom}, test="~") else: code_nip = code_nip or expnom if code_nip: etuds = scolars.etudident_list(cnx, args={"code_nip": code_nip}) else: etuds = [] context.fillEtudsInfo(etuds) return etuds def search_etud_by_name(context, term, REQUEST=None): """Recherche noms étudiants par début du nom, pour autocomplete Accepte aussi un début de code NIP (au moins 6 caractères) Renvoie une liste de nom en JSON """ may_be_nip = scu.is_valid_code_nip(term) # term = scu.strupper(term) # conserve les accents term = term.upper() if ( not scu.ALPHANUM_EXP.match( term.decode(scu.SCO_ENCODING) ) # n'autorise pas les caractères spéciaux and not may_be_nip ): data = [] else: if may_be_nip: r = ndb.SimpleDictFetch( context, "SELECT nom, prenom, code_nip FROM identite WHERE code_nip LIKE %(beginning)s ORDER BY nom", {"beginning": term + "%"}, ) data = [ { "label": "%s %s %s" % (x["code_nip"], x["nom"], scolars.format_prenom(x["prenom"])), "value": x["code_nip"], } for x in r ] else: r = ndb.SimpleDictFetch( context, "SELECT etudid, nom, prenom FROM identite WHERE nom LIKE %(beginning)s ORDER BY nom", {"beginning": term + "%"}, ) data = [ { "label": "%s %s" % (x["nom"], scolars.format_prenom(x["prenom"])), "value": x["etudid"], } for x in r ] # log(data) return scu.sendJSON(REQUEST, data) # ---------- Recherche sur plusieurs département def form_search_etud_in_accessible_depts(context, REQUEST): """Form recherche etudiants pour page accueil ScoDoc""" authuser = REQUEST.AUTHENTICATED_USER # present form only to authenticated users if not authuser.has_role("Authenticated"): return "" return """
Chercher étudiant:
(entrer une partie du nom ou le code NIP, cherche dans tous les départements autorisés) """ def can_view_dept(context, REQUEST): """True if auth user can access (View) this context""" authuser = REQUEST.AUTHENTICATED_USER return authuser.has_permission(ScoView, context) def search_etud_in_accessible_depts(context, expnom=None, code_nip=None, REQUEST=None): """ context est le ZScoDoc result is a list of (sorted) etuds, one list per dept. """ result = [] accessible_depts = [] deptList = context._list_depts() # definis dans Zope for dept in deptList: # log('%s searching %s' % (str(REQUEST.AUTHENTICATED_USER),dept)) if can_view_dept(dept, REQUEST): if expnom or code_nip: accessible_depts.append(dept.Scolarite.DeptId()) etuds = search_etuds_infos( dept.Scolarite, expnom=expnom, code_nip=code_nip, REQUEST=REQUEST ) else: etuds = [] result.append(etuds) return result, accessible_depts def table_etud_in_accessible_depts(context, expnom=None, REQUEST=None): """ Page avec table étudiants trouvés, dans tous les departements. Attention: nous sommes ici au niveau de ScoDoc, pas dans un département """ result, accessible_depts = search_etud_in_accessible_depts( context, expnom=expnom, REQUEST=REQUEST ) H = [ """
""", """

Recherche multi-département de "%s"

""" % expnom, ] for etuds in result: if etuds: DeptId = etuds[0]["dept"] # H.append('

Département %s

' % DeptId) dest_url = DeptId + "/Scolarite/ficheEtud" for e in etuds: target = dest_url + "?etudid=%s" % e["etudid"] e["_nomprenom_target"] = target e["_nomprenom_td_attrs"] = 'id="%s" class="etudinfo"' % (e["etudid"]) tab = GenTable( titles={"nomprenom": "Etudiants en " + DeptId}, columns_ids=("nomprenom",), rows=etuds, html_sortable=True, html_class="table_leftalign", ) H.append('
') H.append(tab.html()) H.append("
") if len(accessible_depts) > 1: ss = "s" else: ss = "" H.append( """

(recherche menée dans le%s département%s: %s)

Retour à l'accueil

""" % (ss, ss, ", ".join(accessible_depts)) ) H.append("
") return ( context.scodoc_top_html_header(REQUEST, page_title="Choix d'un étudiant") + "\n".join(H) + context.standard_html_footer(REQUEST) ) def search_inscr_etud_by_nip(context, code_nip, REQUEST=None, format="json"): """Recherche multi-departement d'un étudiant par son code NIP Seuls les départements accessibles par l'utilisateur sont cherchés. Renvoie une liste des inscriptions de l'étudiants dans tout ScoDoc: code_nip, nom, prenom, civilite_str, dept, formsemestre_id, date_debut_sem, date_fin_sem """ result, _ = search_etud_in_accessible_depts( context, code_nip=code_nip, REQUEST=REQUEST ) T = [] for etuds in result: if etuds: DeptId = etuds[0]["dept"] for e in etuds: for sem in e["sems"]: T.append( { "dept": DeptId, "etudid": e["etudid"], "code_nip": e["code_nip"], "civilite_str": e["civilite_str"], "nom": e["nom"], "prenom": e["prenom"], "formsemestre_id": sem["formsemestre_id"], "date_debut_iso": sem["date_debut_iso"], "date_fin_iso": sem["date_fin_iso"], } ) columns_ids = ( "dept", "etudid", "code_nip", "civilite_str", "nom", "prenom", "formsemestre_id", "date_debut_iso", "date_fin_iso", ) tab = GenTable(columns_ids=columns_ids, rows=T) return tab.make_page( context, format=format, with_html_headers=False, REQUEST=REQUEST, publish=True )