# -*- 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 # ############################################################################## """ Gestion des relations avec les entreprises """ import urllib from sco_zope import * # --------------- from notesdb import * from notes_log import log from scolog import logdb from sco_utils import * import html_sidebar from TrivialFormulator import TrivialFormulator, TF import scolars import string, re import time, calendar def _format_nom(nom): "formatte nom (filtre en entree db) d'une entreprise" if not nom: return nom nom = nom.decode(SCO_ENCODING) return (nom[0].upper() + nom[1:]).encode(SCO_ENCODING) class EntreprisesEditor(EditableTable): def delete(self, cnx, oid): "delete correspondants and contacts, then self" # first, delete all correspondants and contacts cursor = cnx.cursor(cursor_factory=ScoDocCursor) cursor.execute( "delete from entreprise_contact where entreprise_id=%(entreprise_id)s", {"entreprise_id": oid}, ) cursor.execute( "delete from entreprise_correspondant where entreprise_id=%(entreprise_id)s", {"entreprise_id": oid}, ) cnx.commit() EditableTable.delete(self, cnx, oid) def list( self, cnx, args={}, operator="and", test="=", sortkey=None, sort_on_contact=False, ZEntrepriseInstance=None, ): # list, then sort on date of last contact R = EditableTable.list( self, cnx, args=args, operator=operator, test=test, sortkey=sortkey ) if sort_on_contact: for r in R: c = ZEntrepriseInstance.do_entreprise_contact_list( args={"entreprise_id": r["entreprise_id"]}, disable_formatting=True ) if c: r["date"] = max([x["date"] or datetime.date.min for x in c]) else: r["date"] = datetime.date.min # sort R.sort(lambda r1, r2: cmp(r2["date"], r1["date"])) for r in R: r["date"] = DateISOtoDMY(r["date"]) return R def list_by_etud( self, cnx, args={}, sort_on_contact=False, disable_formatting=False ): "cherche rentreprise ayant eu contact avec etudiant" cursor = cnx.cursor(cursor_factory=ScoDocCursor) cursor.execute( "select E.*, I.nom as etud_nom, I.prenom as etud_prenom, C.date from entreprises E, entreprise_contact C, identite I where C.entreprise_id = E.entreprise_id and C.etudid = I.etudid and I.nom ~* %(etud_nom)s ORDER BY E.nom", args, ) _, res = [x[0] for x in cursor.description], cursor.dictfetchall() R = [] for r in res: r["etud_prenom"] = r["etud_prenom"] or "" d = {} for key in r: v = r[key] # format value if not disable_formatting and self.output_formators.has_key(key): v = self.output_formators[key](v) d[key] = v R.append(d) # sort if sort_on_contact: R.sort( lambda r1, r2: cmp( r2["date"] or datetime.date.min, r1["date"] or datetime.date.min ) ) for r in R: r["date"] = DateISOtoDMY(r["date"] or datetime.date.min) return R _entreprisesEditor = EntreprisesEditor( "entreprises", "entreprise_id", ( "entreprise_id", "nom", "adresse", "ville", "codepostal", "pays", "contact_origine", "secteur", "privee", "localisation", "qualite_relation", "plus10salaries", "note", "date_creation", ), sortkey="nom", input_formators={"nom": _format_nom}, ) # ----------- Correspondants _entreprise_correspEditor = EditableTable( "entreprise_correspondant", "entreprise_corresp_id", ( "entreprise_corresp_id", "entreprise_id", "civilite", "nom", "prenom", "fonction", "phone1", "phone2", "mobile", "fax", "mail1", "mail2", "note", ), sortkey="nom", ) # ----------- Contacts _entreprise_contactEditor = EditableTable( "entreprise_contact", "entreprise_contact_id", ( "entreprise_contact_id", "date", "type_contact", "entreprise_id", "entreprise_corresp_id", "etudid", "description", "enseignant", ), sortkey="date", output_formators={"date": DateISOtoDMY}, input_formators={"date": DateDMYtoISO}, ) # --------------- class ZEntreprises( ObjectManager, PropertyManager, RoleManager, Item, Persistent, Implicit ): "ZEntreprises object" meta_type = "ZEntreprises" security = ClassSecurityInfo() # This is the list of the methods associated to 'tabs' in the ZMI # Be aware that The first in the list is the one shown by default, so if # the 'View' tab is the first, you will never see your tabs by cliquing # on the object. 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"}, ) + Item.manage_options # add the 'Undo' & 'Owner' tab + RoleManager.manage_options # add the 'Security' tab ) # no permissions, only called from python def __init__(self, id, title): "initialise a new instance" 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=""): "common header for all Entreprises pages" authuser = REQUEST.AUTHENTICATED_USER # _read_only is used to modify pages properties (links, buttons) # Python methods (do_xxx in this class) are also protected individualy) if authuser.has_permission(ScoEntrepriseChange, self): REQUEST.set("_read_only", False) else: REQUEST.set("_read_only", True) return self.sco_header(REQUEST, container=self, page_title=page_title) security.declareProtected(ScoEntrepriseView, "entreprise_footer") def entreprise_footer(self, REQUEST): "common entreprise footer" return self.sco_footer(REQUEST) security.declareProtected(ScoEntrepriseView, "sidebar") def sidebar(self, REQUEST): "barre gauche (overide std sco sidebar)" # rewritten from legacy DTML code context = self params = {"ScoURL": context.ScoURL()} H = [ """
""") return "".join(H) # -------------------------------------------------------------------- # # Entreprises : Methodes en DTML # # -------------------------------------------------------------------- # used to view content of the object security.declareProtected(ScoEntrepriseView, "index_html") index_html = DTMLFile("dtml/entreprises/index_html", globals()) 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: security.declareProtected(ScoEntrepriseChange, "entreprise_contact_create") entreprise_contact_create = DTMLFile( "dtml/entreprises/entreprise_contact_create", globals() ) security.declareProtected(ScoEntrepriseChange, "entreprise_contact_delete") entreprise_contact_delete = DTMLFile( "dtml/entreprises/entreprise_contact_delete", globals() ) security.declareProtected(ScoEntrepriseChange, "entreprise_correspondant_create") entreprise_correspondant_create = DTMLFile( "dtml/entreprises/entreprise_correspondant_create", globals() ) security.declareProtected(ScoEntrepriseChange, "entreprise_correspondant_delete") entreprise_correspondant_delete = DTMLFile( "dtml/entreprises/entreprise_correspondant_delete", globals() ) security.declareProtected(ScoEntrepriseChange, "entreprise_delete") entreprise_delete = DTMLFile("dtml/entreprises/entreprise_delete", globals()) # -------------------------------------------------------------------- # # Entreprises : Methodes en Python # # -------------------------------------------------------------------- security.declareProtected(ScoEntrepriseChange, "do_entreprise_create") def do_entreprise_create(self, args): "entreprise_create" cnx = self.GetDBConnexion() r = _entreprisesEditor.create(cnx, args) return r security.declareProtected(ScoEntrepriseChange, "do_entreprise_delete") def do_entreprise_delete(self, oid): "entreprise_delete" cnx = self.GetDBConnexion() _entreprisesEditor.delete(cnx, oid) security.declareProtected(ScoEntrepriseView, "do_entreprise_list") def do_entreprise_list(self, **kw): "entreprise_list" cnx = self.GetDBConnexion() kw["ZEntrepriseInstance"] = self return _entreprisesEditor.list(cnx, **kw) security.declareProtected(ScoEntrepriseView, "do_entreprise_list_by_etud") def do_entreprise_list_by_etud(self, **kw): "entreprise_list_by_etud" cnx = self.GetDBConnexion() return _entreprisesEditor.list_by_etud(cnx, **kw) security.declareProtected(ScoEntrepriseView, "do_entreprise_edit") def do_entreprise_edit(self, *args, **kw): "entreprise_edit" cnx = self.GetDBConnexion() _entreprisesEditor.edit(cnx, *args, **kw) security.declareProtected(ScoEntrepriseChange, "do_entreprise_correspondant_create") def do_entreprise_correspondant_create(self, args): "entreprise_correspondant_create" cnx = self.GetDBConnexion() r = _entreprise_correspEditor.create(cnx, args) return r security.declareProtected(ScoEntrepriseChange, "do_entreprise_correspondant_delete") def do_entreprise_correspondant_delete(self, oid): "entreprise_correspondant_delete" cnx = self.GetDBConnexion() _entreprise_correspEditor.delete(cnx, oid) security.declareProtected(ScoEntrepriseView, "do_entreprise_correspondant_list") def do_entreprise_correspondant_list(self, **kw): "entreprise_correspondant_list" cnx = self.GetDBConnexion() return _entreprise_correspEditor.list(cnx, **kw) security.declareProtected(ScoEntrepriseView, "do_entreprise_correspondant_edit") def do_entreprise_correspondant_edit(self, *args, **kw): "entreprise_correspondant_edit" cnx = self.GetDBConnexion() _entreprise_correspEditor.edit(cnx, *args, **kw) def do_entreprise_correspondant_listnames(self, args={}): "-> liste des noms des correspondants (pour affichage menu)" C = self.do_entreprise_correspondant_list(args=args) return [ (x["prenom"] + " " + x["nom"], str(x["entreprise_corresp_id"])) for x in C ] security.declareProtected(ScoEntrepriseChange, "do_entreprise_contact_create") def do_entreprise_contact_create(self, args): "entreprise_contact_create" cnx = self.GetDBConnexion() r = _entreprise_contactEditor.create(cnx, args) return r security.declareProtected(ScoEntrepriseChange, "do_entreprise_contact_delete") def do_entreprise_contact_delete(self, oid): "entreprise_contact_delete" cnx = self.GetDBConnexion() _entreprise_contactEditor.delete(cnx, oid) security.declareProtected(ScoEntrepriseView, "do_entreprise_contact_list") def do_entreprise_contact_list(self, **kw): "entreprise_contact_list" cnx = self.GetDBConnexion() return _entreprise_contactEditor.list(cnx, **kw) security.declareProtected(ScoEntrepriseView, "do_entreprise_contact_edit") def do_entreprise_contact_edit(self, *args, **kw): "entreprise_contact_edit" cnx = self.GetDBConnexion() _entreprise_contactEditor.edit(cnx, *args, **kw) # security.declareProtected(ScoEntrepriseView, "do_entreprise_check_etudiant") def do_entreprise_check_etudiant(self, etudiant): """Si etudiant est vide, ou un ETUDID valide, ou un nom unique, retourne (1, ETUDID). Sinon, retourne (0, 'message explicatif') """ etudiant = etudiant.strip().translate( None, "'()" ) # suppress parens and quote from name if not etudiant: return 1, None cnx = self.GetDBConnexion() cursor = cnx.cursor(cursor_factory=ScoDocCursor) cursor.execute( "select etudid, nom, prenom from identite where upper(nom) ~ upper(%(etudiant)s) or etudid=%(etudiant)s", {"etudiant": etudiant}, ) r = cursor.fetchall() if len(r) < 1: return 0, 'Aucun etudiant ne correspond à "%s"' % etudiant elif len(r) > 10: return ( 0, "%d etudiants correspondent à ce nom (utilisez le code)" % len(r), ) elif len(r) > 1: e = ['