From d6b6ab3ea7d0c23f4837ce4650ddbeaf233cab0f Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Fri, 15 Jan 2021 23:08:27 +0100 Subject: [PATCH 1/3] Port all Entreprise DTML methods to Python --- ZEntreprises.py | 921 ++++++++++++++++++++++++++++++++++++++---- notesdb.py | 24 +- static/css/scodoc.css | 20 + 3 files changed, 885 insertions(+), 80 deletions(-) diff --git a/ZEntreprises.py b/ZEntreprises.py index 3f13897788..5eb610aaf4 100644 --- a/ZEntreprises.py +++ b/ZEntreprises.py @@ -26,23 +26,33 @@ ############################################################################## """ Gestion des relations avec les entreprises + +Note: Code très ancien, porté de Zope/DTML, peu utilisable + +=> Voir si des départements utilisent encore ce module et envisager de le supprimer. + """ import urllib +import string +import re +import time +import calendar from sco_zope import * +from sco_permissions import ScoEntrepriseView, ScoEntrepriseChange # --------------- from notesdb import * from notes_log import log from scolog import logdb -from sco_utils import * +from sco_utils import SCO_ENCODING +import sco_utils as scu import html_sidebar - +import VERSION +from gen_tables import GenTable from TrivialFormulator import TrivialFormulator, TF import scolars -import string, re -import time, calendar def _format_nom(nom): @@ -78,10 +88,19 @@ class EntreprisesEditor(EditableTable): sortkey=None, sort_on_contact=False, ZEntrepriseInstance=None, + limit="", + offset="", ): # list, then sort on date of last contact R = EditableTable.list( - self, cnx, args=args, operator=operator, test=test, sortkey=sortkey + self, + cnx, + args=args, + operator=operator, + test=test, + sortkey=sortkey, + limit=limit, + offset=offset, ) if sort_on_contact: for r in R: @@ -323,7 +342,7 @@ class ZEntreprises( H.append("") # - H.append("""

%s""" % icontag("entreprise_side_img")) + H.append("""

%s""" % scu.icontag("entreprise_side_img")) if REQUEST["_read_only"]: H.append("""
(Lecture seule)""") H.append(""" """) @@ -331,55 +350,835 @@ class ZEntreprises( # -------------------------------------------------------------------- # - # Entreprises : Methodes en DTML + # Entreprises : Vues # # -------------------------------------------------------------------- - # used to view content of the object security.declareProtected(ScoEntrepriseView, "index_html") - index_html = DTMLFile("dtml/entreprises/index_html", globals()) + + def index_html( + self, REQUEST=None, etud_nom=None, limit=50, offset="", format="html" + ): + """Accueil module entreprises""" + # Traduit du DTML - utilise table standard + if limit: + limit = int(limit) + if offset: + offset = int(offset or 0) + + if etud_nom: + entreprises = self.do_entreprise_list_by_etud( + args=REQUEST.form, sort_on_contact=True + ) + table_navigation = "" + else: + entreprises = self.do_entreprise_list( + args=REQUEST.form, + test="~*", + sort_on_contact=True, + limit=limit, + offset=offset, + ) + # Liens navigation précédent/suivant + webparams = {"limit": limit} + if offset: + webparams["offset"] = max((offset or 0) - limit, 0) + prev_lnk = 'précédentes' % ( + REQUEST.URL0 + "?" + urllib.urlencode(webparams) + ) + else: + prev_lnk = "" + if len(entreprises) >= limit: + webparams["offset"] = (offset or 0) + limit + next_lnk = 'suivantes' % ( + REQUEST.URL0 + "?" + urllib.urlencode(webparams) + ) + else: + next_lnk = "" + table_navigation = ( + '
' + + prev_lnk + + '' + + next_lnk + + "
" + ) + # Ajout des liens sur la table: + for e in entreprises: + e["_nom_target"] = "entreprise_edit?entreprise_id=%(entreprise_id)s" % e + e["correspondants"] = self.do_entreprise_correspondant_list( + args={"entreprise_id": e["entreprise_id"]} + ) + e["nbcorr"] = "%d corr." % len(e["correspondants"]) + e["_nbcorr_target"] = ( + "entreprise_correspondant_list?entreprise_id=%(entreprise_id)s" % e + ) + e["contacts"] = self.do_entreprise_contact_list( + args={"entreprise_id": e["entreprise_id"]} + ) + e["nbcontact"] = "%d contacts." % len(e["contacts"]) + e["_nbcontact_target"] = ( + "entreprise_contact_list?entreprise_id=%(entreprise_id)s" % e + ) + tab = GenTable( + rows=entreprises, + columns_ids=("nom", "ville", "secteur", "nbcorr", "nbcontact"), + titles={ + "nom": "Entreprise", + "ville": "Ville", + "secteur": "Secteur", + "nbcorr": "Corresp.", + "contacts": "Contacts", + }, + origin="Généré par %s le " % VERSION.SCONAME + scu.timedate_human_repr(), + filename=scu.make_filename( + "entreprises_%s" % self.get_preference("DeptName") + ), + caption="Entreprises du département %s" % self.get_preference("DeptName"), + html_sortable=True, + html_class="entreprise_list table_leftalign", + html_with_td_classes=True, + html_next_section=table_navigation, + base_url=REQUEST.URL0 + "?", + preferences=self.get_preferences(), + ) + if format != "html": + return tab.make_page(self, format=format, REQUEST=REQUEST) + else: + H = [ + self.entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"), + """

Suivi relations entreprises

