diff --git a/ZAbsences.py b/ZAbsences.py
index e10afce5e..ab194f5ab 100644
--- a/ZAbsences.py
+++ b/ZAbsences.py
@@ -666,21 +666,6 @@ class ZAbsences(
if self.CountAbs(etudid, jour, jour, matin, moduleimpl_id) == 0:
self._AddAbsence(etudid, jour, matin, 0, REQUEST, "", moduleimpl_id)
- #
- security.declareProtected(ScoView, "CalSelectWeek")
-
- def CalSelectWeek(self, year=None, REQUEST=None):
- "display calendar allowing week selection"
- if not year:
- year = scu.AnneeScolaire(REQUEST)
- sems = sco_formsemestre.do_formsemestre_list(self)
- if not sems:
- js = ""
- else:
- js = 'onmouseover="highlightweek(this);" onmouseout="deselectweeks();" onclick="wclick(this);"'
- C = sco_abs.YearTable(self, int(year), dayattributes=js)
- return C
-
# --- Misc tools.... ------------------
def _isFarFutur(self, jour):
@@ -691,65 +676,6 @@ class ZAbsences(
# 6 mois ~ 182 jours:
return j - datetime.date.today() > datetime.timedelta(182)
- security.declareProtected(ScoView, "is_work_saturday")
-
- def is_work_saturday(self):
- "Vrai si le samedi est travaillé"
- 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
- """
- if self.is_work_saturday():
- return ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"]
- else:
- return ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi"]
-
- security.declareProtected(ScoView, "ListMondays")
-
- def ListMondays(self, year=None, REQUEST=None):
- """return list of mondays (ISO dates), from september to june"""
- if not year:
- year = scu.AnneeScolaire(REQUEST)
- d = ddmmyyyy("1/9/%d" % year, work_saturday=self.is_work_saturday())
- while d.weekday != 0:
- d = d.next()
- end = ddmmyyyy("1/7/%d" % (year + 1), work_saturday=self.is_work_saturday())
- L = [d]
- while d < end:
- d = d.next(days=7)
- L.append(d)
- return map(lambda x: x.ISO(), L)
-
- security.declareProtected(ScoView, "NextISODay")
-
- def NextISODay(self, date):
- "return date after date"
- d = ddmmyyyy(date, fmt="iso", work_saturday=self.is_work_saturday())
- return d.next().ISO()
-
- security.declareProtected(ScoView, "DateRangeISO")
-
- def DateRangeISO(self, date_beg, date_end, workable=1):
- """returns list of dates in [date_beg,date_end]
- workable = 1 => keeps only workable days"""
- if not date_beg:
- raise ScoValueError("pas de date spécifiée !")
- if not date_end:
- date_end = date_beg
- r = []
- cur = ddmmyyyy(date_beg, work_saturday=self.is_work_saturday())
- end = ddmmyyyy(date_end, work_saturday=self.is_work_saturday())
- while cur <= end:
- if (not workable) or cur.iswork():
- r.append(cur)
- cur = cur.next()
-
- return map(lambda x: x.ISO(), r)
-
# ------------ HTML Interfaces
security.declareProtected(ScoAbsChange, "SignaleAbsenceGrHebdo")
@@ -801,8 +727,8 @@ class ZAbsences(
# calcule dates jours de cette semaine
# liste de dates iso "yyyy-mm-dd"
datessem = [notesdb.DateDMYtoISO(datelundi)]
- for _ in self.day_names()[1:]:
- datessem.append(self.NextISODay(datessem[-1]))
+ for _ in sco_abs.day_names(self)[1:]:
+ datessem.append(sco_abs.next_iso_day(self, datessem[-1]))
#
if groups_infos.tous_les_etuds_du_sem:
gr_tit = "en"
@@ -944,12 +870,12 @@ class ZAbsences(
sem = sco_formsemestre.do_formsemestre_list(
self, {"formsemestre_id": formsemestre_id}
)[0]
-
- jourdebut = ddmmyyyy(datedebut, work_saturday=self.is_work_saturday())
- jourfin = ddmmyyyy(datefin, work_saturday=self.is_work_saturday())
+ work_saturday = sco_abs.is_work_saturday(self)
+ jourdebut = ddmmyyyy(datedebut, work_saturday=work_saturday)
+ jourfin = ddmmyyyy(datefin, work_saturday=work_saturday)
today = ddmmyyyy(
time.strftime("%d/%m/%Y", time.localtime()),
- work_saturday=self.is_work_saturday(),
+ work_saturday=work_saturday,
)
today.next()
if jourfin > today: # ne propose jamais les semaines dans le futur
@@ -964,7 +890,7 @@ class ZAbsences(
)
# calcule dates
dates = [] # ddmmyyyy instances
- d = ddmmyyyy(datedebut, work_saturday=self.is_work_saturday())
+ d = ddmmyyyy(datedebut, work_saturday=work_saturday)
while d <= jourfin:
dates.append(d)
d = d.next(7) # avance d'une semaine
@@ -982,7 +908,7 @@ class ZAbsences(
url_link_semaines += "&moduleimpl_id=" + moduleimpl_id
#
dates = [x.ISO() for x in dates]
- dayname = self.day_names()[jourdebut.weekday]
+ dayname = sco_abs.day_names(self)[jourdebut.weekday]
if groups_infos.tous_les_etuds_du_sem:
gr_tit = "en"
@@ -1119,7 +1045,7 @@ class ZAbsences(
odates = [datetime.date(*[int(x) for x in d.split("-")]) for d in dates]
# Titres colonnes
noms_jours = [] # eg [ "Lundi", "mardi", "Samedi", ... ]
- jn = self.day_names()
+ jn = sco_abs.day_names(self)
for d in odates:
idx_jour = d.weekday()
noms_jours.append(jn[idx_jour])
@@ -1844,7 +1770,7 @@ ou entrez une date pour visualiser les absents un jour donné :
# 1-- ajout des absences (et justifs)
datedebut = billet["abs_begin"].strftime("%d/%m/%Y")
datefin = billet["abs_end"].strftime("%d/%m/%Y")
- dates = self.DateRangeISO(datedebut, datefin)
+ dates = sco_abs.DateRangeISO(self, datedebut, datefin)
# commence après-midi ?
if dates and billet["abs_begin"].hour > 11:
self._AddAbsence(
diff --git a/ZEntreprises.py b/ZEntreprises.py
index 53d287a0e..56f16eaac 100644
--- a/ZEntreprises.py
+++ b/ZEntreprises.py
@@ -43,7 +43,6 @@ from sco_permissions import ScoEntrepriseView, ScoEntrepriseChange
# ---------------
-from notesdb import *
from notes_log import log
from scolog import logdb
from sco_utils import SCO_ENCODING
@@ -53,169 +52,17 @@ import VERSION
from gen_tables import GenTable
from TrivialFormulator import TrivialFormulator, TF
import scolars
+import sco_entreprises
-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)
+def entreprise_header(context, REQUEST=None, page_title=""):
+ "common header for all Entreprises pages"
+ return context.sco_header(REQUEST, container=context, page_title=page_title)
-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,
- limit="",
- offset="",
- ):
- # list, then sort on date of last contact
- R = EditableTable.list(
- self,
- cnx,
- args=args,
- operator=operator,
- test=test,
- sortkey=sortkey,
- limit=limit,
- offset=offset,
- )
- 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},
-)
-
-# ---------------
+def entreprise_footer(context, REQUEST):
+ "common entreprise footer"
+ return context.sco_footer(REQUEST)
class ZEntreprises(
@@ -251,42 +98,22 @@ class ZEntreprises(
self.id = id
self.title = title
- 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()}
-
+ # XXX rare cas restant d'utilisation de l'acquisition Zope2: à revoir
+ params = {"ScoURL": self.ScoURL()}
H = [
"""
""")
return "".join(H)
@@ -352,12 +181,13 @@ class ZEntreprises(
offset = int(offset or 0)
if etud_nom:
- entreprises = self.do_entreprise_list_by_etud(
- args=REQUEST.form, sort_on_contact=True
+ entreprises = sco_entreprises.do_entreprise_list_by_etud(
+ self, args=REQUEST.form, sort_on_contact=True
)
table_navigation = ""
else:
- entreprises = self.do_entreprise_list(
+ entreprises = sco_entreprises.do_entreprise_list(
+ self,
args=REQUEST.form,
test="~*",
sort_on_contact=True,
@@ -390,15 +220,15 @@ class ZEntreprises(
# 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["correspondants"] = sco_entreprises.do_entreprise_correspondant_list(
+ self, 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["contacts"] = sco_entreprises.do_entreprise_contact_list(
+ self, args={"entreprise_id": e["entreprise_id"]}
)
e["nbcontact"] = "%d contacts." % len(e["contacts"])
e["_nbcontact_target"] = (
@@ -430,12 +260,14 @@ class ZEntreprises(
return tab.make_page(self, format=format, REQUEST=REQUEST)
else:
H = [
- self.entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"),
+ entreprise_header(
+ self, REQUEST=REQUEST, page_title="Suivi entreprises"
+ ),
"""Suivi relations entreprises """,
"""""",
tab.html(),
"""
""",
- self.entreprise_footer(REQUEST),
+ entreprise_footer(self, REQUEST),
]
return "\n".join(H)
@@ -443,17 +275,21 @@ class ZEntreprises(
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")]
+ H = [entreprise_header(self, 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})
+ E = sco_entreprises.do_entreprise_list(
+ self, args={"entreprise_id": entreprise_id}
+ )[0]
+ C = sco_entreprises.do_entreprise_contact_list(
+ self, args={"entreprise_id": entreprise_id}
+ )
H.append(
"""
"""
% E
)
else:
- C = self.do_entreprise_contact_list(args={})
+ C = sco_entreprises.do_entreprise_contact_list(self, args={})
H.append(
"""
"""
@@ -465,8 +301,8 @@ class ZEntreprises(
REQUEST.URL1,
c["entreprise_contact_id"],
)
- c["entreprise"] = self.do_entreprise_list(
- args={"entreprise_id": c["entreprise_id"]}
+ c["entreprise"] = sco_entreprises.do_entreprise_list(
+ self, args={"entreprise_id": c["entreprise_id"]}
)[0]
if c["etudid"]:
c["etud"] = self.getEtudInfo(etudid=c["etudid"], filled=1)[0]
@@ -502,7 +338,7 @@ class ZEntreprises(
H.append(tab.html())
- if not REQUEST["_read_only"]: # portage DTML, à modifier
+ if REQUEST.AUTHENTICATED_USER.has_permission(ScoEntrepriseChange, self):
if entreprise_id:
H.append(
"""nouveau "contact"
@@ -510,7 +346,7 @@ class ZEntreprises(
% E
)
- H.append(self.entreprise_footer(REQUEST))
+ H.append(entreprise_footer(self, REQUEST))
return "\n".join(H)
security.declareProtected(ScoEntrepriseView, "entreprise_correspondant_list")
@@ -522,23 +358,28 @@ class ZEntreprises(
REQUEST=None,
):
"""Liste des correspondants de l'entreprise"""
- E = self.do_entreprise_list(args={"entreprise_id": entreprise_id})[0]
+ E = sco_entreprises.do_entreprise_list(
+ self, args={"entreprise_id": entreprise_id}
+ )[0]
H = [
- self.entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"),
+ entreprise_header(self, 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}
+ correspondants = sco_entreprises.do_entreprise_correspondant_list(
+ self, 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[
+ "_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"]:
@@ -559,11 +400,11 @@ class ZEntreprises(
]
)
c["modifier"] = (
- 'modifier '
+ 'modifier '
% c["entreprise_corresp_id"]
)
c["supprimer"] = (
- 'supprimer '
+ 'supprimer '
% c["entreprise_corresp_id"]
)
tab = GenTable(
@@ -604,34 +445,36 @@ class ZEntreprises(
H.append(tab.html())
- if not REQUEST["_read_only"]: # portage DTML, à modifier
+ if REQUEST.AUTHENTICATED_USER.has_permission(ScoEntrepriseChange, self):
H.append(
"""Ajouter un correspondant dans l'entreprise %(nom)s
"""
% E
)
- H.append(self.entreprise_footer(REQUEST))
+ H.append(entreprise_footer(self, 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}
+ c = sco_entreprises.do_entreprise_contact_list(
+ self, 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"]}
+ E = sco_entreprises.do_entreprise_list(
+ self, args={"entreprise_id": c["entreprise_id"]}
+ )[0]
+ correspondants = sco_entreprises.do_entreprise_correspondant_listnames(
+ self, args={"entreprise_id": c["entreprise_id"]}
) + [("inconnu", "")]
H = [
- self.entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"),
+ entreprise_header(self, REQUEST=REQUEST, page_title="Suivi entreprises"),
"""
Contact avec entreprise %(nom)s """
% E,
@@ -708,12 +551,14 @@ class ZEntreprises(
cancelbutton="Annuler",
initvalues=c,
submitlabel="Modifier les valeurs",
- readonly=REQUEST["_read_only"],
+ readonly=not REQUEST.AUTHENTICATED_USER.has_permission(
+ ScoEntrepriseChange, self
+ ),
)
if tf[0] == 0:
H.append(tf[1])
- if not REQUEST["_read_only"]: # portage DTML, à modifier
+ if REQUEST.AUTHENTICATED_USER.has_permission(ScoEntrepriseChange, self):
H.append(
"""Supprimer ce contact
"""
% entreprise_contact_id
@@ -721,30 +566,31 @@ class ZEntreprises(
elif tf[0] == -1:
REQUEST.RESPONSE.redirect(REQUEST.URL1)
else:
- etudok = self.do_entreprise_check_etudiant(tf[2]["etudiant"])
+ etudok = sco_entreprises.do_entreprise_check_etudiant(
+ self, 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])
+ sco_entreprises.do_entreprise_contact_edit(self, tf[2])
REQUEST.RESPONSE.redirect(
REQUEST.URL1
+ "/entreprise_contact_list?entreprise_id="
+ str(c["entreprise_id"])
)
- H.append(self.entreprise_footer(REQUEST))
+ H.append(entreprise_footer(self, 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}
+ c = sco_entreprises.do_entreprise_correspondant_list(
+ self, args={"entreprise_corresp_id": entreprise_corresp_id}
)[0]
H = [
- self.entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"),
+ entreprise_header(self, REQUEST=REQUEST, page_title="Suivi entreprises"),
"""Édition contact entreprise """,
]
tf = TrivialFormulator(
@@ -829,7 +675,9 @@ class ZEntreprises(
cancelbutton="Annuler",
initvalues=c,
submitlabel="Modifier les valeurs",
- readonly=REQUEST["_read_only"],
+ readonly=not REQUEST.AUTHENTICATED_USER.has_permission(
+ ScoEntrepriseChange, self
+ ),
)
if tf[0] == 0:
H.append(tf[1])
@@ -839,21 +687,23 @@ class ZEntreprises(
% (REQUEST.URL1, c["entreprise_id"])
)
else:
- self.do_entreprise_correspondant_edit(tf[2])
+ sco_entreprises.do_entreprise_correspondant_edit(self, tf[2])
REQUEST.RESPONSE.redirect(
"%s/entreprise_correspondant_list?entreprise_id=%s"
% (REQUEST.URL1, c["entreprise_id"])
)
- H.append(self.entreprise_footer(REQUEST))
+ H.append(entreprise_footer(self, REQUEST))
return "\n".join(H)
security.declareProtected(ScoEntrepriseChange, "entreprise_contact_create")
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}
+ E = sco_entreprises.do_entreprise_list(
+ self, args={"entreprise_id": entreprise_id}
+ )[0]
+ correspondants = sco_entreprises.do_entreprise_correspondant_listnames(
+ self, args={"entreprise_id": entreprise_id}
)
if not correspondants:
correspondants = [("inconnu", "")]
@@ -863,7 +713,7 @@ class ZEntreprises(
% (REQUEST.URL1, entreprise_id)
)
H = [
- self.entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"),
+ entreprise_header(self, REQUEST=REQUEST, page_title="Suivi entreprises"),
""""""
% E,
]
@@ -934,32 +784,36 @@ class ZEntreprises(
),
cancelbutton="Annuler",
submitlabel="Ajouter ce contact",
- readonly=REQUEST["_read_only"],
+ readonly=not REQUEST.AUTHENTICATED_USER.has_permission(
+ ScoEntrepriseChange, self
+ ),
)
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"])
+ etudok = sco_entreprises.do_entreprise_check_etudiant(
+ self, 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])
+ sco_entreprises.do_entreprise_contact_create(self, tf[2])
REQUEST.RESPONSE.redirect(REQUEST.URL1)
- H.append(self.entreprise_footer(REQUEST))
+ H.append(entreprise_footer(self, REQUEST))
return "\n".join(H)
security.declareProtected(ScoEntrepriseChange, "entreprise_contact_delete")
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}
+ c = sco_entreprises.do_entreprise_contact_list(
+ self, args={"entreprise_contact_id": entreprise_contact_id}
)[0]
H = [
- self.entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"),
+ entreprise_header(self, REQUEST=REQUEST, page_title="Suivi entreprises"),
"""Suppression du contact """,
]
tf = TrivialFormulator(
@@ -969,25 +823,31 @@ class ZEntreprises(
initvalues=c,
submitlabel="Confirmer la suppression",
cancelbutton="Annuler",
- readonly=REQUEST["_read_only"],
+ readonly=not REQUEST.AUTHENTICATED_USER.has_permission(
+ ScoEntrepriseChange, self
+ ),
)
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"])
+ sco_entreprises.do_entreprise_contact_delete(
+ self, c["entreprise_contact_id"]
+ )
REQUEST.RESPONSE.redirect(REQUEST.URL1)
- H.append(self.entreprise_footer(REQUEST))
+ H.append(entreprise_footer(self, REQUEST))
return "\n".join(H)
security.declareProtected(ScoEntrepriseChange, "entreprise_correspondant_create")
def entreprise_correspondant_create(self, entreprise_id, REQUEST=None):
"""Form création correspondant"""
- E = self.do_entreprise_list(args={"entreprise_id": entreprise_id})[0]
+ E = sco_entreprises.do_entreprise_list(
+ self, args={"entreprise_id": entreprise_id}
+ )[0]
H = [
- self.entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"),
+ entreprise_header(self, REQUEST=REQUEST, page_title="Suivi entreprises"),
""""""
% E,
]
@@ -1070,27 +930,29 @@ class ZEntreprises(
),
cancelbutton="Annuler",
submitlabel="Ajouter ce correspondant",
- readonly=REQUEST["_read_only"],
+ readonly=not REQUEST.AUTHENTICATED_USER.has_permission(
+ ScoEntrepriseChange, self
+ ),
)
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])
+ sco_entreprises.do_entreprise_correspondant_create(self, tf[2])
REQUEST.RESPONSE.redirect(REQUEST.URL1)
- H.append(self.entreprise_footer(REQUEST))
+ H.append(entreprise_footer(self, REQUEST))
return "\n".join(H)
security.declareProtected(ScoEntrepriseChange, "entreprise_correspondant_delete")
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}
+ c = sco_entreprises.do_entreprise_correspondant_list(
+ self, args={"entreprise_corresp_id": entreprise_corresp_id}
)[0]
H = [
- self.entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"),
+ entreprise_header(self, REQUEST=REQUEST, page_title="Suivi entreprises"),
"""Suppression du correspondant %(nom)s %(prenom)s """ % c,
]
tf = TrivialFormulator(
@@ -1100,32 +962,38 @@ class ZEntreprises(
initvalues=c,
submitlabel="Confirmer la suppression",
cancelbutton="Annuler",
- readonly=REQUEST["_read_only"],
+ readonly=not REQUEST.AUTHENTICATED_USER.has_permission(
+ ScoEntrepriseChange, self
+ ),
)
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"])
+ sco_entreprises.do_entreprise_correspondant_delete(
+ self, c["entreprise_corresp_id"]
+ )
REQUEST.RESPONSE.redirect(REQUEST.URL1)
- H.append(self.entreprise_footer(REQUEST))
+ H.append(entreprise_footer(self, REQUEST))
return "\n".join(H)
security.declareProtected(ScoEntrepriseChange, "entreprise_delete")
def entreprise_delete(self, entreprise_id, REQUEST=None):
"""Form delete entreprise"""
- E = self.do_entreprise_list(args={"entreprise_id": entreprise_id})[0]
+ E = sco_entreprises.do_entreprise_list(
+ self, args={"entreprise_id": entreprise_id}
+ )[0]
H = [
- self.entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"),
+ entreprise_header(self, 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}
+ Cl = sco_entreprises.do_entreprise_correspondant_list(
+ self, args={"entreprise_id": entreprise_id}
)
if Cl:
H.append(
@@ -1135,7 +1003,9 @@ class ZEntreprises(
H.append("""%(nom)s %(prenom)s (%(fonction)s) """ % c)
H.append("""""")
- Cts = self.do_entreprise_contact_list(args={"entreprise_id": entreprise_id})
+ Cts = sco_entreprises.do_entreprise_contact_list(
+ self, args={"entreprise_id": entreprise_id}
+ )
if Cts:
H.append(
"""Contacts avec l'entreprise qui seront supprimés : """
@@ -1150,233 +1020,27 @@ class ZEntreprises(
initvalues=E,
submitlabel="Confirmer la suppression",
cancelbutton="Annuler",
- readonly=REQUEST["_read_only"],
+ readonly=not REQUEST.AUTHENTICATED_USER.has_permission(
+ ScoEntrepriseChange, self
+ ),
)
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"])
+ sco_entreprises.do_entreprise_delete(self, E["entreprise_id"])
REQUEST.RESPONSE.redirect(REQUEST.URL1)
- H.append(self.entreprise_footer(REQUEST))
+ H.append(entreprise_footer(self, REQUEST))
return "\n".join(H)
- # --------------------------------------------------------------------
- #
- # Entreprises : Actions
- #
- # --------------------------------------------------------------------
- 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)
-
- security.declareProtected(
- ScoEntrepriseView, "do_entreprise_correspondant_listnames"
- )
-
- 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 = ['']
- for x in r:
- e.append(
- "%s %s (code %s) "
- % (scu.strupper(x[1]), x[2] or "", x[0].strip())
- )
- e.append(" ")
- return (
- 0,
- "Les étudiants suivants correspondent: préciser le nom complet ou le code\n"
- + "\n".join(e),
- )
- else: # une seule reponse !
- return 1, r[0][0].strip()
-
- security.declareProtected(ScoEntrepriseView, "do_entreprise_list_by_contact")
-
- def do_entreprise_list_by_contact(
- self, args={}, operator="and", test="=", sortkey=None
- ):
- """Recherche dans entreprises, avec date de contact"""
- # (fonction ad-hoc car requete sur plusieurs tables)
- raise NotImplementedError
- # XXXXX fonction non achevee , non testee...
-
- # cnx = self.GetDBConnexion()
- # cursor = cnx.cursor(cursor_factory=ScoDocCursor)
- # if sortkey:
- # orderby = " order by " + sortkey
- # else:
- # orderby = ""
- # vals = dictfilter(args, self.dbfields)
- # # DBSelect
- # what = ["*"]
- # operator = " " + operator + " "
- # cond = " E.entreprise_id = C.entreprise_id "
- # if vals:
- # cond += " where " + operator.join(
- # ["%s%s%%(%s)s" % (x, test, x) for x in vals.keys() if vals[x] != None]
- # )
- # cnuls = " and ".join(
- # ["%s is NULL" % x for x in vals.keys() if vals[x] is None]
- # )
- # if cnuls:
- # cond = cond + " and " + cnuls
- # else:
- # cond += ""
- # cursor.execute(
- # "select distinct"
- # + ", ".join(what)
- # + " from entreprises E, entreprise_contact C "
- # + cond
- # + orderby,
- # vals,
- # )
- # titles, res = [x[0] for x in cursor.description], cursor.fetchall()
- # #
- # R = []
- # for r in res:
- # d = {}
- # for i in range(len(titles)):
- # v = r[i]
- # # value not formatted ! (see EditableTable.list())
- # d[titles[i]] = v
- # R.append(d)
- # return R
-
# -------- Formulaires: traductions du DTML
security.declareProtected(ScoEntrepriseChange, "entreprise_create")
def entreprise_create(self, REQUEST=None):
"""Form. création entreprise"""
- context = self
H = [
- self.entreprise_header(REQUEST, page_title="Création d'une entreprise"),
+ entreprise_header(self, REQUEST, page_title="Création d'une entreprise"),
"""Création d'une entreprise """,
]
tf = TrivialFormulator(
@@ -1451,26 +1115,29 @@ class ZEntreprises(
),
cancelbutton="Annuler",
submitlabel="Ajouter cette entreprise",
- readonly=REQUEST["_read_only"],
+ readonly=not REQUEST.AUTHENTICATED_USER.has_permission(
+ ScoEntrepriseChange, self
+ ),
)
if tf[0] == 0:
- return "\n".join(H) + tf[1] + context.entreprise_footer(REQUEST)
+ return "\n".join(H) + tf[1] + entreprise_footer(self, REQUEST)
elif tf[0] == -1:
return REQUEST.RESPONSE.redirect(REQUEST.URL1)
else:
- self.do_entreprise_create(tf[2])
+ sco_entreprises.do_entreprise_create(self, tf[2])
return REQUEST.RESPONSE.redirect(REQUEST.URL1)
security.declareProtected(ScoEntrepriseView, "entreprise_edit")
def entreprise_edit(self, entreprise_id, REQUEST=None, start=1):
"""Form. edit entreprise"""
- context = self
authuser = REQUEST.AUTHENTICATED_USER
readonly = not authuser.has_permission(ScoEntrepriseChange, self)
- F = self.do_entreprise_list(args={"entreprise_id": entreprise_id})[0]
+ F = sco_entreprises.do_entreprise_list(
+ self, args={"entreprise_id": entreprise_id}
+ )[0]
H = [
- self.entreprise_header(REQUEST, page_title="Entreprise"),
+ entreprise_header(self, REQUEST, page_title="Entreprise"),
"""%(nom)s """ % F,
]
tf = TrivialFormulator(
@@ -1555,11 +1222,11 @@ class ZEntreprises(
if tf[0] == 0:
H.append(tf[1])
- Cl = self.do_entreprise_correspondant_list(
- args={"entreprise_id": F["entreprise_id"]}
+ Cl = sco_entreprises.do_entreprise_correspondant_list(
+ self, args={"entreprise_id": F["entreprise_id"]}
)
- Cts = self.do_entreprise_contact_list(
- args={"entreprise_id": F["entreprise_id"]}
+ Cts = sco_entreprises.do_entreprise_contact_list(
+ self, args={"entreprise_id": F["entreprise_id"]}
)
if not readonly:
H.append(
@@ -1628,9 +1295,9 @@ class ZEntreprises(
H.append("(%s)" % c["description"])
H.append("")
H.append(" ")
- return "\n".join(H) + context.entreprise_footer(REQUEST)
+ return "\n".join(H) + entreprise_footer(self, REQUEST)
elif tf[0] == -1:
return REQUEST.RESPONSE.redirect(REQUEST.URL1 + "?start=" + start)
else:
- self.do_entreprise_edit(tf[2])
+ sco_entreprises.do_entreprise_edit(self, tf[2])
return REQUEST.RESPONSE.redirect(REQUEST.URL1 + "?start=" + start)
diff --git a/ZScolar.py b/ZScolar.py
index c39d8bdc5..8d4307809 100644
--- a/ZScolar.py
+++ b/ZScolar.py
@@ -599,7 +599,7 @@ UE11 Découverte métiers (code UCOD46, 16 ECTS, Apo ')
FA.append('')
date = first_monday
- for jour in self.Absences.day_names():
+ for jour in sco_abs.day_names(self):
FA.append('%s ' % (date, jour))
date = date.next()
FA.append(" ")
diff --git a/sco_abs.py b/sco_abs.py
index 8d97d949e..21538e677 100644
--- a/sco_abs.py
+++ b/sco_abs.py
@@ -43,6 +43,11 @@ import sco_formsemestre
import sco_compute_moy
+def is_work_saturday(context):
+ "Vrai si le samedi est travaillé"
+ return int(context.get_preference("work_saturday"))
+
+
def MonthNbDays(month, year):
"returns nb of days in month"
if month > 7:
@@ -173,6 +178,39 @@ class ddmmyyyy:
# d = ddmmyyyy( '21/12/99' )
+def DateRangeISO(context, date_beg, date_end, workable=1):
+ """returns list of dates in [date_beg,date_end]
+ workable = 1 => keeps only workable days"""
+ if not date_beg:
+ raise ScoValueError("pas de date spécifiée !")
+ if not date_end:
+ date_end = date_beg
+ r = []
+ work_saturday = is_work_saturday(context)
+ cur = ddmmyyyy(date_beg, work_saturday=work_saturday)
+ end = ddmmyyyy(date_end, work_saturday=work_saturday)
+ while cur <= end:
+ if (not workable) or cur.iswork():
+ r.append(cur)
+ cur = cur.next()
+
+ return map(lambda x: x.ISO(), r)
+
+
+def day_names(context):
+ """Returns week day names.
+ If work_saturday property is set, include saturday
+ """
+ if is_work_saturday(context):
+ return ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"]
+ else:
+ return ["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi"]
+
+
+def next_iso_day(context, date):
+ "return date after date"
+ d = ddmmyyyy(date, fmt="iso", work_saturday=is_work_saturday(context))
+ return d.next().ISO()
def YearTable(
@@ -207,7 +245,7 @@ def YearTable(
events,
halfday,
dayattributes,
- context.is_work_saturday(),
+ is_work_saturday(context),
pad_width=pad_width,
)
)
diff --git a/sco_abs_views.py b/sco_abs_views.py
index 9ede1d384..a76e225a6 100644
--- a/sco_abs_views.py
+++ b/sco_abs_views.py
@@ -28,12 +28,16 @@
"""Pages HTML gestion absences
(la plupart portées du DTML)
"""
+import datetime
from stripogram import html2text, html2safehtml
+
from gen_tables import GenTable
-from notesdb import *
-from sco_utils import *
+from notesdb import DateISOtoDMY
+import sco_utils as scu
+from sco_exceptions import ScoValueError
+from sco_permissions import ScoAbsChange
from notes_log import log
import sco_groups
import sco_find_etud
@@ -58,7 +62,7 @@ def doSignaleAbsence(
etudid = etud["etudid"]
description_abs = description
- dates = context.DateRangeISO(datedebut, datefin)
+ dates = sco_abs.DateRangeISO(context, datedebut, datefin)
nbadded = 0
for jour in dates:
if demijournee == "2":
@@ -248,7 +252,7 @@ def doJustifAbsence(
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"]
description_abs = description
- dates = context.DateRangeISO(datedebut, datefin)
+ dates = sco_abs.DateRangeISO(context, datedebut, datefin)
nbadded = 0
for jour in dates:
if demijournee == "2":
@@ -371,7 +375,7 @@ def doAnnuleAbsence(
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"]
- dates = context.DateRangeISO(datedebut, datefin)
+ dates = sco_abs.DateRangeISO(context, datedebut, datefin)
nbadded = 0
for jour in dates:
if demijournee == "2":
@@ -506,7 +510,7 @@ def doAnnuleJustif(
"""Annulation d'une justification"""
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"]
- dates = context.DateRangeISO(datedebut0, datefin0)
+ dates = sco_abs.DateRangeISO(context, datedebut0, datefin0)
nbadded = 0
for jour in dates:
# Attention: supprime matin et après-midi
@@ -571,7 +575,7 @@ def EtatAbsences(context, REQUEST=None):
"""
- % (AnneeScolaire(REQUEST), datetime.datetime.now().strftime("%d/%m/%Y")),
+ % (scu.AnneeScolaire(REQUEST), datetime.datetime.now().strftime("%d/%m/%Y")),
context.sco_footer(REQUEST),
]
return "\n".join(H)
@@ -610,7 +614,7 @@ def CalAbs(context, REQUEST=None): # etud implied
# crude portage from 1999 DTML
etud = context.getEtudInfo(filled=1, REQUEST=REQUEST)[0]
etudid = etud["etudid"]
- anneescolaire = int(AnneeScolaire(REQUEST))
+ anneescolaire = int(scu.AnneeScolaire(REQUEST))
datedebut = str(anneescolaire) + "-08-31"
datefin = str(anneescolaire + 1) + "-07-31"
nbabs = context.CountAbs(etudid=etudid, debut=datedebut, fin=datefin)
@@ -693,7 +697,7 @@ def ListeAbsEtud(
En format 'text': texte avec liste d'absences (pour mails).
"""
absjust_only = int(absjust_only) # si vrai, table absjust seule (export xls ou pdf)
- datedebut = "%s-08-31" % AnneeScolaire(REQUEST)
+ datedebut = "%s-08-31" % scu.AnneeScolaire(REQUEST)
etud = context.getEtudInfo(etudid=etudid, filled=True)[0]
@@ -714,7 +718,7 @@ def ListeAbsEtud(
html_class="table_leftalign",
table_id="tab_absnonjust",
base_url=base_url_nj,
- filename="abs_" + make_filename(etud["nomprenom"]),
+ filename="abs_" + scu.make_filename(etud["nomprenom"]),
caption="Absences non justifiées de %(nomprenom)s" % etud,
preferences=context.get_preferences(),
)
@@ -725,7 +729,7 @@ def ListeAbsEtud(
html_class="table_leftalign",
table_id="tab_absjust",
base_url=base_url_j,
- filename="absjust_" + make_filename(etud["nomprenom"]),
+ filename="absjust_" + scu.make_filename(etud["nomprenom"]),
caption="Absences justifiées de %(nomprenom)s" % etud,
preferences=context.get_preferences(),
)
@@ -830,7 +834,7 @@ def absences_index_html(context, REQUEST=None):
% REQUEST.URL0,
formChoixSemestreGroupe(context),
"",
- context.CalSelectWeek(REQUEST=REQUEST),
+ cal_select_week(context, REQUEST=REQUEST),
"""Sélectionner le groupe d'étudiants, puis cliquez sur une semaine pour
saisir les absences de toute cette semaine.
""",
@@ -843,3 +847,16 @@ saisir les absences de toute cette semaine.
H.append(context.sco_footer(REQUEST))
return "\n".join(H)
+
+
+def cal_select_week(context, year=None, REQUEST=None):
+ "display calendar allowing week selection"
+ if not year:
+ year = scu.AnneeScolaire(REQUEST)
+ sems = sco_formsemestre.do_formsemestre_list(context)
+ if not sems:
+ js = ""
+ else:
+ js = 'onmouseover="highlightweek(this);" onmouseout="deselectweeks();" onclick="wclick(this);"'
+ C = sco_abs.YearTable(context, int(year), dayattributes=js)
+ return C
diff --git a/sco_entreprises.py b/sco_entreprises.py
new file mode 100644
index 000000000..fdbef5e55
--- /dev/null
+++ b/sco_entreprises.py
@@ -0,0 +1,326 @@
+# -*- 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
+#
+##############################################################################
+
+"""Fonctions sur les entreprises
+"""
+# codes anciens déplacés de ZEntreprise
+import datetime
+
+import sco_utils as scu
+from notesdb import ScoDocCursor, EditableTable, DateISOtoDMY, DateDMYtoISO
+
+
+def _format_nom(nom):
+ "formatte nom (filtre en entree db) d'une entreprise"
+ if not nom:
+ return nom
+ nom = nom.decode(scu.SCO_ENCODING)
+ return (nom[0].upper() + nom[1:]).encode(scu.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,
+ context=None,
+ limit="",
+ offset="",
+ ):
+ # list, then sort on date of last contact
+ R = EditableTable.list(
+ self,
+ cnx,
+ args=args,
+ operator=operator,
+ test=test,
+ sortkey=sortkey,
+ limit=limit,
+ offset=offset,
+ )
+ if sort_on_contact:
+ for r in R:
+ c = do_entreprise_contact_list(
+ context,
+ 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},
+)
+
+
+def do_entreprise_create(context, args):
+ "entreprise_create"
+ cnx = context.GetDBConnexion()
+ r = _entreprisesEditor.create(cnx, args)
+ return r
+
+
+def do_entreprise_delete(context, oid):
+ "entreprise_delete"
+ cnx = context.GetDBConnexion()
+ _entreprisesEditor.delete(cnx, oid)
+
+
+def do_entreprise_list(context, **kw):
+ "entreprise_list"
+ cnx = context.GetDBConnexion()
+ kw["context"] = context
+ return _entreprisesEditor.list(cnx, **kw)
+
+
+def do_entreprise_list_by_etud(context, **kw):
+ "entreprise_list_by_etud"
+ cnx = context.GetDBConnexion()
+ return _entreprisesEditor.list_by_etud(cnx, **kw)
+
+
+def do_entreprise_edit(context, *args, **kw):
+ "entreprise_edit"
+ cnx = context.GetDBConnexion()
+ _entreprisesEditor.edit(cnx, *args, **kw)
+
+
+def do_entreprise_correspondant_create(context, args):
+ "entreprise_correspondant_create"
+ cnx = context.GetDBConnexion()
+ r = _entreprise_correspEditor.create(cnx, args)
+ return r
+
+
+def do_entreprise_correspondant_delete(context, oid):
+ "entreprise_correspondant_delete"
+ cnx = context.GetDBConnexion()
+ _entreprise_correspEditor.delete(cnx, oid)
+
+
+def do_entreprise_correspondant_list(context, **kw):
+ "entreprise_correspondant_list"
+ cnx = context.GetDBConnexion()
+ return _entreprise_correspEditor.list(cnx, **kw)
+
+
+def do_entreprise_correspondant_edit(context, *args, **kw):
+ "entreprise_correspondant_edit"
+ cnx = context.GetDBConnexion()
+ _entreprise_correspEditor.edit(cnx, *args, **kw)
+
+
+def do_entreprise_correspondant_listnames(context, args={}):
+ "-> liste des noms des correspondants (pour affichage menu)"
+ C = do_entreprise_correspondant_list(context, args=args)
+ return [(x["prenom"] + " " + x["nom"], str(x["entreprise_corresp_id"])) for x in C]
+
+
+def do_entreprise_contact_delete(context, oid):
+ "entreprise_contact_delete"
+ cnx = context.GetDBConnexion()
+ _entreprise_contactEditor.delete(cnx, oid)
+
+
+def do_entreprise_contact_list(context, **kw):
+ "entreprise_contact_list"
+ cnx = context.GetDBConnexion()
+ return _entreprise_contactEditor.list(cnx, **kw)
+
+
+def do_entreprise_contact_edit(context, *args, **kw):
+ "entreprise_contact_edit"
+ cnx = context.GetDBConnexion()
+ _entreprise_contactEditor.edit(cnx, *args, **kw)
+
+
+def do_entreprise_contact_create(context, args):
+ "entreprise_contact_create"
+ cnx = context.GetDBConnexion()
+ r = _entreprise_contactEditor.create(cnx, args)
+ return r
+
+
+def do_entreprise_check_etudiant(context, 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 = context.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 = ['']
+ for x in r:
+ e.append(
+ "%s %s (code %s) "
+ % (scu.strupper(x[1]), x[2] or "", x[0].strip())
+ )
+ e.append(" ")
+ return (
+ 0,
+ "Les étudiants suivants correspondent: préciser le nom complet ou le code\n"
+ + "\n".join(e),
+ )
+ else: # une seule reponse !
+ return 1, r[0][0].strip()
\ No newline at end of file
diff --git a/sco_groups_view.py b/sco_groups_view.py
index 152ceb98e..fbc622205 100644
--- a/sco_groups_view.py
+++ b/sco_groups_view.py
@@ -30,8 +30,16 @@
"""
# Re-ecriture en 2014 (re-organisation de l'interface, modernisation du code)
+import datetime
+import cgi
+import urllib
+import time
+import collections
+import operator
-from sco_utils import *
+import sco_utils as scu
+from sco_permissions import ScoEtudInscrit, ScoEtudAddAnnotations, ScoAbsChange
+from sco_exceptions import ScoValueError
import html_sco_header
from gen_tables import GenTable
import scolars
@@ -441,8 +449,6 @@ def groups_table(
# "enter groups_table %s: %s"
# % (groups_infos.members[0]["nom"], groups_infos.members[0].get("etape", "-"))
# )
- authuser = REQUEST.AUTHENTICATED_USER
-
with_codes = int(with_codes)
with_paiement = int(with_paiement)
with_archives = int(with_archives)
@@ -891,7 +897,7 @@ def form_choix_jour_saisie_hebdo(
FA.append("""""")
date = first_monday
i = 0
- for jour in context.Absences.day_names():
+ for jour in sco_abs.day_names(context):
if i == today_idx:
sel = "selected"
else:
@@ -910,7 +916,6 @@ def form_choix_saisie_semaine(context, groups_infos, REQUEST=None):
authuser = REQUEST.AUTHENTICATED_USER
if not authuser.has_permission(ScoAbsChange, context):
return ""
- sem = groups_infos.formsemestre
# construit l'URL "destination"
# (a laquelle on revient apres saisie absences)
query_args = cgi.parse_qs(REQUEST.QUERY_STRING)