""", + """
""", + tab.html(), + """
""", + self.entreprise_footer(REQUEST), + ] + return "\n".join(H) security.declareProtected(ScoEntrepriseView, "entreprise_contact_list") - entreprise_contact_list = DTMLFile( - "dtml/entreprises/entreprise_contact_list", globals() - ) - security.declareProtected(ScoEntrepriseView, "entreprise_correspondant_list") - entreprise_correspondant_list = DTMLFile( - "dtml/entreprises/entreprise_correspondant_list", globals() - ) - # les methodes "edit" sont aussi en ScoEntrepriseView car elles permettent - # la visualisation (via variable _read_only positionnee dans entreprise_header) - security.declareProtected(ScoEntrepriseView, "entreprise_contact_edit") - entreprise_contact_edit = DTMLFile( - "dtml/entreprises/entreprise_contact_edit", globals() - ) - security.declareProtected(ScoEntrepriseView, "entreprise_correspondant_edit") - entreprise_correspondant_edit = DTMLFile( - "dtml/entreprises/entreprise_correspondant_edit", globals() - ) - # Acces en modification: + def entreprise_contact_list(self, entreprise_id=None, format="html", REQUEST=None): + """Liste des contacts de l'entreprise""" + H = [self.entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises")] + if entreprise_id: + E = self.do_entreprise_list(args={"entreprise_id": entreprise_id})[0] + C = self.do_entreprise_contact_list(args={"entreprise_id": entreprise_id}) + H.append( + """

Listes des contacts avec l'entreprise %(nom)s

+ """ + % E + ) + else: + C = self.do_entreprise_contact_list(args={}) + H.append( + """

Listes des contacts

+ """ + ) + for c in C: + c[ + "_date_target" + ] = "%s/entreprise_contact_edit?entreprise_contact_id=%s" % ( + REQUEST.URL1, + c["entreprise_contact_id"], + ) + c["entreprise"] = self.do_entreprise_list( + args={"entreprise_id": c["entreprise_id"]} + )[0] + if c["etudid"]: + c["etud"] = self.getEtudInfo(etudid=c["etudid"], filled=1)[0] + c["etudnom"] = c["etud"]["nomprenom"] + c["_etudnom_target"] = "%s/ficheEtud?etudid=%s" % ( + REQUEST.URL1, + c["etudid"], + ) + else: + c["etud"] = None + c["etudnom"] = "" + + tab = GenTable( + rows=C, + columns_ids=("date", "type_contact", "etudnom", "description"), + titles={ + "date": "Date", + "type_contact": "Object", + "etudnom": "Étudiant", + "description": "Description", + }, + origin="Généré par %s le " % VERSION.SCONAME + scu.timedate_human_repr(), + filename=scu.make_filename("contacts_%s" % self.get_preference("DeptName")), + caption="", + html_sortable=True, + html_class="contact_list table_leftalign", + html_with_td_classes=True, + base_url=REQUEST.URL0 + "?", + preferences=self.get_preferences(), + ) + if format != "html": + return tab.make_page(self, format=format, REQUEST=REQUEST) + + H.append(tab.html()) + + if not REQUEST["_read_only"]: # portage DTML, à modifier + if entreprise_id: + H.append( + """

nouveau "contact"

+ """ + % E + ) + + H.append(self.entreprise_footer(REQUEST)) + return "\n".join(H) + + security.declareProtected(ScoEntrepriseView, "entreprise_correspondant_list") + + def entreprise_correspondant_list( + self, + entreprise_id=None, + format="html", + REQUEST=None, + ): + """Liste des correspondants de l'entreprise""" + E = self.do_entreprise_list(args={"entreprise_id": entreprise_id})[0] + H = [ + self.entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"), + """ +

Listes des correspondants dans l'entreprise %(nom)s

+ """ + % E, + ] + correspondants = self.do_entreprise_correspondant_list( + args={"entreprise_id": entreprise_id} + ) + for c in correspondants: + c["nomprenom"] = c["nom"].upper() + " " + c["nom"].capitalize() + c["_nomprenom_target"] = ( + "%s/entreprise_correspondant_edit?entreprise_corresp_id=%s" + % (REQUEST.URL1, c["entreprise_corresp_id"]), + ) + c["nom_entreprise"] = E["nom"] + l = [] + if c["phone1"]: + l.append(c["phone1"]) + if c["phone2"]: + l.append(c["phone2"]) + if c["mobile"]: + l.append(c["mobile"]) + c["telephones"] = " / ".join(l) + c["mails"] = " ".join( + [ + '%s' % (c["mail1"], c["mail1"]) + if c["mail1"] + else "", + '%s' % (c["mail2"], c["mail2"]) + if c["mail2"] + else "", + ] + ) + c["modifier"] = ( + 'modifier' + % c["entreprise_corresp_id"] + ) + c["supprimer"] = ( + 'supprimer' + % c["entreprise_corresp_id"] + ) + tab = GenTable( + rows=correspondants, + columns_ids=( + "nomprenom", + "nom_entreprise", + "fonction", + "telephones", + "mails", + "note", + "modifier", + "supprimer", + ), + titles={ + "nomprenom": "Nom", + "nom_entreprise": "Entreprise", + "fonction": "Fonction", + "telephones": "Téléphone", + "mails": "Mail", + "note": "Note", + "modifier": "", + "supprimer": "", + }, + origin="Généré par %s le " % VERSION.SCONAME + scu.timedate_human_repr(), + filename=scu.make_filename( + "correspondants_%s_%s" % (E["nom"], self.get_preference("DeptName")) + ), + caption="", + html_sortable=True, + html_class="contact_list table_leftalign", + html_with_td_classes=True, + base_url=REQUEST.URL0 + "?", + preferences=self.get_preferences(), + ) + if format != "html": + return tab.make_page(self, format=format, REQUEST=REQUEST) + + H.append(tab.html()) + + if not REQUEST["_read_only"]: # portage DTML, à modifier + H.append( + """

Ajouter un correspondant dans l'entreprise %(nom)s

+ """ + % E + ) + + H.append(self.entreprise_footer(REQUEST)) + return "\n".join(H) + + security.declareProtected(ScoEntrepriseView, "entreprise_contact_edit") + + def entreprise_contact_edit(self, entreprise_contact_id, REQUEST=None): + """Form edit contact""" + c = self.do_entreprise_contact_list( + args={"entreprise_contact_id": entreprise_contact_id} + )[0] + link_create_corr = ( + 'créer un nouveau correspondant' + % (REQUEST.URL1, c["entreprise_id"]) + ) + E = self.do_entreprise_list(args={"entreprise_id": c["entreprise_id"]})[0] + correspondants = self.do_entreprise_correspondant_listnames( + args={"entreprise_id": c["entreprise_id"]} + ) + [("inconnu", "")] + + H = [ + self.entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"), + """

Suivi entreprises

+

Contact avec entreprise %(nom)s

""" + % E, + ] + tf = TrivialFormulator( + REQUEST.URL0, + REQUEST.form, + ( + ( + "entreprise_contact_id", + {"default": entreprise_contact_id, "input_type": "hidden"}, + ), + ( + "entreprise_id", + {"input_type": "hidden", "default": c["entreprise_id"]}, + ), + ( + "type_contact", + { + "input_type": "menu", + "title": "Objet", + "allowed_values": ( + "Prospection", + "Stage étudiant", + "Contrat Apprentissage", + "Projet", + "Autre", + ), + }, + ), + ( + "date", + { + "size": 12, + "title": "Date du contact (j/m/a)", + "allow_null": False, + }, + ), + ( + "entreprise_corresp_id", + { + "input_type": "menu", + "title": "Correspondant entreprise", + "explanation": link_create_corr, + "allow_null": True, + "labels": [x[0] for x in correspondants], + "allowed_values": [x[1] for x in correspondants], + }, + ), + ( + "etudiant", + { + "size": 16, + "title": "Etudiant concerné", + "allow_null": True, + "default": c["etudid"], + "explanation": "nom (si pas ambigu) ou code", + }, + ), + ( + "enseignant", + {"size": 16, "title": "Enseignant (tuteur)", "allow_null": True}, + ), + ( + "description", + { + "input_type": "textarea", + "rows": 3, + "cols": 40, + "title": "Description", + }, + ), + ), + cancelbutton="Annuler", + initvalues=c, + submitlabel="Modifier les valeurs", + readonly=REQUEST["_read_only"], + ) + + if tf[0] == 0: + H.append(tf[1]) + if not REQUEST["_read_only"]: # portage DTML, à modifier + H.append( + """

Supprimer ce contact

""" + % entreprise_contact_id + ) + elif tf[0] == -1: + REQUEST.RESPONSE.redirect(REQUEST.URL1) + else: + etudok = self.do_entreprise_check_etudiant(tf[2]["etudiant"]) + if etudok[0] == 0: + H.append("""

%s

""" % etudok[1]) + else: + tf[2].update({"etudid": etudok[1]}) + self.do_entreprise_contact_edit(tf[2]) + REQUEST.RESPONSE.redirect( + REQUEST.URL1 + + "/entreprise_contact_list?entreprise_id=" + + str(c["entreprise_id"]) + ) + H.append(self.entreprise_footer(REQUEST)) + return "\n".join(H) + + security.declareProtected(ScoEntrepriseView, "entreprise_correspondant_edit") + + def entreprise_correspondant_edit(self, entreprise_corresp_id, REQUEST=None): + """Form édition d'un correspondant""" + # F -> c + c = self.do_entreprise_correspondant_list( + args={"entreprise_corresp_id": entreprise_corresp_id} + )[0] + H = [ + self.entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"), + """

Édition contact entreprise

""", + ] + tf = TrivialFormulator( + REQUEST.URL0, + REQUEST.form, + ( + ( + "entreprise_corresp_id", + {"default": entreprise_corresp_id, "input_type": "hidden"}, + ), + ( + "civilite", + { + "input_type": "menu", + "labels": ["M.", "Mme"], + "allowed_values": ["M.", "Mme"], + }, + ), + ("nom", {"size": 25, "title": "Nom", "allow_null": False}), + ("prenom", {"size": 25, "title": "Prénom"}), + ( + "fonction", + { + "input_type": "menu", + "allowed_values": ( + "Directeur", + "RH", + "Resp. Administratif", + "Tuteur", + "Autre", + ), + "explanation": "fonction via à vis de l'IUT", + }, + ), + ( + "phone1", + { + "size": 14, + "title": "Téléphone 1", + }, + ), + ( + "phone2", + { + "size": 14, + "title": "Téléphone 2", + }, + ), + ( + "mobile", + { + "size": 14, + "title": "Tél. mobile", + }, + ), + ( + "fax", + { + "size": 14, + "title": "Fax", + }, + ), + ( + "mail1", + { + "size": 25, + "title": "e-mail", + }, + ), + ( + "mail2", + { + "size": 25, + "title": "e-mail 2", + }, + ), + ( + "note", + {"input_type": "textarea", "rows": 3, "cols": 40, "title": "Note"}, + ), + ), + cancelbutton="Annuler", + initvalues=c, + submitlabel="Modifier les valeurs", + readonly=REQUEST["_read_only"], + ) + if tf[0] == 0: + H.append(tf[1]) + elif tf[0] == -1: + REQUEST.RESPONSE.redirect( + "%s/entreprise_correspondant_list?entreprise_id=%s" + % (REQUEST.URL1, c["entreprise_id"]) + ) + else: + self.do_entreprise_correspondant_edit(tf[2]) + REQUEST.RESPONSE.redirect( + "%s/entreprise_correspondant_list?entreprise_id=%s" + % (REQUEST.URL1, c["entreprise_id"]) + ) + H.append(self.entreprise_footer(REQUEST)) + return "\n".join(H) + security.declareProtected(ScoEntrepriseChange, "entreprise_contact_create") - entreprise_contact_create = DTMLFile( - "dtml/entreprises/entreprise_contact_create", globals() - ) + + def entreprise_contact_create(self, entreprise_id, REQUEST=None): + """Form création contact""" + E = self.do_entreprise_list(args={"entreprise_id": entreprise_id})[0] + correspondants = self.do_entreprise_correspondant_listnames( + args={"entreprise_id": entreprise_id} + ) + if not correspondants: + correspondants = [("inconnu", "")] + curtime = time.strftime("%d/%m/%Y") + link_create_corr = ( + 'créer un nouveau correspondant' + % (REQUEST.URL1, entreprise_id) + ) + H = [ + self.entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"), + """

Nouveau "contact" avec l'entreprise %(nom)s

""" + % E, + ] + tf = TrivialFormulator( + REQUEST.URL0, + REQUEST.form, + ( + ("entreprise_id", {"input_type": "hidden", "default": entreprise_id}), + ( + "type_contact", + { + "input_type": "menu", + "title": "Objet", + "allowed_values": ( + "Prospection", + "Stage étudiant", + "Contrat Apprentissage DUT GTR1", + "Contrat Apprentissage DUT GTR2", + "Contrat Apprentissage Licence SQRT", + "Projet", + "Autre", + ), + "default": "Stage étudiant", + }, + ), + ( + "date", + { + "size": 12, + "title": "Date du contact (j/m/a)", + "allow_null": False, + "default": curtime, + }, + ), + ( + "entreprise_corresp_id", + { + "input_type": "menu", + "title": "Correspondant entreprise", + "explanation": link_create_corr, + "allow_null": True, + "labels": [x[0] for x in correspondants], + "allowed_values": [x[1] for x in correspondants], + }, + ), + ( + "etudiant", + { + "size": 16, + "title": "Etudiant concerné", + "allow_null": True, + "explanation": "nom (si pas ambigu) ou code", + }, + ), + ( + "enseignant", + {"size": 16, "title": "Enseignant (tuteur)", "allow_null": True}, + ), + ( + "description", + { + "input_type": "textarea", + "rows": 3, + "cols": 40, + "title": "Description", + }, + ), + ), + cancelbutton="Annuler", + submitlabel="Ajouter ce contact", + readonly=REQUEST["_read_only"], + ) + if tf[0] == 0: + H.append(tf[1]) + elif tf[0] == -1: + REQUEST.RESPONSE.redirect(REQUEST.URL1) + else: + etudok = self.do_entreprise_check_etudiant(tf[2]["etudiant"]) + if etudok[0] == 0: + H.append("""

%s

""" % etudok[1]) + else: + tf[2].update({"etudid": etudok[1]}) + self.do_entreprise_contact_create(tf[2]) + REQUEST.RESPONSE.redirect(REQUEST.URL1) + H.append(self.entreprise_footer(REQUEST)) + return "\n".join(H) + security.declareProtected(ScoEntrepriseChange, "entreprise_contact_delete") - entreprise_contact_delete = DTMLFile( - "dtml/entreprises/entreprise_contact_delete", globals() - ) + + def entreprise_contact_delete(self, entreprise_contact_id, REQUEST=None): + """Form delete contact""" + c = self.do_entreprise_contact_list( + args={"entreprise_contact_id": entreprise_contact_id} + )[0] + H = [ + self.entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"), + """

Suppression du contact

""", + ] + tf = TrivialFormulator( + REQUEST.URL0, + REQUEST.form, + (("entreprise_contact_id", {"input_type": "hidden"}),), + initvalues=c, + submitlabel="Confirmer la suppression", + cancelbutton="Annuler", + readonly=REQUEST["_read_only"], + ) + if tf[0] == 0: + H.append(tf[1]) + elif tf[0] == -1: + REQUEST.RESPONSE.redirect(REQUEST.URL1) + else: + self.do_entreprise_contact_delete(c["entreprise_contact_id"]) + REQUEST.RESPONSE.redirect(REQUEST.URL1) + H.append(self.entreprise_footer(REQUEST)) + return "\n".join(H) + security.declareProtected(ScoEntrepriseChange, "entreprise_correspondant_create") - entreprise_correspondant_create = DTMLFile( - "dtml/entreprises/entreprise_correspondant_create", globals() - ) + + def entreprise_correspondant_create(self, entreprise_id, REQUEST=None): + """Form création correspondant""" + E = self.do_entreprise_list(args={"entreprise_id": entreprise_id})[0] + H = [ + self.entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"), + """

Nouveau correspondant l'entreprise %(nom)s

""" + % E, + ] + tf = TrivialFormulator( + REQUEST.URL0, + REQUEST.form, + ( + ("entreprise_id", {"input_type": "hidden", "default": entreprise_id}), + ( + "civilite", + { + "input_type": "menu", + "labels": ["M.", "Mme"], + "allowed_values": ["M.", "Mme"], + }, + ), + ("nom", {"size": 25, "title": "Nom", "allow_null": False}), + ("prenom", {"size": 25, "title": "Prénom"}), + ( + "fonction", + { + "input_type": "menu", + "allowed_values": ( + "Directeur", + "RH", + "Resp. Administratif", + "Tuteur", + "Autre", + ), + "default": "Tuteur", + "explanation": "fonction via à vis de l'IUT", + }, + ), + ( + "phone1", + { + "size": 14, + "title": "Téléphone 1", + }, + ), + ( + "phone2", + { + "size": 14, + "title": "Téléphone 2", + }, + ), + ( + "mobile", + { + "size": 14, + "title": "Tél. mobile", + }, + ), + ( + "fax", + { + "size": 14, + "title": "Fax", + }, + ), + ( + "mail1", + { + "size": 25, + "title": "e-mail", + }, + ), + ( + "mail2", + { + "size": 25, + "title": "e-mail 2", + }, + ), + ( + "note", + {"input_type": "textarea", "rows": 3, "cols": 40, "title": "Note"}, + ), + ), + cancelbutton="Annuler", + submitlabel="Ajouter ce correspondant", + readonly=REQUEST["_read_only"], + ) + if tf[0] == 0: + H.append(tf[1]) + elif tf[0] == -1: + REQUEST.RESPONSE.redirect(REQUEST.URL1) + else: + self.do_entreprise_correspondant_create(tf[2]) + REQUEST.RESPONSE.redirect(REQUEST.URL1) + H.append(self.entreprise_footer(REQUEST)) + return "\n".join(H) + security.declareProtected(ScoEntrepriseChange, "entreprise_correspondant_delete") - entreprise_correspondant_delete = DTMLFile( - "dtml/entreprises/entreprise_correspondant_delete", globals() - ) + + def entreprise_correspondant_delete(self, entreprise_corresp_id, REQUEST=None): + """Form delete correspondant""" + c = self.do_entreprise_correspondant_list( + args={"entreprise_corresp_id": entreprise_corresp_id} + )[0] + H = [ + self.entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"), + """

Suppression du correspondant %(nom)s %(prenom)s

""" % c, + ] + tf = TrivialFormulator( + REQUEST.URL0, + REQUEST.form, + (("entreprise_corresp_id", {"input_type": "hidden"}),), + initvalues=c, + submitlabel="Confirmer la suppression", + cancelbutton="Annuler", + readonly=REQUEST["_read_only"], + ) + if tf[0] == 0: + H.append(tf[1]) + elif tf[0] == -1: + REQUEST.RESPONSE.redirect(REQUEST.URL1) + else: + self.do_entreprise_correspondant_delete(c["entreprise_corresp_id"]) + REQUEST.RESPONSE.redirect(REQUEST.URL1) + H.append(self.entreprise_footer(REQUEST)) + return "\n".join(H) + security.declareProtected(ScoEntrepriseChange, "entreprise_delete") - entreprise_delete = DTMLFile("dtml/entreprises/entreprise_delete", globals()) + + def entreprise_delete(self, entreprise_id, REQUEST=None): + """Form delete entreprise""" + E = self.do_entreprise_list(args={"entreprise_id": entreprise_id})[0] + H = [ + self.entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"), + """

Suppression de l'entreprise %(nom)s

+

Attention: supression définitive de l'entreprise, de ses correspondants et contacts. +

""" + % E, + ] + Cl = self.do_entreprise_correspondant_list( + args={"entreprise_id": entreprise_id} + ) + if Cl: + H.append( + """

Correspondants dans l'entreprise qui seront supprimés:

""") + + Cts = self.do_entreprise_contact_list(args={"entreprise_id": entreprise_id}) + if Cts: + H.append( + """

Contacts avec l'entreprise qui seront supprimés:

""") + tf = self.TrivialFormulator( + REQUEST.URL0, + REQUEST.form, + (("entreprise_id", {"input_type": "hidden"}),), + initvalues=E, + submitlabel="Confirmer la suppression", + cancelbutton="Annuler", + readonly=REQUEST["_read_only"], + ) + if tf[0] == 0: + H.append(tf[1]) + elif tf[0] == -1: + REQUEST.RESPONSE.redirect(REQUEST.URL1) + else: + self.do_entreprise_delete(E["entreprise_id"]) + REQUEST.RESPONSE.redirect(REQUEST.URL1) + H.append(self.entreprise_footer(REQUEST)) + return "\n".join(H) # -------------------------------------------------------------------- # - # Entreprises : Methodes en Python + # Entreprises : Actions # # -------------------------------------------------------------------- security.declareProtected(ScoEntrepriseChange, "do_entreprise_create") @@ -521,7 +1320,7 @@ class ZEntreprises( for x in r: e.append( "
  • %s %s (code %s)
  • " - % (strupper(x[1]), x[2] or "", x[0].strip()) + % (scu.strupper(x[1]), x[2] or "", x[0].strip()) ) e.append("") return ( @@ -780,7 +1579,7 @@ class ZEntreprises( H.append( """

    %s Supprimer cette entreprise

    """ % ( - icontag("delete_img", title="delete", border="0"), + scu.icontag("delete_img", title="delete", border="0"), F["entreprise_id"], ) ) @@ -850,42 +1649,6 @@ class ZEntreprises( self.do_entreprise_edit(tf[2]) return REQUEST.RESPONSE.redirect(REQUEST.URL1 + "?start=" + start) - # --- Misc tools.... ------------------ - security.declareProtected(ScoEntrepriseView, "str_abbrev") - - def str_abbrev(self, s, maxlen): - "abreviation" - if s == None: - return "?" - if len(s) < maxlen: - return s - return s[: maxlen - 3] + "..." - - security.declareProtected(ScoEntrepriseView, "setPageSizeCookie") - - def setPageSizeCookie(self, REQUEST=None): - "set page size cookie" - RESPONSE = REQUEST.RESPONSE - # - if REQUEST.form.has_key("entreprise_page_size"): - RESPONSE.setCookie( - "entreprise_page_size", - REQUEST.form["entreprise_page_size"], - path="/", - expires="Wed, 31-Dec-2025 23:55:00 GMT", - ) - RESPONSE.redirect(REQUEST.form["target_url"]) - - security.declareProtected(ScoEntrepriseView, "make_link_create_corr") - - def make_link_create_corr(self, entreprise_id): - "yet another stupid code snippet" - return ( - 'créer un nouveau correspondant' - ) - # -------------------------------------------------------------------- # diff --git a/notesdb.py b/notesdb.py index 5bdbcf40a8..09e51a3be2 100644 --- a/notesdb.py +++ b/notesdb.py @@ -141,6 +141,8 @@ def DBSelectArgs( distinct=True, aux_tables=[], id_name=None, + limit="", + offset="", ): """Select * from table where values match dict vals. Returns cnx, columns_names, list of tuples @@ -155,6 +157,12 @@ def DBSelectArgs( distinct = " distinct " else: distinct = "" + if limit != "": + limit = " LIMIT %d" % limit + if not offset: + offset = "" + if offset != "": + offset = " OFFSET %d" % offset operator = " " + operator + " " # liste des tables (apres "from") tables = [table] + [x[0] for x in aux_tables] @@ -195,7 +203,17 @@ def DBSelectArgs( if cond: cond = " where " + cond # - req = "select " + distinct + ", ".join(what) + " from " + tables + cond + orderby + req = ( + "select " + + distinct + + ", ".join(what) + + " from " + + tables + + cond + + orderby + + limit + + offset + ) # open('/tmp/select.log','a').write( req % vals + '\n' ) try: cursor.execute(req, vals) @@ -329,6 +347,8 @@ class EditableTable: test="=", sortkey=None, disable_formatting=False, + limit="", + offset="", ): "returns list of dicts" # REQLOG.write('%s: %s by %s (%s) %d\n'%(self.table_name,args,sys._getframe(1).f_code.co_name, sys._getframe(2).f_code.co_name, REQN)) @@ -347,6 +367,8 @@ class EditableTable: operator=operator, aux_tables=self.aux_tables, id_name=self.id_name, + limit=limit, + offset=offset, ) for r in res: self.format_output(r, disable_formatting=disable_formatting) diff --git a/static/css/scodoc.css b/static/css/scodoc.css index 7eebc65f8b..48dd4df816 100644 --- a/static/css/scodoc.css +++ b/static/css/scodoc.css @@ -2039,7 +2039,14 @@ table.entreprise_list, table.corr_list, table.contact_list { /* border-style: solid; */ border-spacing: 0px 0px; padding: 0px; + margin-left: 0px; } + +table.entreprise_list td.nbcorr a, table.entreprise_list td.nbcontact a, table.contact_list td.etudnom a, table.contact_list td a { + color: navy; + text-decoration: underline; +} + tr.entreprise_list_even, tr.corr_list_even, tr.contact_list_even { background-color: rgb(85%,85%,95%); } @@ -2047,6 +2054,19 @@ tr.entreprise_list_odd, tr.corr_list_odd, tr.contact_list_odd { background-color: rgb(90%,90%, 90%); } +span.table_nav_mid { + flex-grow: 1; /* Set the middle element to grow and stretch */ +} +span.table_nav_prev, span.table_nav_next { + width: 11em; /* A fixed width as the default */ +} + +div.table_nav { + width: 100%; + display: flex; + justify-content: space-between; +} + td.entreprise_descr, td.corr_descr, td.contact_descr { padding-left: 2em; } From 9b9ed47e9663e404eace7c390d1bde09f1caabaa Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Sat, 16 Jan 2021 10:44:02 +0100 Subject: [PATCH 2/3] Removed more Zope archaeological remains --- ZAbsences.py | 20 +------------------- ZEntreprises.py | 29 ----------------------------- ZNotes.py | 19 ------------------- ZScoDoc.py | 8 +------- ZScoUsers.py | 14 -------------- ZScolar.py | 18 +----------------- __init__.py | 18 ------------------ 7 files changed, 3 insertions(+), 123 deletions(-) diff --git a/ZAbsences.py b/ZAbsences.py index afdcb39674..33e09b6b76 100644 --- a/ZAbsences.py +++ b/ZAbsences.py @@ -697,6 +697,7 @@ class ZAbsences( return int(self.get_preference("work_saturday")) security.declareProtected(ScoView, "day_names") + def day_names(self): """Returns week day names. If work_saturday property is set, include saturday @@ -1993,22 +1994,3 @@ ou entrez une date pour visualiser les absents un jour donné : doc._pop() log("XMLgetAbsEtud (%gs)" % (time.time() - t0)) return repr(doc) - - -# -------------------------------------------------------------------- -# -# Zope Product Administration -# -# -------------------------------------------------------------------- -def manage_addZAbsences( - self, id="id_ZAbsences", title="The Title for ZAbsences Object", REQUEST=None -): - "Add a ZAbsences instance to a folder." - self._setObject(id, ZAbsences(id, title)) - if REQUEST is not None: - return self.manage_main(self, REQUEST) - # return self.manage_editForm(self, REQUEST) - - -# The form used to get the instance id from the user. -# manage_addZAbsencesForm = DTMLFile('dtml/manage_addZAbsencesForm', globals()) diff --git a/ZEntreprises.py b/ZEntreprises.py index 5eb610aaf4..53d287a0ea 100644 --- a/ZEntreprises.py +++ b/ZEntreprises.py @@ -251,20 +251,6 @@ class ZEntreprises( self.id = id self.title = title - # The form used to edit this object - # def manage_editZEntreprises(self, title, RESPONSE=None): - # "Changes the instance values" - # self.title = title - # self._p_changed = 1 - # RESPONSE.redirect("manage_editForm") - - # Ajout (dans l'instance) d'un dtml modifiable par Zope - def defaultDocFile(self, id, title, file): - f = open(file_path + "/dtml-editable/" + file + ".dtml") - file = f.read() - f.close() - self.manage_addDTMLMethod(id, title, file) - security.declareProtected(ScoEntrepriseView, "entreprise_header") def entreprise_header(self, REQUEST=None, page_title=""): @@ -1648,18 +1634,3 @@ class ZEntreprises( else: self.do_entreprise_edit(tf[2]) return REQUEST.RESPONSE.redirect(REQUEST.URL1 + "?start=" + start) - - -# -------------------------------------------------------------------- -# -# Zope Product Administration -# -# -------------------------------------------------------------------- -def manage_addZEntreprises( - self, id="id_ZEntreprises", title="The Title for ZEntreprises Object", REQUEST=None -): - "Add a ZEntreprises instance to a folder." - self._setObject(id, ZEntreprises(id, title)) - if REQUEST is not None: - return self.manage_main(self, REQUEST) - # return self.manage_editForm(self, REQUEST) diff --git a/ZNotes.py b/ZNotes.py index b1e4fe9232..d02d384e34 100644 --- a/ZNotes.py +++ b/ZNotes.py @@ -3631,22 +3631,3 @@ class ZNotes(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Impl ) # -------------------------------------------------------------------- - - -# -------------------------------------------------------------------- -# -# Zope Product Administration -# -# -------------------------------------------------------------------- -def manage_addZNotes( - self, id="id_ZNotes", title="The Title for ZNotes Object", REQUEST=None -): - "Add a ZNotes instance to a folder." - self._setObject(id, ZNotes(id, title)) - if REQUEST is not None: - return self.manage_main(self, REQUEST) - # return self.manage_editForm(self, REQUEST) - - -# The form used to get the instance id from the user. -manage_addZNotesForm = DTMLFile("dtml/manage_addZNotesForm", globals()) diff --git a/ZScoDoc.py b/ZScoDoc.py index c2c7094ccd..76827bd8be 100644 --- a/ZScoDoc.py +++ b/ZScoDoc.py @@ -77,13 +77,7 @@ class ZScoDoc(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Imp manage_options = ( ({"label": "Contents", "action": "manage_main"},) + PropertyManager.manage_options # add the 'Properties' tab - + ( - # this line is kept as an example with the files : - # dtml/manage_editZScolarForm.dtml - # html/ZScolar-edit.stx - # {'label': 'Properties', 'action': 'manage_editForm',}, - {"label": "View", "action": "index_html"}, - ) + + ({"label": "View", "action": "index_html"},) + Item.manage_options # add the 'Undo' & 'Owner' tab + RoleManager.manage_options # add the 'Security' tab ) diff --git a/ZScoUsers.py b/ZScoUsers.py index c62d74f267..0e03a39e01 100644 --- a/ZScoUsers.py +++ b/ZScoUsers.py @@ -105,20 +105,6 @@ class ZScoUsers( self.id = id self.title = title - # The form used to edit this object - # def manage_editZScousers(self, title, RESPONSE=None): - # "Changes the instance values" - # self.title = title - # self._p_changed = 1 - # RESPONSE.redirect("manage_editForm") - - # Ajout (dans l'instance) d'un dtml modifiable par Zope - def defaultDocFile(self, id, title, file): - f = open(file_path + "/dtml-editable/" + file + ".dtml") - file = f.read() - f.close() - self.manage_addDTMLMethod(id, title, file) - # Connexion to SQL database of users: # Ugly but necessary during transition out of Zope: diff --git a/ZScolar.py b/ZScolar.py index e42397c88d..c39d8bdc57 100644 --- a/ZScolar.py +++ b/ZScolar.py @@ -133,13 +133,7 @@ class ZScolar(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Imp manage_options = ( ({"label": "Contents", "action": "manage_main"},) + PropertyManager.manage_options # add the 'Properties' tab - + ( - # this line is kept as an example with the files : - # dtml/manage_editZScolarForm.dtml - # html/ZScolar-edit.stx - # {'label': 'Properties', 'action': 'manage_editForm',}, - {"label": "View", "action": "index_html"}, - ) + + ({"label": "View", "action": "index_html"},) + Item.manage_options # add the 'Undo' & 'Owner' tab + RoleManager.manage_options # add the 'Security' tab ) @@ -152,17 +146,7 @@ class ZScolar(ObjectManager, PropertyManager, RoleManager, Item, Persistent, Imp self.title = title self._db_cnx_string = db_cnx_string self._cnx = None - # --- add editable DTML documents: - # self.defaultDocFile('sidebar_dept', - # 'barre gauche (partie haute)', - # 'sidebar_dept') - # --- add DB connector - # id = 'DB' - # da = ZopeDA.Connection( - # id, 'DB connector', db_cnx_string, False, - # check=1, tilevel=2, encoding='utf-8') - # self._setObject(id, da) # --- add Scousers instance id = "Users" obj = ZScoUsers.ZScoUsers(id, "Gestion utilisateurs zope") diff --git a/__init__.py b/__init__.py index a7ebcf4b30..98fd402381 100644 --- a/__init__.py +++ b/__init__.py @@ -27,8 +27,6 @@ from ZScolar import ZScolar, manage_addZScolarForm, manage_addZScolar -# from ZNotes import ZNotes, manage_addZNotesForm, manage_addZNotes - from ZScoDoc import ZScoDoc, manage_addZScoDoc # from sco_zope import * @@ -53,23 +51,7 @@ def initialize(context): icon="static/icons/sco_icon.png", ) - # context.registerHelp() - # context.registerHelpTitle("ZScolar") - # --- ZScoDoc context.registerClass( ZScoDoc, constructors=(manage_addZScoDoc,), icon="static/icons/sco_icon.png" ) - - # --- ZNotes - # context.registerClass( - # ZNotes, - # constructors = ( - # manage_addZNotesForm, - # manage_addZNotes - # ), - # icon = 'static/icons/notes_icon.png' - # ) - - # context.registerHelp() - # context.registerHelpTitle("ZNotes") From 09f9124b01b07ddaecc5e78a43b039238b1c51f0 Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Sat, 16 Jan 2021 10:53:15 +0100 Subject: [PATCH 3/3] removed (last) dtml methods: entreprises --- .../entreprise_contact_create.dtml | 62 -------- .../entreprise_contact_delete.dtml | 27 ---- dtml/entreprises/entreprise_contact_edit.dtml | 62 -------- dtml/entreprises/entreprise_contact_list.dtml | 54 ------- .../entreprise_correspondant_create.dtml | 43 ------ .../entreprise_correspondant_delete.dtml | 27 ---- .../entreprise_correspondant_edit.dtml | 41 ------ .../entreprise_correspondant_list.dtml | 52 ------- dtml/entreprises/entreprise_delete.dtml | 60 -------- dtml/entreprises/index_html.dtml | 139 ------------------ 10 files changed, 567 deletions(-) delete mode 100644 dtml/entreprises/entreprise_contact_create.dtml delete mode 100644 dtml/entreprises/entreprise_contact_delete.dtml delete mode 100644 dtml/entreprises/entreprise_contact_edit.dtml delete mode 100644 dtml/entreprises/entreprise_contact_list.dtml delete mode 100644 dtml/entreprises/entreprise_correspondant_create.dtml delete mode 100644 dtml/entreprises/entreprise_correspondant_delete.dtml delete mode 100644 dtml/entreprises/entreprise_correspondant_edit.dtml delete mode 100644 dtml/entreprises/entreprise_correspondant_list.dtml delete mode 100644 dtml/entreprises/entreprise_delete.dtml delete mode 100644 dtml/entreprises/index_html.dtml diff --git a/dtml/entreprises/entreprise_contact_create.dtml b/dtml/entreprises/entreprise_contact_create.dtml deleted file mode 100644 index e0c3ab058b..0000000000 --- a/dtml/entreprises/entreprise_contact_create.dtml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - -

    Nouveau "contact" avec l'entreprise

    - - - - - - - - -

    -
    - - - - - - - -
    - - \ No newline at end of file diff --git a/dtml/entreprises/entreprise_contact_delete.dtml b/dtml/entreprises/entreprise_contact_delete.dtml deleted file mode 100644 index df73659b91..0000000000 --- a/dtml/entreprises/entreprise_contact_delete.dtml +++ /dev/null @@ -1,27 +0,0 @@ - - - - -

    Suppression du contact

    - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/dtml/entreprises/entreprise_contact_edit.dtml b/dtml/entreprises/entreprise_contact_edit.dtml deleted file mode 100644 index 5fe437f14b..0000000000 --- a/dtml/entreprises/entreprise_contact_edit.dtml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - -

    - - -

    Contact avec entreprise

    - - - - - - - -

    -
    - - - -

    Supprimer ce contact

    -
    - - - - - - -
    - - - \ No newline at end of file diff --git a/dtml/entreprises/entreprise_contact_list.dtml b/dtml/entreprises/entreprise_contact_list.dtml deleted file mode 100644 index cffeb3512d..0000000000 --- a/dtml/entreprises/entreprise_contact_list.dtml +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - -

    Listes des contacts avec l'entreprise

    - - -

    Listes des contacts

    - -
    - - - - - - - - - - - - - - - - - - - - - - - -
    DateObjetEntrepriseEtudiantDescription
    "> - - - - - "> - - -
    Aucun contact !
    - - - -

    -">nouveau "contact" -

    -
    -
    - - \ No newline at end of file diff --git a/dtml/entreprises/entreprise_correspondant_create.dtml b/dtml/entreprises/entreprise_correspondant_create.dtml deleted file mode 100644 index 2ffdbba441..0000000000 --- a/dtml/entreprises/entreprise_correspondant_create.dtml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - -

    dans l'entreprise

    - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/dtml/entreprises/entreprise_correspondant_delete.dtml b/dtml/entreprises/entreprise_correspondant_delete.dtml deleted file mode 100644 index ac50550ee3..0000000000 --- a/dtml/entreprises/entreprise_correspondant_delete.dtml +++ /dev/null @@ -1,27 +0,0 @@ - - - - -

    Suppression du correspondant

    - - - - - - - - - - - - - - - - diff --git a/dtml/entreprises/entreprise_correspondant_edit.dtml b/dtml/entreprises/entreprise_correspondant_edit.dtml deleted file mode 100644 index 2b254568bf..0000000000 --- a/dtml/entreprises/entreprise_correspondant_edit.dtml +++ /dev/null @@ -1,41 +0,0 @@ - - - - -

    - - - - - - - - - - - - - - - diff --git a/dtml/entreprises/entreprise_correspondant_list.dtml b/dtml/entreprises/entreprise_correspondant_list.dtml deleted file mode 100644 index 085d4375a4..0000000000 --- a/dtml/entreprises/entreprise_correspondant_list.dtml +++ /dev/null @@ -1,52 +0,0 @@ - - - - -

    Listes des correspondants dans l'entreprise

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NomEntrepriseFonctionTéléphoneMailNote
    "> - - - - - - / - / - - "> -
    ">
    -
    ">modifier ">supprimer
    Aucun correspondant dans cette entreprise !
    - -

    - - - diff --git a/dtml/entreprises/entreprise_delete.dtml b/dtml/entreprises/entreprise_delete.dtml deleted file mode 100644 index 7f7db5f8bb..0000000000 --- a/dtml/entreprises/entreprise_delete.dtml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - -

    Suppression de l'entreprise

    - -

    Attention: supression définitive de l'entreprise, de ses correspondants et contacts. -

    - - - - -

    Correspondants dans l'entreprise (seront supprimés):

    -
      - - -
    • - - () -
    • -
      -
      -
    -
    - - - -

    Contacts avec l'entreprise (seront supprimés):

    -
      - - -
    • - () -
    • -
      -
      -
    -
    - - - - - - - - - - - - - - - diff --git a/dtml/entreprises/index_html.dtml b/dtml/entreprises/index_html.dtml deleted file mode 100644 index 1e2fbc25cb..0000000000 --- a/dtml/entreprises/index_html.dtml +++ /dev/null @@ -1,139 +0,0 @@ - - - - - - - - - - -

    - - -

    -Attention: version test préliminaire. Signaler les problèmes à Emmanuel -

    -
    - - - - - - - - - - - - - - -

    valeur invalide pour 'sort_type' !

    -
    - - - - - - - - - - -
    - - - - - - - - -
    nomvilleétudiant     Tri par:
    -
    - - - - - -
    - - - -
    EntreprisesRésultats - sur -
    - - - - - - - - - - - - - - - - - - - - - - -
    &start=">
     
    - - -

    Aucune entreprise !

    - - - -

    -

    - "> - - - - - - page précédente     - - - - - - page suivante - - - -   Résultats par page : - -
    - -

    -