diff --git a/intranet/modules/gestionFactures/main.py b/intranet/modules/gestionFactures/main.py
new file mode 100755
index 00000000..b558dce4
--- /dev/null
+++ b/intranet/modules/gestionFactures/main.py
@@ -0,0 +1,140 @@
+#! /usr/bin/env python
+# -*- coding: iso-8859-15 -*-
+# ##################################################################################################### #
+# Factures (gestion)
+# ##################################################################################################### #
+# Description:
+# Permet de chercher dans les facture, d'en créditer et d'en supprimer
+# Informations:
+#
+# Pages:
+# index:afiche le formulaire et les factures
+#
+# ##################################################################################################### #
+import cherrypy, sys, os, datetime
+import crans.cp
+from ClassesIntranet.ModuleBase import ModuleBase
+
+class main(ModuleBase):
+ _droits = ["Imprimeur"]
+ def title(self):
+ return "Gestion factures"
+ def category(self):
+ return "Imprimeur"
+
+ def index(self, message = '', erreur = ''):
+ if cherrypy.session.has_key('gestion_factures-current_search'):
+ del cherrypy.session['gestion_factures-current_search']
+ return self.displayTemplate()
+ index.exposed = True
+
+ def search(self, fid=None, uid=None, aid=None):
+ cherrypy.session['gestion_factures-current_search'] = {
+ "fid":fid,
+ "uid":uid,
+ "aid":aid,
+ }
+ return self.displayTemplate()
+ search.exposed = True
+
+
+
+ def displayTemplate(self, message = '', erreur = ''):
+ t = {}
+ t['message'] = message
+ t['error'] = erreur
+ if cherrypy.session.has_key('gestion_factures-current_search'):
+ fid = cherrypy.session['gestion_factures-current_search']['fid']
+ uid = cherrypy.session['gestion_factures-current_search']['uid']
+ aid = cherrypy.session['gestion_factures-current_search']['aid']
+ t['listeFactures'] = self.buildInvoiceList(
+ fid = fid,
+ uid = uid,
+ aid = aid,
+ )
+
+ else:
+ fid = ""
+ uid = ""
+ aid = ""
+ t["form"] = []
+ t["form"]+= [{'name':'fid', 'label':'fid', 'value':fid}]
+ t["form"]+= [{'name':'uid', 'label':'login', 'value':uid}]
+ t["form"]+= [{'name':'aid', 'label':'aid', 'value':aid}]
+
+ return {
+ 'template' :'factures-gestion',
+ 'values' :t,
+ 'stylesheets' :['cransFactures.css'],
+ }
+
+
+
+
+ def buildInvoiceList(self, fid=None, uid=None, aid=None):
+ ############## liste des factures ##############
+ if fid:
+ search_string = "fid=%s" % str(fid)
+ liste_factures_ldap = cherrypy.session['LDAP'].search(search_string)['facture']
+ elif uid:
+ search_string = "uid=%s" % str(uid)
+ try:
+ liste_factures_ldap = cherrypy.session['LDAP'].search(search_string)['adherent'][0].factures()
+ except:
+ liste_factures_ldap = []
+ elif aid:
+ search_string = "aid=%s" % str(aid)
+ try:
+ liste_factures_ldap = cherrypy.session['LDAP'].search(search_string)['adherent'][0].factures()
+ except:
+ liste_factures_ldap = []
+ else:
+ return []
+ liste_factures_affichees = []
+ for f in liste_factures_ldap:
+ try:
+ facture = {}
+ facture['no'] = f.numero()
+ facture['adherent'] = f.proprietaire().mail()
+ facture['montant'] = f.total()
+ facture['payee'] = f.recuPaiement()
+ facture['intitule'] = f.articles()[0]['designation']
+ facture['details'] = [
+ {
+ 'intitule':art['designation'],
+ 'quantite':art['nombre'],
+ 'prixUnitaire':art['pu'],
+ 'prixTotal':art['pu']*art['nombre'],
+ } for art in f.articles()]
+ liste_factures_affichees.append(facture)
+ except:
+ crans.cp.log("Facture non affichable : fid=%s" % str(f.numero()), "GESTION FACTURES", 1)
+
+ return liste_factures_affichees
+
+ def delFacture(self, fid):
+ try:
+ # trrouver la factures
+ fact = cherrypy.session['LDAP'].search('fid=' + fid, 'w')['facture'][0]
+ # la supprimer
+ fact.delete()
+ except Exception, e:
+ crans.cp.log(unicode(e), "GESTION FACTURES", 1)
+ return self.index(erreur=u"Probleme lors de la suppression")
+ crans.cp.log(u"Facture supprimee [fid=%s]" % fid, "GESTION FACTURES")
+ return self.displayTemplate(message=u"Facture suprimée")
+ delFacture.exposed = True
+
+ def crediteFacture(self, fid):
+ try:
+ # trrouver la factures
+ fact = cherrypy.session['LDAP'].search('fid=' + fid, 'w')['facture'][0]
+ # la supprimer
+ fact.recuPaiement(cherrypy.session['uid'])
+ fact.save()
+ except Exception, e:
+ crans.cp.log("pb crédit", "GESTION FACTURES", 1)
+ return self.index(erreur=u"Problème lors du crédit")
+ crans.cp.log("Facture creditee [fid=%s]" % fid, "GESTION FACTURES")
+ return self.displayTemplate(message=u"Facture créditée")
+ crediteFacture.exposed = True
diff --git a/intranet/modules/gestionFactures/static/cransFactures.css b/intranet/modules/gestionFactures/static/cransFactures.css
new file mode 100644
index 00000000..cc230642
--- /dev/null
+++ b/intranet/modules/gestionFactures/static/cransFactures.css
@@ -0,0 +1,205 @@
+/********************************************
+ *
+********************************************/
+#globalDiv {
+ //padding-left:20%;
+ position: relative;
+}
+
+ul#actionMenu {
+ list-style-type:none;
+ width:18%;
+ padding:0;
+ float:left;
+}
+
+h1 {
+ font-size:1.4em;
+ margin:2px;
+}
+td, tr {
+ margin:0;
+}
+
+#factureListDiv {
+ padding:5px;
+ background:#fad163;
+ float:left;
+ width:75%;
+}
+
+#factureListDiv table#listeFactures {
+ padding:0;
+ width:100%;
+}
+
+.factureRow {
+ margin:2px;
+ position:relative;
+}
+
+.help_text {
+ background:#fff7D7;
+ font-weight:normal;
+ padding:10px 20px;
+
+}
+
+.factureRow .factureSummary {
+ background:#fff7D7;
+ height:30px;
+ font-weight:bold;
+ padding:10px 20px;
+}
+
+.factureRow .factureSummary span.intitule {
+ float:left;
+}
+
+.factureRow .factureSummary span.montant {
+ float:right;
+ text-align:right;
+}
+
+.tdNoFactures {
+ text-align:center;
+ font-size:1.2em;
+ background-color:#fff7D7;
+ color:#666;
+ margin:0;
+ padding:5px;
+}
+
+.facturePayee {
+}
+.factureNonPayee .factureSummary {
+ color:red;
+}
+
+
+.actions {
+ display:block;
+ float:right;
+ font-size:0.9em;
+ font-weight:normal;
+}
+.actions a {
+ margin:2px 10px;
+}
+
+/********************************************
+ *
+********************************************/
+
+table.factureDetails {
+ background: #fff7D7 url(fondFacturesDetails.png) repeat-x top;
+ padding:1%;
+ width:96%;
+ margin:0 1% 10px 1%;
+}
+
+.tdTotalDetail,
+.tdTotalDetailIntitule {
+ border-top:thin black solid;
+}
+
+.tdTotalDetailIntitule {
+ text-align:right;
+ font-weight:bold;
+}
+
+table.factureDetails th {
+ border-bottom:thin black solid;
+}
+table.factureDetails th,
+table.factureDetails td {
+ border-right:thin black solid;
+ margin:0;
+ padding:5px 20px;
+}
+
+/********************************************
+ *
+********************************************/
+.note {
+ display:block;
+ font-size:small;
+ margin:3px;
+ font-weight:normal;
+}
+.note {
+ color:#666
+}
+
+.linkToggle {
+ display:block;
+ float:left;
+ height:15px;
+ width:15px;
+ background:transparent url(fl.png) top left;
+ margin-right:1px;
+}
+
+/********************************************
+ *
+********************************************/
+
+table#historique_sous {
+ width:100%;
+}
+
+table#historique_sous td {
+ background:#fff7D7;
+ padding:5px;
+ text-align:center;
+ border-top:2px #fad163 solid;
+}
+
+table#historique_sous th {
+ background:#fff7D7;
+ padding:5px;
+ text-decoration:underline;
+}
+
+/********************************************
+ *
+********************************************/
+
+form.search {
+ display:block;
+ border: thin black solid;
+ padding:.2em 1em;
+ float:left;
+ //position:absolute;
+ width:18%;
+ //top:0;
+ //left:0;
+ margin:0 1%;
+}
+
+form.search input {
+ max-width:95%;
+ margin:.3em;
+ float:left;
+ border: thin gray solid;
+}
+
+form.search label {
+ padding-top:7px;
+ display:block;
+ width:4em;
+ float:left;
+ clear:left;
+font-weight:bold;
+}
+
+form.search h3 {
+ margin:.2em 0;
+}
+
+form.search input.button {
+ margin:.5em;
+ text-align:center;
+ clear:left;
+}
+
diff --git a/intranet/modules/gestionFactures/static/fl.png b/intranet/modules/gestionFactures/static/fl.png
new file mode 100644
index 00000000..2c72f9ea
Binary files /dev/null and b/intranet/modules/gestionFactures/static/fl.png differ
diff --git a/intranet/modules/gestionFactures/static/fondFacturesDetails.png b/intranet/modules/gestionFactures/static/fondFacturesDetails.png
new file mode 100644
index 00000000..b747a69c
Binary files /dev/null and b/intranet/modules/gestionFactures/static/fondFacturesDetails.png differ
diff --git a/intranet/modules/gestionFactures/static/icon.png b/intranet/modules/gestionFactures/static/icon.png
new file mode 100644
index 00000000..efe29dd9
Binary files /dev/null and b/intranet/modules/gestionFactures/static/icon.png differ
diff --git a/intranet/modules/gestionFactures/templates/factures-historique.tmpl b/intranet/modules/gestionFactures/templates/factures-historique.tmpl
new file mode 100644
index 00000000..065725d9
--- /dev/null
+++ b/intranet/modules/gestionFactures/templates/factures-historique.tmpl
@@ -0,0 +1,45 @@
+
diff --git a/intranet/modules/gestionFactures/templates/factures.tmpl b/intranet/modules/gestionFactures/templates/factures.tmpl
new file mode 100644
index 00000000..7551fcc8
--- /dev/null
+++ b/intranet/modules/gestionFactures/templates/factures.tmpl
@@ -0,0 +1,107 @@
+
+
+
+
+
Mes factures PayPal
+
+ #for f in $listeFactures
+ #if $f.payee
+
+ #else
+
+ #end if
+
+
+ #if $f.details.__len__() > 1
+
+ #end if
+ $f.intitule
+ #if not $f.payee
+ (non payée)
+ #end if
+
+
+
+ $f.montant €
+
+
Crée le -
+ #if not $f.payee
+
+ Annuler
+ Payer avec PayPal
+
+ #else
+
Payée
+ #end if
+
+
+ #if $f.details.__len__() > 1
+
+
+
+ Description |
+ Prix unitaire |
+ Quantité |
+ total |
+
+ #for unDetail in $f.details
+
+ $unDetail.intitule |
+ $unDetail.prixUnitaire € |
+ $unDetail.quantite |
+ $unDetail.prixTotal € |
+
+ #end for
+
+
+ Total
+ |
+ $f.montant € |
+
+
+
+
+ #end if
+ #end for
+
+ #if $listeFactures == []
+
+ AUCUNE TRANSACTION PAYPAL ENREGISTRÉE
+
+ #end if
+
+
+
diff --git a/intranet/modules/impression/main.py b/intranet/modules/impression/main.py
new file mode 100755
index 00000000..deb384b0
--- /dev/null
+++ b/intranet/modules/impression/main.py
@@ -0,0 +1,237 @@
+#!/usr/bin/env python
+# -*- coding: iso-8859-15 -*-
+# #############################################################
+# ..
+# .... ............ ........
+# . ....... . .... ..
+# . ... .. .. .. .. ..... . ..
+# .. .. ....@@@. .. . ........ .
+# .. . .. ..@.@@..@@. .@@@@@@@ @@@@@@. ....
+# .@@@@. .@@@@. .@@@@..@@.@@..@@@..@@@..@@@@.... ....
+# @@@@... .@@@.. @@ @@ .@..@@..@@...@@@. .@@@@@. ..
+# .@@@.. . @@@. @@.@@..@@.@@..@@@ @@ .@@@@@@.. .....
+# ...@@@.... @@@ .@@.......... ........ ..... ..
+# . ..@@@@.. . .@@@@. .. ....... . .............
+# . .. .... .. .. . ... ....
+# . . .... ............. .. ...
+# .. .. ... ........ ... ...
+# ................................
+#
+# #############################################################
+#
+# interface d'impression
+#
+# Copyright (c) 2006 by www.crans.org
+# #############################################################
+
+import cherrypy, tempfile, shutil, os
+import crans.impression
+import crans.impression.digicode
+import crans.impression.etat_imprimante
+import crans.cp
+FILE_UPLOAD_BASE_FOLDER = cherrypy.config.get('fileUpload.folder', "/var/impression/fichiers/")
+
+class FileError(Exception):
+ pass
+from ClassesIntranet.ModuleBase import ModuleBase
+
+class main(ModuleBase):
+ def category(self):
+ return "Services"
+ def title(self):
+ return "Impression"
+ def icon(self):
+ return "icon.png"
+
+
+ ##########################
+ # affichage
+ ##########################
+ #
+ # template principale
+ #
+ def index(self, submit = None, fileList = None, newFile = None ):
+ data = {}
+ # on efface un eventuel objet impression existant
+ cherrypy.session['impression'] = None
+ if submit == "Envoyer":
+ try:
+ self.savePDF(newFile)
+ data['fileName'] = newFile.filename
+ except FileError, e:
+ data['openError'] = e.args[0]
+ elif submit == "Choisir":
+ if (fileList):
+ data['fileName'] = fileList
+ else:
+ data['openError'] = "Choisissez un fichier"
+
+ data['fileList'] = self.getUploadedFileListFor(cherrypy.session['uid'])
+ try:
+ crans.impression.etat_imprimante.etat()
+ except Exception, e:
+ data['Erreur_imprimante'] = str(e).replace("\"", "\\\"")
+ data['errorMsg'] = u"Imprimante injoignable"
+ if not cherrypy.config.get('crans.activate', True):
+ data['Erreur_imprimante'] = "Config impression"
+ data['errorMsg'] = cherrypy.config.get('crans.activate.errorMsg', u"Imprimante HS")
+ return {'template':'impression',
+ 'values':data,
+ 'stylesheets':['impression.css'],
+ 'scripts':['impression.js', 'popup.js'],
+ }
+ index.exposed = True
+
+ ##########################
+ # devis
+ ##########################
+ #
+ # methode qui affiche la template du devis
+ #
+
+ def devis(self):
+ return {
+ 'template':'impression-devis',
+ 'values':
+ {
+ 'devis':cherrypy.session['impression'].devisDetaille(),
+ 'total':cherrypy.session['impression'].prix(),
+ 'nomFichier':cherrypy.session['impression'].fileName(),
+ },
+ 'standalone':True,
+ }
+ devis.exposed=True
+
+
+ ##########################
+ # AJAX
+ ##########################
+ #
+ # methode qui renvoie la liste des codes de l'adherent
+ #
+ def codeList(self):
+ try:
+ listeBrute = crans.impression.digicode.list_code()
+ # liste de la forme :
+ # [(code, age, description),...]
+ listeBrute = [item[0] for item in listeBrute if item[2] == cherrypy.session['uid']]
+ return {'codes': listeBrute}
+ except Exception, e:
+ crans.cp.log('erreur lors de la creation de la liste de codes :' + str(e), 'IMPRESSION', 1)
+ return {'erreur':str(e)}
+ codeList.exposed= True
+
+ #
+ # methode qui indique quel fichier utiliser
+ #
+ def useFile(self, fileName):
+ try:
+ filepath = os.path.join(os.path.join(FILE_UPLOAD_BASE_FOLDER, cherrypy.session['uid']+"/"), fileName)
+ cherrypy.session['impression'] = crans.impression.impression(filepath, cherrypy.session['uid'])
+ return {'nbPages': cherrypy.session['impression'].pages()}
+ except crans.impression.FichierInvalide, e:
+ crans.cp.log("useFile : %s (%s)" % (str(e), e.file()), 'IMPRESSION', 1)
+ return {'erreur':str(e) }
+ except Exception, e:
+ crans.cp.log("useFile : %s" % str(e), 'IMPRESSION', 1)
+ return {'erreur':str(e) }
+ useFile.exposed= True
+
+
+ #
+ # methode pour changer les parametres
+ #
+ def changeSettings(self, copies=None, couleurs=None, recto_verso=None, agrafes=None, papier=None):
+ try:
+ nouvPrix = cherrypy.session['impression'].changeSettings(papier=papier, couleurs=couleurs, agraphes=agrafes, recto_verso=recto_verso, copies=int(copies))
+ except Exception, e:
+ crans.cp.log("changeSettings : %s" % str(e), 'IMPRESSION', 1)
+ return {"erreur":str(e)}
+ return {'nouvPrix':nouvPrix}
+ changeSettings.exposed = True
+
+
+ #
+ # methode pour lancer l'impression
+ #
+ def lancerImpression(self):
+ try:
+ cherrypy.session['impression'].imprime()
+ except crans.impression.SoldeInsuffisant:
+ return {"SoldeInsuffisant":1}
+ except Exception, e:
+ crans.cp.log("lancerImpression : %s" % str(e), 'IMPRESSION', 1)
+ return {"erreur":str(e)}
+ crans.cp.log("impression", 'IMPRESSION')
+ return {'code':str(crans.impression.digicode.gen_code(cherrypy.session['uid'])) + "#"}
+ lancerImpression.exposed = True
+
+ #
+ # methode pour recuperer l'etat de l'imprimante
+ #
+ def etatImprimante(self):
+ if not cherrypy.config.get('crans.activate', True):
+ return {"printer_state" : u"Système down"}
+ try:
+ return {"printer_state" : u"\\n".join(crans.impression.etat_imprimante.etat())}
+ except Exception, e:
+ return {"printer_state" : 'Imprimante hors ligne'}
+ etatImprimante.exposed = True
+
+ #
+ # methode pour le solde
+ #
+ def AJAXGetSolde(self):
+ try:
+ adh = cherrypy.session['LDAP'].search('uid=' + cherrypy.session['uid'])['adherent'][0]
+ return {"solde" : adh.solde() }
+ except Exception, e:
+ return {"erreur" : str(e)}
+ AJAXGetSolde.exposed = True
+
+
+
+
+ ##########################
+ # privees
+ ##########################
+ #
+ # methode pour obtenir la liste des fichiers uploadés
+ #
+ def getUploadedFileListFor(self, adh):
+ file_folder = os.path.join(FILE_UPLOAD_BASE_FOLDER, cherrypy.session['uid']+"/")
+ if not os.path.isdir(file_folder):
+ return []
+ return os.listdir(file_folder)
+
+
+ #
+ # methode pour enregistrer un fichier
+ #
+ def savePDF(self, aFile):
+
+ _, tempFileName = tempfile.mkstemp()
+ f = open(tempFileName, 'w+b')
+ size=0
+ while True:
+ data = aFile.file.read(1024 * 8) # Read blocks of 8KB at a time
+ if not data:
+ break
+ f.write(data)
+ size += len(data)
+ f.close()
+ if size == 0:
+ raise FileError("Fichier vide")
+
+ file_folder = os.path.join(FILE_UPLOAD_BASE_FOLDER, cherrypy.session['uid']+"/")
+ if not os.path.isdir(file_folder):
+ os.makedirs(file_folder)
+ newFilePath = os.path.join(file_folder, aFile.filename)
+ shutil.move(tempFileName, newFilePath)
+ crans.cp.log("New file uploaded at : %s" % newFilePath, "IMPRESSION")
+ return newFilePath
+
+
+
+
+
diff --git a/intranet/modules/impression/static/WindowTitleLogo.png b/intranet/modules/impression/static/WindowTitleLogo.png
new file mode 100644
index 00000000..d704d48e
Binary files /dev/null and b/intranet/modules/impression/static/WindowTitleLogo.png differ
diff --git a/intranet/modules/impression/static/dialog-printer.png b/intranet/modules/impression/static/dialog-printer.png
new file mode 100644
index 00000000..e812c880
Binary files /dev/null and b/intranet/modules/impression/static/dialog-printer.png differ
diff --git a/intranet/modules/impression/static/dialog-solde.png b/intranet/modules/impression/static/dialog-solde.png
new file mode 100644
index 00000000..a6cd9dd8
Binary files /dev/null and b/intranet/modules/impression/static/dialog-solde.png differ
diff --git a/intranet/modules/impression/static/dialog-warning.png b/intranet/modules/impression/static/dialog-warning.png
new file mode 100644
index 00000000..632f99a3
Binary files /dev/null and b/intranet/modules/impression/static/dialog-warning.png differ
diff --git a/intranet/modules/impression/static/icon.png b/intranet/modules/impression/static/icon.png
new file mode 100644
index 00000000..efe62510
Binary files /dev/null and b/intranet/modules/impression/static/icon.png differ
diff --git a/intranet/modules/impression/static/impression.css b/intranet/modules/impression/static/impression.css
new file mode 100644
index 00000000..09f330ea
--- /dev/null
+++ b/intranet/modules/impression/static/impression.css
@@ -0,0 +1,162 @@
+/* ****************************************** *
+ *
+ * ****************************************** */
+#globalDiv {
+ padding-left:200px;
+ position: relative;
+}
+
+ul#actionMenu {
+ list-style-type:none;
+ position:absolute;
+ width:150px;
+ top:0;
+ left:0;
+ margin:20px;
+ padding:0;
+}
+ul#actionMenu li {
+ clear:both;
+}
+/* ****************************************** *
+ *
+ * ****************************************** */
+#fileName {
+ display: block;
+ width:150px;
+ text-align:center;
+ padding:50px 5px 5px 5px;
+ background: url(../images/pdf-icon.png) center top no-repeat;
+ margin:0 0 10px 0;
+ overflow:auto;
+}
+
+#actionMenu li {
+ margin: .8em 0;
+}
+
+#actionEtatImprimante {
+ padding:0.4em;
+ border: thin black solid;
+}
+
+/* ******************************************* *
+ *
+ * ******************************************* */
+form#form_impression {
+ margin: 0px;
+ font-size: 100%;
+ min-width:600px;
+}
+form#form_impression #preview {
+ border:1px black solid;
+ width:150px;
+ height:150px;
+ padding:10px;
+ background-color:#C0C0C0;
+}
+
+form#form_impression #rightColumn {
+ margin:10px 10px 10px 240px;
+}
+
+form#form_impression #leftColumn {
+ float:left;
+ width:170px;
+ margin:10px;
+ padding:0;
+}
+div#prix_placeholder {
+ margin:6px 0;
+ width:170px;
+ min-height:16px;
+ padding:0;
+ color:gray;
+}
+div#prix_placeholder img {
+ margin-right:2px;
+ float:right;
+}
+form#form_impression fieldset fieldset {
+ margin:10px;
+}
+form#form_impression>fieldset {
+ position:relative;
+ padding:20px;
+}
+
+.clear {
+ clear:both;
+}
+
+form#form_impression .bouttons {
+ text-align:right;
+}
+form#form_impression label.labelInput {
+ display:block;
+ width:4em;
+ margin-right:4px;
+ float:left;
+ text-align:right;
+}
+
+/* ****************************************** *
+ *
+ * ****************************************** */
+#popupFichiers {
+ background:#AE0F3E;
+ z-index:500;
+ float:left;
+ position:fixed;
+ min-width:450px;
+ top:110px;
+ left:20%;
+ right:20%;
+ padding:0;
+}
+#popupFichiers #insideDiv {
+ background:white;
+ margin:2px 5px;
+}
+#popupFichiers #insideDiv form {
+ margin:2px 5px;
+}
+#popupFichiers h1 {
+ font-size:1em;
+ margin:0;
+ text-align:center;
+ color:white;
+}
+#popupFichiers h1:before {
+ content:url("../images/WindowTitleLogo.png");
+ margin-right:5px;
+}
+
+#popupFichiers h2 {
+ font-size:1.1em;
+ border-bottom:thin black solid;
+}
+#popupFichiers select,
+#popupFichiers input.file {
+ width:100%;
+}
+
+.button {
+ float:right;
+}
+
+/* ****************************************** *
+ *
+ * ****************************************** */
+div#printingPopupContent {
+ background: white url("../images/printer.png") left center no-repeat;;
+ padding:10px 10px 10px 115px;
+ min-height:100px;
+}
+
+#printingPopupContent a,
+#printingPopupContent span {
+ display:block;
+ font-weight: bold;
+ margin:5px 0;
+}
diff --git a/intranet/modules/impression/static/impression.js b/intranet/modules/impression/static/impression.js
new file mode 100644
index 00000000..298ab375
--- /dev/null
+++ b/intranet/modules/impression/static/impression.js
@@ -0,0 +1,404 @@
+/* ************************************************************
+ * Impression
+ ************************************************************
+ * Impression.settings : panneau de configuration
+ * Impression.popup : popup
+ * Impression.AJAX : ajax
+ */
+Impression = {};
+
+/*****************************
+ Impression.settings
+ *****************************/
+
+Impression.settings = {};
+
+ //
+//// images : images used for previewing
+//
+Impression.settings.images = [
+ "portrait_couleurs_agraphediagonale.png",
+ "portrait_couleurs_pasdagraphes.png",
+ "portrait_couleurs_uneagraphe.png",
+ "portrait_couleurs_Deuxagraphes.png",
+ "portrait_couleurs_troisAgraphes.png",
+ "portrait_couleurs_stitching.png",
+ "portrait_nb_agraphediagonale.png",
+ "portrait_nb_pasdagraphes.png",
+ "portrait_nb_uneagraphe.png",
+ "portrait_nb_Deuxagraphes.png",
+ "portrait_nb_troisAgraphes.png",
+ "portrait_nb_stitching.png",
+ "portrait_transparent_couleurs.png",
+ "portrait_transparent_nb.png",
+ ];
+
+Impression.settings.preloadImage = function(imageName) {
+ var image = new Image();
+ image.src = "/static/images/"+imageName;
+}
+
+Impression.settings.preloadAllImages = function() {
+ log("Preloading images...");
+ map(this.preloadImage,this.images);
+}
+
+ //
+//// init : parse every field and display preview
+//
+Impression.settings.init = function () {
+ log("Init settings...");
+ this.theform = document.form_impression;
+ this.disableForm(false);
+}
+ //
+//// reset : reset form and then re-init settings
+//
+Impression.settings.reset = function () {
+ log("Reset form");
+ this.theform.reset();
+ this.init();
+ Impression.settings.update();
+}
+
+Impression.settings.disableForm = function(bool)
+{
+ log("Set Disable Form : " + bool);
+ var fields = this.theform.elements;
+ for( var i=0; i< fields.length; i++)
+ {
+ this.setDisableField( fields[i], bool );
+ }
+}
+
+ //
+//// getValue : parse a field and store value in fielld.name
+//
+Impression.settings.getValue = function(field)
+{
+ if (field.value)
+ {
+ this[field.name] = field.value;
+ log( field.name + " is now " + this[field.name]);
+ }
+ else
+ {
+ logError("Can't get fieldValue");
+ }
+}
+ //
+//// getCopies : parse copies field
+//
+Impression.settings.getCopies = function(field) {
+ if ( (!field.value) || (parseInt(field.value)!=field.value-0) || (parseInt(field.value) < 1) )
+ {
+ this.copies = 1;
+ logError("Can't get copies");
+ }
+ else
+ {
+ this.copies = parseInt(field.value);
+ }
+ log("copies is now " + this.copies);
+}
+
+ //
+//// setValue : set field value
+//
+Impression.settings.setValue = function(afield, avalue) {
+ afield.value = avalue;
+ this.getValue(afield);
+}
+
+ //
+//// setDisableField : set field disabled on/off
+//
+Impression.settings.setDisableField = function( afield, isdisabled ) {
+ afield.disabled = isdisabled ;
+}
+
+ //
+//// disableField : set field disabled on
+//
+Impression.settings.disableField = function(afield) {
+ this.setDisableField(afield, true);
+}
+
+ //
+//// fieldChanges : when a field is changed
+//
+Impression.settings.update = function () {
+ var orientation = "portrait";
+ if (this.theform.type_impression_couleur.checked)
+ this.getValue(this.theform.type_impression_couleur);
+ else
+ this.getValue(this.theform.type_impression_nb);
+
+ if (this.theform.disposition_recto.checked)
+ this.getValue(this.theform.disposition_recto);
+ else
+ this.getValue(this.theform.disposition_recto_verso);
+ this.getValue(this.theform.papier);
+ this.getCopies(this.theform.nb_copies);
+ this.getValue(this.theform.agrafes);
+ // Contraintes
+ if (
+ ( this.papier != "A4" ) ||
+ ( (this.disposition == "recto") && (this.nb_pages>50) ) ||
+ ( (this.disposition == "rectoverso") && (this.nb_pages>100) ) )
+ {
+ this.setValue(this.theform.agrafes, "pasdagraphes");
+ this.disableField(this.theform.agrafes);
+ this.getValue(this.theform.agrafes);
+ } else {
+ this.setDisableField(this.theform.agrafes, false);
+ }
+ if (this.papier == "A4tr")
+ {
+ this.theform.disposition_recto.checked = true;
+ this.disableField(this.theform.disposition_recto);
+ this.disableField(this.theform.disposition_recto_verso);
+ this.getValue(this.theform.disposition_recto);
+ }
+ else
+ {
+ this.setDisableField(this.theform.disposition_recto, false);
+ this.setDisableField(this.theform.disposition_recto_verso, false);
+ }
+
+ this.updatePreview();
+ Impression.AJAX.recalcPrix();
+
+}
+
+ //
+//// updatePreview : update preview with new value
+//
+Impression.settings.updatePreview = function()
+{
+ var image_name = "";
+ if (this.papier == "A4tr")
+ image_name = "portrait_transparent_" + this.type_impression + ".png";
+ else
+ image_name = "portrait_" + this.type_impression + '_' + this.agrafes + ".png";
+ var image = createDOM("IMG",{'src':'/static/images/'+image_name});
+ log("Updating preview (new image : " + image_name + ")");
+ replaceChildNodes("preview",image)
+}
+
+
+/*****************************
+ Impression.popup
+ *****************************/
+Impression.popup = {};
+
+Impression.popup.popupImpression = function(code) {
+ Popup.hide();
+ Popup.create({}, "Impression en cours...",
+ DIV(
+ {"id":"printingPopupContent", "style":"background-image:url(/static/images/dialog-printer.png)"},
+ SPAN("code: "+code),
+ A({"href":"https://wiki.crans.org/VieCrans/ImpressionReseau", "class":"aide", "target":"_blank"}, "Comment récupérer mon impression ? "),
+ A({"href":"index", "class":"aide", "style":"text-align:right;"}, "Nouvelle impression")
+ )
+
+ );
+Popup.display();
+}
+
+Impression.popup.popupError = function(erreur) {
+ Popup.hide();
+ Popup.create({}, "Erreur",
+ DIV({"id":"printingPopupContent", "style":"background-image:url(/static/images/dialog-warning.png)"},
+ SPAN(erreur),
+ A({"href":"mailto:nounous@crans.org", "class":"crans_help aide"}, "Envoyer un rapport aux nounous"),
+ Popup.closeLink({"class":"aide", "style":"text-align:right;"}, "Fermer")));
+ Popup.display();
+}
+
+Impression.popup.popupSolde = function(code) {
+ Popup.hide();
+ Popup.create({}, "Solde insuffisant",
+ DIV(
+ {"id":"printingPopupContent", "style":"background-image:url(/static/images/dialog-solde.png)"},
+ SPAN("pas assez de sous"),
+ A({"href":"https://wiki.crans.org/CransPratique/SoldeImpression", "class":"aide", "target":"_blank"}, "Comment recharger mon compte ? "),
+ Popup.closeLink({"class":"aide", "style":"text-align:right;"}, "Fermer")));
+ Popup.display();
+}
+
+Impression.popup.popupCodes = function(codeList) {
+ Popup.hide();
+ Popup.create({}, "Codes de mes impressions",
+ DIV(
+ {"id":"printingPopupContent", "style":"background-image:url(/static/images/dialog-printer.png)"},
+ SPAN("Mes codes"),
+ //UL({"size":"4", "style":"width:6em;; height:4em;padding:0;margin:0;list-style-type:none;overflow:auto;"}, map(function (code) {return LI({}, code);}, codeList)),
+ SELECT({"size":"4", "style":"width:100%;"}, map(function (code) {return LI({}, code);}, codeList)),
+ Popup.closeLink({"class":"aide", "style":"text-align:right;"}, "Fermer")));
+ Popup.display();
+}
+
+
+
+/*****************************
+ Impression.mesCodes
+ *****************************/
+Impression.mesCodes = {};
+Impression.mesCodes.getCodes = function ()
+{
+ Impression.AJAX.call('codeList', this.displayCodes );
+}
+
+Impression.mesCodes.displayCodes = function (result) {
+ if (result.codes)
+ Impression.popup.popupCodes(result.codes);
+ else if (result.erreur)
+ logError('erreur distante (codeLlist) : ' + result.erreur);
+ else
+ logError('erreur bizarre (codeLlist) : ');
+}
+
+/*****************************
+ Impression.AJAX
+ *****************************/
+Impression.AJAX = {};
+
+
+Impression.AJAX.modifPrix = function( text, wheel )
+{
+ if (wheel)
+ {
+ var image = createDOM("IMG",{'src':'/static/images/indicator.gif'});
+ }
+ else
+ {
+ var image = new DIV({});
+ }
+ var item = new DIV({'onclick':'Impression.AJAX.recalcPrix();'}, image, text);
+ replaceChildNodes("prix_placeholder",item);
+}
+
+Impression.AJAX.modifNbPages = function( nbpages )
+{
+ Impression.settings.nb_pages = nbpages;
+ replaceChildNodes("fileNbPages",nbpages);
+}
+
+Impression.AJAX.call = function(page, callBack) {
+ logDebug("calling AJAX : " + page);
+ var e = loadJSONDoc(page);
+ e.addCallback(callBack);
+ e.addErrback(this.errorHandler);
+}
+
+Impression.AJAX.errorHandler = function(d) {
+ logError("AJAX Error: " + d);
+ //Impression.AJAX.modifPrix("Erreur...", false);
+}
+
+
+Impression.AJAX.usefile = function(filename) {
+ var item = new DIV({}, "Calculs en cours...");
+ this.modifPrix("Analyse du fichier...", true);
+ this.call('useFile?fileName=' + filename,this.analysefini );
+}
+
+Impression.AJAX.analysefini = function(AJAXResp)
+{
+ logDebug('AJAX terminated (usefile)');
+ if (AJAXResp.erreur) {
+ Impression.AJAX.modifPrix(AJAXResp.erreur, false);
+ Impression.popup.popupError(AJAXResp.erreur);
+ Impression.settings.disableForm(true);
+ logWarning('Erreur distante : ' + AJAXResp.erreur);
+ } else {
+ Impression.AJAX.modifPrix("Analyse terminée", true);
+ Impression.settings.update();
+ Impression.AJAX.modifNbPages(AJAXResp.nbPages);
+ }
+}
+
+Impression.AJAX.recalcPrix = function()
+{
+ settings = Impression.settings;
+ var url = "changeSettings?copies=" + settings.copies
+ +"&couleurs="+ settings.type_impression
+ +"&papier="+ settings.papier
+ +"&recto_verso="+ settings.disposition
+ +"&agrafes="+ settings.agrafes;
+ this.modifPrix("Calcul en cours", true);
+ this.call(url, this.changePrix);
+}
+
+Impression.AJAX.changePrix = function(AJAXResp)
+{
+ logDebug('AJAX terminated (recalcPrix)');
+ if (AJAXResp.erreur) {
+ Impression.AJAX.modifPrix(AJAXResp.erreur, false);
+ Impression.popup.popupError(AJAXResp.erreur);
+ Impression.settings.disableForm(true);
+ logWarning('Erreur distante : ' + AJAXResp.erreur);
+ } else {
+ Impression.AJAX.modifPrix("Coût : " + AJAXResp.nouvPrix + "€", false);
+ }
+}
+
+Impression.AJAX.lancerImpression = function(AJAXResp)
+{
+ var url = "lancerImpression";
+ Impression.settings.disableForm(true);
+ this.call(url, this.finImpression);
+}
+
+Impression.AJAX.finImpression = function(AJAXResp)
+{
+ logDebug('AJAX terminated (lancerImpression)');
+ if (AJAXResp.erreur) {
+ Impression.popup.popupError(AJAXResp.erreur);
+ logWarning('Erreur distante : ' + AJAXResp.erreur);
+ } else if (AJAXResp.SoldeInsuffisant) {
+ Impression.popup.popupSolde();
+ Impression.settings.disableForm(false);
+ Impression.settings.update();
+ } else {
+ Impression.popup.popupImpression(AJAXResp.code);
+ }
+ Impression.AJAX.updateSolde();
+
+}
+
+Impression.AJAX.getPrinterState = function()
+{
+ var url = "etatImprimante";
+ Impression.AJAX.call(url, Impression.AJAX.displayPrinterState);
+}
+
+Impression.AJAX.displayPrinterState = function(AJAXResp)
+{
+ logDebug('AJAX terminated (getPrinterState)');
+ if (AJAXResp.erreur) {
+ logWarning('Erreur distante (etatImprimante) : ' + AJAXResp.erreur);
+ } else {
+ replaceChildNodes("etatImprimanteIci", AJAXResp.printer_state)
+ }
+}
+
+Impression.AJAX.updateSolde = function()
+{
+ var url = "AJAXGetSolde";
+ Impression.AJAX.call(url, Impression.AJAX.displaySolde);
+}
+
+Impression.AJAX.displaySolde = function(AJAXResp)
+{
+ logDebug('AJAX terminated (updateSolde)');
+ if (AJAXResp.erreur) {
+ logWarning('Erreur distante (etatImprimante) : ' + AJAXResp.erreur);
+ } else {
+ replaceChildNodes("soldePlaceHolder", AJAXResp.solde )
+ }
+}
+
+setInterval(Impression.AJAX.getPrinterState, 30000);
+setInterval(Impression.AJAX.updateSolde, 60000);
diff --git a/intranet/modules/impression/static/indicator.gif b/intranet/modules/impression/static/indicator.gif
new file mode 100644
index 00000000..085ccaec
Binary files /dev/null and b/intranet/modules/impression/static/indicator.gif differ
diff --git a/intranet/modules/impression/static/paysage_b&w_non.png b/intranet/modules/impression/static/paysage_b&w_non.png
new file mode 100644
index 00000000..441ac6d2
Binary files /dev/null and b/intranet/modules/impression/static/paysage_b&w_non.png differ
diff --git a/intranet/modules/impression/static/paysage_couleur_non.png b/intranet/modules/impression/static/paysage_couleur_non.png
new file mode 100644
index 00000000..d3b440d7
Binary files /dev/null and b/intranet/modules/impression/static/paysage_couleur_non.png differ
diff --git a/intranet/modules/impression/static/pdf-icon.png b/intranet/modules/impression/static/pdf-icon.png
new file mode 100644
index 00000000..552079fd
Binary files /dev/null and b/intranet/modules/impression/static/pdf-icon.png differ
diff --git a/intranet/modules/impression/static/portrait_couleur_diagonale.psd b/intranet/modules/impression/static/portrait_couleur_diagonale.psd
new file mode 100644
index 00000000..55c6280c
Binary files /dev/null and b/intranet/modules/impression/static/portrait_couleur_diagonale.psd differ
diff --git a/intranet/modules/impression/static/portrait_couleurs_Deuxagraphes.png b/intranet/modules/impression/static/portrait_couleurs_Deuxagraphes.png
new file mode 100644
index 00000000..f431ce39
Binary files /dev/null and b/intranet/modules/impression/static/portrait_couleurs_Deuxagraphes.png differ
diff --git a/intranet/modules/impression/static/portrait_couleurs_agraphediagonale.png b/intranet/modules/impression/static/portrait_couleurs_agraphediagonale.png
new file mode 100644
index 00000000..25d82c81
Binary files /dev/null and b/intranet/modules/impression/static/portrait_couleurs_agraphediagonale.png differ
diff --git a/intranet/modules/impression/static/portrait_couleurs_pasdagraphes.png b/intranet/modules/impression/static/portrait_couleurs_pasdagraphes.png
new file mode 100644
index 00000000..68f469cc
Binary files /dev/null and b/intranet/modules/impression/static/portrait_couleurs_pasdagraphes.png differ
diff --git a/intranet/modules/impression/static/portrait_couleurs_stitching.png b/intranet/modules/impression/static/portrait_couleurs_stitching.png
new file mode 100644
index 00000000..62c2df16
Binary files /dev/null and b/intranet/modules/impression/static/portrait_couleurs_stitching.png differ
diff --git a/intranet/modules/impression/static/portrait_couleurs_troisAgraphes.png b/intranet/modules/impression/static/portrait_couleurs_troisAgraphes.png
new file mode 100644
index 00000000..bd7d91f0
Binary files /dev/null and b/intranet/modules/impression/static/portrait_couleurs_troisAgraphes.png differ
diff --git a/intranet/modules/impression/static/portrait_couleurs_uneagraphe.png b/intranet/modules/impression/static/portrait_couleurs_uneagraphe.png
new file mode 100644
index 00000000..cd7df8dc
Binary files /dev/null and b/intranet/modules/impression/static/portrait_couleurs_uneagraphe.png differ
diff --git a/intranet/modules/impression/static/portrait_nb_Deuxagraphes.png b/intranet/modules/impression/static/portrait_nb_Deuxagraphes.png
new file mode 100644
index 00000000..77308966
Binary files /dev/null and b/intranet/modules/impression/static/portrait_nb_Deuxagraphes.png differ
diff --git a/intranet/modules/impression/static/portrait_nb_agraphediagonale.png b/intranet/modules/impression/static/portrait_nb_agraphediagonale.png
new file mode 100644
index 00000000..d76ce6fa
Binary files /dev/null and b/intranet/modules/impression/static/portrait_nb_agraphediagonale.png differ
diff --git a/intranet/modules/impression/static/portrait_nb_pasdagraphes.png b/intranet/modules/impression/static/portrait_nb_pasdagraphes.png
new file mode 100644
index 00000000..d58be940
Binary files /dev/null and b/intranet/modules/impression/static/portrait_nb_pasdagraphes.png differ
diff --git a/intranet/modules/impression/static/portrait_nb_stitching.png b/intranet/modules/impression/static/portrait_nb_stitching.png
new file mode 100644
index 00000000..ed5ee87b
Binary files /dev/null and b/intranet/modules/impression/static/portrait_nb_stitching.png differ
diff --git a/intranet/modules/impression/static/portrait_nb_troisAgraphes.png b/intranet/modules/impression/static/portrait_nb_troisAgraphes.png
new file mode 100644
index 00000000..cb3b5b35
Binary files /dev/null and b/intranet/modules/impression/static/portrait_nb_troisAgraphes.png differ
diff --git a/intranet/modules/impression/static/portrait_nb_uneagraphe.png b/intranet/modules/impression/static/portrait_nb_uneagraphe.png
new file mode 100644
index 00000000..84191d66
Binary files /dev/null and b/intranet/modules/impression/static/portrait_nb_uneagraphe.png differ
diff --git a/intranet/modules/impression/static/portrait_transparent.png b/intranet/modules/impression/static/portrait_transparent.png
new file mode 100644
index 00000000..b34b64cc
Binary files /dev/null and b/intranet/modules/impression/static/portrait_transparent.png differ
diff --git a/intranet/modules/impression/static/portrait_transparent_couleurs.png b/intranet/modules/impression/static/portrait_transparent_couleurs.png
new file mode 100644
index 00000000..b55adf05
Binary files /dev/null and b/intranet/modules/impression/static/portrait_transparent_couleurs.png differ
diff --git a/intranet/modules/impression/static/portrait_transparent_nb.png b/intranet/modules/impression/static/portrait_transparent_nb.png
new file mode 100644
index 00000000..e891650f
Binary files /dev/null and b/intranet/modules/impression/static/portrait_transparent_nb.png differ
diff --git a/intranet/modules/impression/templates/impression-devis.tmpl b/intranet/modules/impression/templates/impression-devis.tmpl
new file mode 100644
index 00000000..06c2eb10
--- /dev/null
+++ b/intranet/modules/impression/templates/impression-devis.tmpl
@@ -0,0 +1,67 @@
+
+
+
+
+
Cr@ns Intranet
+
+
+
+
+
Devis pour impression
+
Fichier : $nomFichier
+
+
+
+ Description |
+ Prix unitaire |
+ Quantité |
+
+ total |
+
+ #for anItem in $devis
+
+ $anItem[0] |
+ $anItem[1] € |
+ $anItem[2] |
+
+ #echo str($anItem[1] * $anItem[2]) + ' €'
+ |
+
+
+ #end for
+
+
+ Total
+ |
+ $total € |
+
+
+
+
+
diff --git a/intranet/modules/impression/templates/impression.tmpl b/intranet/modules/impression/templates/impression.tmpl
new file mode 100644
index 00000000..1f5b7e00
--- /dev/null
+++ b/intranet/modules/impression/templates/impression.tmpl
@@ -0,0 +1,170 @@
+#import crans.impression
+
+#if $getVar('errorMsg',False)
+
+#end if
+
+
+
+
+
+
+
+#if not $getVar('Erreur_imprimante',False)
+ #if not $getVar('fileName',False)
+
+
+ #end if
+
+
+ #if $getVar('fileName',False)
+
+ #else
+
+ #end if
+#else
+ ## desactivation de l'interface si l'imprimant a un probleme
+
+#end if
diff --git a/intranet/modules/infos/main.py b/intranet/modules/infos/main.py
new file mode 100644
index 00000000..797773c1
--- /dev/null
+++ b/intranet/modules/infos/main.py
@@ -0,0 +1,16 @@
+from ClassesIntranet.ModuleBase import ModuleBase
+
+
+class main(ModuleBase):
+ def category(self):
+ return u"Services"
+ def title(self):
+ return u"Informations utiles"
+
+ def index(self):
+ return {
+ 'template':'info-diverses',
+ 'values':{},
+ 'stylesheets':['infos.css'],
+ }
+ index.exposed = True
diff --git a/intranet/modules/infos/static/icon.png b/intranet/modules/infos/static/icon.png
new file mode 100644
index 00000000..df73c4d5
Binary files /dev/null and b/intranet/modules/infos/static/icon.png differ
diff --git a/intranet/modules/infos/static/infos.css b/intranet/modules/infos/static/infos.css
new file mode 100644
index 00000000..c2f0b785
--- /dev/null
+++ b/intranet/modules/infos/static/infos.css
@@ -0,0 +1,75 @@
+/*************************************************************
+ ..
+ .... ............ ........
+ . ....... . .... ..
+ . ... .. .. .. .. ..... . ..
+ .. .. ....@@@. .. . ........ .
+ .. . .. ..@.@@..@@. .@@@@@@@ @@@@@@. ....
+ .@@@@. .@@@@. .@@@@..@@.@@..@@@..@@@..@@@@.... ....
+ @@@@... .@@@.. @@ @@ .@..@@..@@...@@@. .@@@@@. ..
+ .@@@.. . @@@. @@.@@..@@.@@..@@@ @@ .@@@@@@.. .....
+ ...@@@.... @@@ .@@.......... ........ ..... ..
+ . ..@@@@.. . .@@@@. .. ....... . .............
+ . .. .... .. .. . ... ....
+. . .... ............. .. ...
+.. .. ... ........ ... ...
+ ................................
+
+==============================================================
+mainInterface.css - Intranet Style
+
+ Mise en page de l'accueil
+
+
+Copyright (c) 2006 by www.crans.org
+
+**************************************************************/
+
+div.framed_gray {
+ border:5px solid #e2e2e2; /* #acc0ff */
+ background-color:#f2f2f2;
+ padding:10px;
+}
+
+div.framed_gray fieldset {
+ border-width:2px;
+ border-style:solid none none none;
+ border-color:#a2a2a2;
+ padding:10px;
+ margin:10px 10px;
+ font-weight:bold;
+}
+
+div.framed_gray fieldset legend {
+ color:#a2a2a2;
+}
+
+div.framed_gray fieldset ul {
+ list-style-type:none;
+ margin:0;
+ padding:0;
+}
+
+div.framed_gray fieldset ul li {
+ float:left;
+ height:70px;
+ width:100px;
+ margin:5px;
+ display:block;
+ text-align:center;
+}
+
+div.framed_gray fieldset ul li span {
+ margin-bottom:0;
+ display:block;
+}
+div.framed_gray fieldset ul a {
+ color:black;
+ text-decoration:none;
+}
+
+div.framed_gray fieldset ul li img {
+ margin:2px auto;
+ width:32px;
+ height:32px;
+}
diff --git a/intranet/modules/infos/templates/info-diverses.tmpl b/intranet/modules/infos/templates/info-diverses.tmpl
new file mode 100644
index 00000000..82e8ee53
--- /dev/null
+++ b/intranet/modules/infos/templates/info-diverses.tmpl
@@ -0,0 +1,17 @@
+
+
Mots de passe Cr@ns
+
Pour les news
+
+ - Utilisateur :
+ - Vivelapa
+ - Mot de passe :
+ - ranoia!
+
+
Pour le wiki
+
+ - Utilisateur :
+ - ViveLe
+ - Mot de passe :
+ - Wiki!
+
+
diff --git a/intranet/modules/mesMachines/main.py b/intranet/modules/mesMachines/main.py
new file mode 100755
index 00000000..a98f8b9b
--- /dev/null
+++ b/intranet/modules/mesMachines/main.py
@@ -0,0 +1,249 @@
+#! /usr/bin/env python
+# -*- coding: iso-8859-15 -*-
+# ##################################################################################################### #
+# Machines
+# ##################################################################################################### #
+# Description:
+# Affiche la liste des machies, les infons sur une machine et permet des modifications
+# Informations:
+#
+# Pages:
+# index:liste des machines + le reste (AJAX)
+#
+# ##################################################################################################### #
+import cherrypy, sys, os, datetime
+from time import strftime, localtime, time
+# libraries crans
+sys.path.append('/usr/scripts/gestion/')
+import crans.cp
+if (cherrypy.config.configMap["global"]["server.environment"] == "development"):
+ from ldap_crans_test import *
+# print("mesmachines : unsing test ldap : env=" + cherrypy.config.configMap["global"]["server.environment"])
+else:
+ from ldap_crans import *
+# print("mesmachines : unsing prod ldap : env=" + cherrypy.config.configMap["global"]["server.environment"])
+
+from ClassesIntranet.ModuleBase import ModuleBase
+
+class main(ModuleBase):
+ def title(self):
+ return "Mes Machines"
+ def icon(self):
+ return "machines_icon_fixe.png"
+
+ def AJAXListeMachines(self):
+ adh = cherrypy.session['LDAP'].search('uid=' + cherrypy.session['uid'])['adherent'][0]
+ machines = []
+ for une_machine in adh.machines():
+ machineInfos = {}
+ # nom, mac, mid, ip
+ machineInfos['nom'] = une_machine.nom()
+ machineInfos['nomCourt'] = une_machine.nom().split('.',1)[0]
+ machineInfos['mid'] = une_machine.id()
+ # type
+ if une_machine.objectClass == 'machineFixe':
+ machineInfos['type'] = 'fixe'
+ #machineInfos['type'] = 'Machine fixe'
+ else:
+ machineInfos['type'] = 'wifi'
+ #machineInfos['type'] = 'Machine wifi'
+ # clef ipsec
+ machines.append(machineInfos)
+
+ return {"machines":machines}
+ AJAXListeMachines.exposed = True
+
+ def AJAXMachineInfo(self, mid):
+ try:
+ machine = cherrypy.session['LDAP'].search('mid=' + mid)['machine'][0]
+ if machine.proprietaire().mail() != cherrypy.session['uid']:
+ raise Exception
+ # zamok -> pour tester l'affichage des ports, des alias
+ #machine = cherrypy.session['LDAP'].search('mid=896')['machine'][0]
+ machineInfos = {}
+ # nom, mac, mid, ip
+ machineInfos['nom'] = machine.nom()
+ machineInfos['nomCourt'] = machine.nom().split('.',1)[0]
+ machineInfos['mac'] = machine.mac()
+ machineInfos['mid'] = machine.id()
+ machineInfos['ip'] = machine.ip()
+ # type
+ if machine.objectClass == 'machineFixe':
+ machineInfos['type'] = 'fixe'
+ else:
+ machineInfos['type'] = 'wifi'
+ # clef ipsec
+ try:
+ machineInfos['ipsec'] = machine.ipsec()
+ except:
+ machineInfos['ipsec'] = ''
+ # alias
+ machineInfos['alias'] = machine.alias()
+ # blacklists
+ machineInfos['blacklist'] = []
+ for blacklist_type in machine.blacklist_all()[0].keys():
+ for (begin, end) in machine.blacklist_all()[0][blacklist_type]:
+ blacklist = {}
+ blacklist['begin'] = strftime('%d/%m/%Y %H:%M', localtime(int(begin)))
+ blacklist['end'] = strftime('%d/%m/%Y %H:%M', localtime(int(end)))
+ blacklist['type'] = blacklist_type
+ blacklist['actif'] = 1
+ machineInfos['blacklist'].append(blacklist)
+ for blacklist_type in machine.blacklist_all()[1].keys():
+ for (begin, end) in machine.blacklist_all()[1][blacklist_type]:
+ blacklist = {}
+ blacklist['begin'] = strftime('%d/%m/%Y %H:%M', localtime(int(begin)))
+ blacklist['end'] = strftime('%d/%m/%Y %H:%M', localtime(int(end)))
+ blacklist['type'] = blacklist_type
+ blacklist['actif'] = 0
+ machineInfos['blacklist'].append(blacklist)
+ # ports
+ machineInfos['ports'] = []
+ if machine.portTCPin() != []:
+ machineInfos['ports'].append(
+ {
+ 'titre':'Ports TCP ouvert ext->machine',
+ 'ports':machine.portTCPin()
+ }
+ )
+ if machine.portTCPout() != []:
+ machineInfos['ports'].append(
+ {
+ 'titre':'Ports TCP ouvert machine->ext',
+ 'ports':machine.portTCPout()
+ }
+ )
+ if machine.portUDPin() != []:
+ machineInfos['ports'].append(
+ {
+ 'titre':'Ports UDP ouvert ext->machine',
+ 'ports':machine.portUDPin()
+ }
+ )
+ if machine.portUDPout() != []:
+ machineInfos['ports'].append(
+ {
+ 'titre':'Ports TCP ouvert machine->ext',
+ 'ports':machine.portUDPout()
+ }
+ )
+
+ return machineInfos
+ except Exception, e:
+ return {"erreur":str(e)}
+ AJAXMachineInfo.exposed = True
+
+ ##########################
+ # affichage
+ ##########################
+ #
+ # methode qui affiche la template
+ #
+ def index(self):
+ return {
+ 'template' :'machines',
+ 'values' :{},
+ 'stylesheets' :['machines.css'],
+ 'scripts':['machines.js'],
+ }
+ index.exposed = True
+
+
+ ###########################################################################
+ # methodes pour changer
+ # des valeurs
+ ###########################################################################
+ #
+
+ ##########################
+ # machine:nom
+ ##########################
+ def AJAXChangerNom(self, mid, nouveauNom):
+ try:
+ adh = cherrypy.session['LDAP'].search('uid=' + cherrypy.session['uid'])['adherent'][0]
+ mach = cherrypy.session['LDAP'].search('mid=' + mid, 'w')['machine'][0]
+ # tester si c'est bien la machine de l'adherent
+ if mach.proprietaire().compte() != cherrypy.session['uid']:
+ del adh, mach
+ raise Exception(u"L'uid de l'adherent ne correspond mas au proprietaire de la machine.")
+ anciennom = mach.nom()
+ nouveauNom = mach.nom(nouveauNom)
+ mach.save()
+ del mach
+ except ValueError, e:
+ raise e
+ #return {'error':str(e)}
+ crans.cp.log("Changer nom machine : %s->%s" % (anciennom, nouveauNom), "MESMACHINES")
+ return {'message':u"Modification réussie", 'mid':mid}
+ AJAXChangerNom.exposed = True
+
+ ##########################
+ # machine:mac
+ ##########################
+ def AJAXchangerMAC(self, mid, nouvelleMAC):
+ try:
+ adh = cherrypy.session['LDAP'].search('uid=' + cherrypy.session['uid'])['adherent'][0]
+ mach = cherrypy.session['LDAP'].search('mid=' + mid, 'w')['machine'][0]
+ # tester si c'est bien la machine de l'adherent
+ if mach.proprietaire().compte() != cherrypy.session['uid']:
+ del adh, mach
+ raise Exception(u"L'uid de l'adherent ne correspond mas au proprietaire de la machine.")
+ anciennemac = mach.mac()
+ nommachine = mach.nom()
+ mach.mac(nouvelleMAC)
+ mach.save()
+ del mach
+ except ValueError, e:
+ return {'error':e.args[0]}
+ crans.cp.log("Change mac machine %s : %s->%s" % (nommachine, anciennemac, nouvelleMAC), "MESMACHINES")
+ return {'message':u"Modification réussie", 'mid':mid}
+ AJAXchangerMAC.exposed = True
+
+
+
+ ##########################
+ # machine:suppression
+ ##########################
+ def AJAXSupprimerMachine(self, mid):
+ try:
+ adh = cherrypy.session['LDAP'].search('uid=' + cherrypy.session['uid'])['adherent'][0]
+ mach = cherrypy.session['LDAP'].search('mid=' + mid, 'w')['machine'][0]
+ # tester si c'est bien la machine de l'adherent
+ if mach.proprietaire().compte() != cherrypy.session['uid']:
+ del adh, mach
+ raise Exception(u"L'uid de l'adherent ne correspond mas au proprietaire de la machine.")
+ mach.delete()
+ except ValueError, e:
+ return {'error':e.args[0]}
+ crans.cp.log("Machine supprimee", "MACHINES")
+ return {'message':u"Machine supprimée"}
+ AJAXSupprimerMachine.exposed = True
+
+ ##########################
+ # machine:creation
+ ##########################
+ def AJAXCreerMachine(self, nomNouvelleMachine, MACNouvelleMachine, typeNouvelleMachine):
+ adh = cherrypy.session['LDAP'].search('uid=' + cherrypy.session['uid'])['adherent'][0]
+ if typeNouvelleMachine=='fixe' and adh.droits() == [] and adh.machines_fixes() != []:
+ return {'error':'Vous avez deja une machine fixe. Vous ne pouvez ajouter que des machines WiFi.'}
+ try:
+ if typeNouvelleMachine=='wifi':
+ m = MachineWifi(adh)
+ elif typeNouvelleMachine=='fixe':
+ m = MachineFixe(adh)
+ else:
+ raise Exception, "type de machine inconnu : %s " % typeNouvelleMachine
+ m.nom(nomNouvelleMachine)
+ m.mac(MACNouvelleMachine)
+ m.ip("
")
+ message = m.save()
+ del m
+ except ValueError, e:
+ del m
+ return {'error':e.args[0].replace("\n","\\n")}
+ crans.cp.log("Nouvelle machine %s" % nomNouvelleMachine, "MACHINES")
+ return {'message':u"Machine enregistrée avec succès"}
+ AJAXCreerMachine.exposed = True
+
+
+
diff --git a/intranet/modules/mesMachines/static/machines.css b/intranet/modules/mesMachines/static/machines.css
new file mode 100644
index 00000000..b25aba27
--- /dev/null
+++ b/intranet/modules/mesMachines/static/machines.css
@@ -0,0 +1,160 @@
+/*************************************************************
+ ..
+ .... ............ ........
+ . ....... . .... ..
+ . ... .. .. .. .. ..... . ..
+ .. .. ....@@@. .. . ........ .
+ .. . .. ..@.@@..@@. .@@@@@@@ @@@@@@. ....
+ .@@@@. .@@@@. .@@@@..@@.@@..@@@..@@@..@@@@.... ....
+ @@@@... .@@@.. @@ @@ .@..@@..@@...@@@. .@@@@@. ..
+ .@@@.. . @@@. @@.@@..@@.@@..@@@ @@ .@@@@@@.. .....
+ ...@@@.... @@@ .@@.......... ........ ..... ..
+ . ..@@@@.. . .@@@@. .. ....... . .............
+ . .. .... .. .. . ... ....
+. . .... ............. .. ...
+.. .. ... ........ ... ...
+ ................................
+
+==============================================================
+macines.css - Intranet Style
+
+Copyright (c) 2006 by www.crans.org
+
+**************************************************************/
+#globalDiv {
+ padding-left : 20%;
+ margin:0;
+ position:relative;
+}
+h2 {
+ margin: 0 5px .5em 5px;padding:5px;
+}
+
+div.alias {
+ color:gray;
+ margin:0;
+ padding:0 0 0 60px;
+ display:block;
+ font-weight:normal;
+ font-size:0.6em;
+
+}
+
+table.blacklist_table,
+table.ports_table {
+ border-top: thin black solid;
+ border-left: thin black solid;
+}
+
+table.blacklist_table td,
+table.blacklist_table th,
+table.ports_table td,
+table.ports_table th {
+ border-right: thin black solid;
+ border-bottom: thin black solid;
+ padding: 3px;
+}
+
+.actif {
+ color:red;
+}
+.inactif {
+}
+
+
+#gestion_machines_main_frame {
+ padding:5px;
+}
+
+dl.basicInfos dt {
+ float:left;
+ font-weight:bold;
+ clear:left;
+}
+
+dl.basicInfos dd {
+ float:left;
+ margin:0 1em;
+}
+
+ul#listeMachines {
+ list-style-type:none;
+ margin:0;
+ padding:0;
+}
+
+ul#listeMachines li {
+ float:left;
+ height:70px;
+ width:100px;
+ margin:5px;
+ display:block;
+ text-align:center;
+}
+
+ul#listeMachines li span {
+ margin-bottom:0;
+ display:block;
+}
+
+ul#listeMachines li a {
+display:block;
+ color:black;
+ text-decoration:none;
+}
+
+ul#listeMachines li a:hover {
+ background:#bbbbff;
+}
+
+ul#listeMachines li a:active {
+ background:#8888ff;
+}
+
+ul#listeMachines li img {
+ margin:2px auto;
+ width:32px;
+ height:32px;
+}
+
+#menu_actions {
+ background:#eeeeff;
+ padding:.3em;
+ width:18%;
+ float:left;
+ position:absolute;
+ top:1em;
+ left:0;
+ border: thin black solid;
+}
+
+#menu_actions ul {
+ list-style-type:none;
+ padding:0;
+ margin:.5em;
+}
+#menu_actions ul li a {
+ text-decoration:none;
+}
+#menu_actions ul li a:hover {
+ text-decoration:underline;
+}
+
+#menu_actions h1 {
+ font-size:1em;
+ margin:0;
+ text-align:center;
+ border-bottom: thin black solid;
+}
+
+// on change la couleur des messages
+.message {
+ background-color:#000080;
+ color:white;
+}
+
+label {
+ width:175px;
+ display:block;
+ float:left;
+}
diff --git a/intranet/modules/mesMachines/static/machines.js b/intranet/modules/mesMachines/static/machines.js
new file mode 100644
index 00000000..023002bb
--- /dev/null
+++ b/intranet/modules/mesMachines/static/machines.js
@@ -0,0 +1,348 @@
+/* ************************************************************
+ * Machines
+ ************************************************************
+ * Machines.init : initialisation de la page
+ * Machines.listeMachines : liste des machines
+ * Machines.infoPane : information sur une machine
+ * Machines.actions : modifications, ajout...
+ * Machines.AJAX : ajax
+ */
+Machines = {};
+
+/*****************************
+ Machines.init
+ *****************************/
+Machines.init = function()
+{
+ // afficher le tableau codelist
+ appendChildNodes("globalDiv", Machines.createFrames());
+ appendChildNodes("globalDiv", Machines.actions.makeMenu());
+ // recuperer la liste des codes
+ this.listeMachines.load();
+}
+
+Machines.createFrames = function()
+{
+ var main = DIV({"id":"gestion_machines_main_frame"});
+ var inside = DIV({"id":"__insideDivId", "style":"background:white;margin:5px;padding:5px;"},main);
+ var outside = DIV({"id":"__outsideDivId","style":"background:#000080;z-index:500;padding:0;"}, inside );
+ roundElement(outside);
+ roundElement(inside);
+ log("Creation du cadre");
+ return outside
+}
+
+/*****************************
+ Machines.listeMachines
+ *****************************/
+Machines.listeMachines = {};
+
+
+Machines.listeMachines.load = function()
+{
+ Machines.AJAX.call("AJAXListeMachines", Machines.listeMachines.display);
+ log("Chargement liste...");
+ Machines.currentMachine = '';
+}
+
+Machines.listeMachines.display = function(result)
+{
+ Crans.loading.display(false);
+ log("display liste");
+
+ replaceChildNodes( "gestion_machines_main_frame",
+ H2({}, "Mes machines"),
+ UL({"id":"listeMachines"}),
+ DIV( {"style":"clear:both;"} )
+ );
+ if (result.machines) {
+ replaceChildNodes('listeMachines',map(Machines.listeMachines.newMachineNodeFromDict ,result.machines));
+ Machines.actions.updateMenu(Machines.actions.actionForMachineList);
+ Machines.currentMid = '';
+ }
+ else if (result.erreur)
+ logError("Erreur distante : " + result.erreur);
+ else
+ logError("Probleme bizarre...");
+}
+
+Machines.listeMachines.newMachineNodeFromDict = function (aDict, style)
+{
+ var nom = aDict.nomCourt;
+ var mid = aDict.mid;
+ var image = "machines_icon_" + aDict.type + ".png";
+ //log("create an item : " + nom);
+ if (style) {
+ var anIcon = LI({'id':'machine_' + mid,"style":style});
+ } else
+ var anIcon = LI( {'id':'machine_' + mid} );
+ appendChildNodes(anIcon, A({"href":"#", "onclick":"Machines.infoPane.loadInfo('"+mid+"');return false;"}, IMG({"src":"/static/images/" + image}), SPAN({},nom) ) );
+ return anIcon;
+}
+
+/*****************************
+ Machines.infoPane
+ *****************************/
+Machines.infoPane = {};
+
+Machines.infoPane.loadInfo = function(mid)
+{
+ if (!mid)
+ if (!Machines.currentMachine) {
+ logError("Machines.infoPane.loadInfo : pas de mid, pas de machine courrante...");
+ return
+ } else
+ mid = Machines.currentMachine.mid;
+
+ log("load info : " + mid);
+ Machines.AJAX.call("AJAXMachineInfo?mid=" + mid, Machines.infoPane.display);
+ try {
+ pulsate('machine_' + mid);
+ } catch (error) {}
+}
+
+Machines.infoPane.display = function(result)
+{
+ Crans.loading.display(false);
+ if (result.nom) {
+ log("displaying info : " + result.mid);
+ // building pane
+ var machinePane = DIV({"id":"machine_pane"});
+
+ // lien pour retourner a la liste des machines
+ var back_link = A({"href":"#", "onclick":"Machines.listeMachines.load(); return false;"},"Retour");
+ appendChildNodes( machinePane, back_link );
+
+ // titre (nom de machine + alias)
+ var title = H2({}, IMG({"src":"/static/images/machines_icon_" + result.type + ".png"}), " ", result.nom);
+ var alias = DIV({"class":"alias"},
+ map(function(a_name) { return SPAN({}, a_name + " ")}, result.alias));
+ appendChildNodes( title, alias );
+ appendChildNodes( machinePane, title );
+
+ // infos de base (type, mac, ip, ipsec...)
+ var basicInfos = createDOM("DL", {"class":"basicInfos"});
+ appendChildNodes(basicInfos, createDOM("DT", "type:" ), createDOM("DD",{},"Machine " + result.type ) );
+ appendChildNodes(basicInfos, createDOM("DT", "mac: " ), createDOM("DD",{},result.mac ) );
+ appendChildNodes(basicInfos, createDOM("DT", "ip: " ), createDOM("DD",{},result.ip ) );
+ if (result.ipsec)
+ appendChildNodes(basicInfos, createDOM("DT", "Clef ipSec:" ), createDOM("DD",{},result.ipsec ) );
+ appendChildNodes( machinePane, basicInfos );
+ appendChildNodes( machinePane, DIV( {"style":"clear:both;"} ) );
+
+
+ // blacklist
+ if (result.blacklist)
+ if (result.blacklist.length) {
+ var subtitle = H3({}, "Blacklist");
+ appendChildNodes( machinePane, subtitle );
+ var blacklist_table = TABLE({"class":"blacklist_table", "cellspacing":"0"},
+ THEAD({},
+ TH({}, "Cause"),
+ TH({}, "Debut"),
+ TH({}, "Fin")
+ )
+ );
+ map(function(a_blacklist_dict) {
+ var style = "inactif";
+ if (a_blacklist_dict.actif)
+ style = "actif";
+ var line = TR({"class":style},
+ TD({}, a_blacklist_dict.type),
+ TD({}, a_blacklist_dict.begin),
+ TD({}, a_blacklist_dict.end)
+ );
+ appendChildNodes(blacklist_table, line);
+ }, result.blacklist );
+ appendChildNodes( machinePane, blacklist_table );
+ }
+ // liste des ports ouverts
+ if (result.ports)
+ if (result.ports.length) {
+ var subtitle = H3({}, "Ports ouverts");
+ appendChildNodes( machinePane, subtitle );
+ var port_table = TABLE({"class":"ports_table", "cellspacing":"0"});
+ map(function(a_port_dict) {
+ var line = TR({},
+ TH({}, a_port_dict.titre),
+ map(function(a_port) {return TD({}, a_port);}, a_port_dict.ports)
+ );
+ appendChildNodes(port_table, line);
+ }, result.ports );
+ appendChildNodes( machinePane, port_table );
+ }
+
+ // attaching pane to document
+ replaceChildNodes( "gestion_machines_main_frame", machinePane);
+ // updationg actions
+ Machines.currentMachine = result;
+ Machines.actions.updateMenu(Machines.actions.actionsForInfoPane);
+ } else if (result.erreur) {
+ logError("Erreur distante : " + result.erreur);
+ } else
+ logError("Probleme bizarr...");
+
+}
+
+/*****************************
+ Machines.actions
+ *****************************/
+Machines.actions = {}
+
+Machines.actions.disponibles =
+{
+ 'Ajouter machine fixe':'Machines.actions.formulaire.nouvelleMachine(\'fixe\');',
+ 'Ajouter machine wifi':'Machines.actions.formulaire.nouvelleMachine(\'wifi\');',
+ 'Modifier Mac':'Machines.actions.formulaire.modifierMac(Machines.currentMid);',
+ 'Renommer':'Machines.actions.formulaire.renommer(Machines.currentMid);',
+ 'Supprimer':'Machines.actions.formulaire.supprimer(Machines.currentMid);',
+ 'Demander l\'ouverture d\'un port':'Machines.actions.formulaire.ouverturePort(Machines.currentMid);'
+}
+Machines.actions.actionForMachineList = ['Ajouter machine fixe', 'Ajouter machine wifi'];
+Machines.actions.actionsForInfoPane = ['Modifier Mac', 'Renommer', 'Supprimer'];
+
+Machines.actions.makeMenu = function(actionListe)
+{
+ log("building action menu");
+ var liste = UL({"id":"liste_actions"});
+ //this.updateMenu(actionListe, liste)
+ return DIV( {"id":"menu_actions"},
+ H1( {}, "ACTIONS"),
+ liste
+ );
+}
+
+Machines.actions.updateMenu = function(actionListe, liste_actionsNode)
+{
+ if (!liste_actionsNode)
+ liste_actionsNode = "liste_actions";
+ replaceChildNodes(liste_actionsNode);
+ map(
+ function(actionName) {
+ appendChildNodes(liste_actionsNode, LI({}, Machines.actions.makeActionLink(actionName)));
+ }
+ , actionListe);
+}
+
+Machines.actions.makeActionLink = function(actionName)
+{
+ if (this.disponibles[actionName])
+ {
+ return A({"href":"#", "onclick":this.disponibles[actionName] + "return false;"}, actionName);
+ } else
+ logError("action inconnue " + actionName);
+ return A({}, "???");
+}
+
+
+
+Machines.actions.callback = function(result) {
+ Crans.loading.display(false);
+ if (result.message){
+ log(result.message);
+ Crans.messages.setMessage(result.message);
+ if (result.mid)
+ Machines.infoPane.loadInfo(result.mid);
+ else
+ Machines.listeMachines.load();
+ }
+ if (result.error){
+ alert(result.error);
+ logError("AJAX error");
+ }
+}
+
+// actions : affichage des formulaires
+Machines.actions.formulaire = {}
+Machines.actions.formulaire.modifierMac = function()
+{
+ if (!Machines.currentMachine)
+ logError("pas de machine courrante");
+ else {
+ var c = '';
+ while ( c == '')
+ c = prompt("Adresse MAC de la machine :",Machines.currentMachine.mac);
+ if (c == null)
+ return false;
+ // AJAX stuff
+ Machines.AJAX.call('AJAXchangerMAC?nouvelleMAC=' + c + '&mid=' + Machines.currentMachine.mid,
+ Machines.actions.callback);
+ }
+ return false;
+}
+Machines.actions.formulaire.renommer = function() {
+ if (!Machines.currentMachine)
+ logError("pas de machine courrante");
+ else {
+ var c = '';
+ while ( c == '')
+ c = prompt("Nom de la machine :",Machines.currentMachine.nomCourt);
+ if (c == null)
+ return false;
+ // AJAX stuff
+ Machines.AJAX.call('AJAXChangerNom?nouveauNom=' + c + '&mid=' + Machines.currentMachine.mid,
+ Machines.actions.callback);
+ }
+ return false;
+}
+Machines.actions.formulaire.supprimer = function() {
+ if (!Machines.currentMachine)
+ logError("pas de machine courrante");
+ else {
+ if (confirm("Supprimer la machine " + Machines.currentMachine.nomCourt +" ?")) {
+ // AJAX stuff
+ Machines.AJAX.call('AJAXSupprimerMachine?mid=' + Machines.currentMachine.mid,
+ Machines.actions.callback);
+ }
+ }
+ return false;
+}
+
+Machines.actions.formulaire.nouvelleMachine = function(type) {
+ replaceChildNodes( "gestion_machines_main_frame",
+ A({"href":"#", "onclick":"Machines.listeMachines.load(); return false;"},"Retour"),
+ H2({}, "Nouvelle machine"),
+ FORM({"style":"clear:both;", 'onsubmit':'Machines.actions.creerMachine(this.typeField.value, this.nom.value, this.mac.value);return false;'},
+ createDOM('label', {'for':'add_machine_nom'}, "Nom de la machine : "),
+ INPUT({"name":"nom"}),
+ BR(),
+ createDOM('label', {'for':'add_machine_mac'}, "Adresse MAC : "),
+ INPUT({"name":"mac"}),
+ BR(),
+ createDOM('label', {'for':'add_machine_type'}, "Type de machine : "),
+ SPAN({'id':'add_machine_type'}, type),
+ INPUT({"name":"typeField", 'type':'hidden', 'value':type}),
+ BR(),
+ BUTTON({"class":"liens", 'type':'submit'}, 'Ajouter')
+ )
+ );
+ return false;
+}
+
+Machines.actions.creerMachine = function(type, nom, mac) {
+ Machines.AJAX.call('AJAXCreerMachine?nomNouvelleMachine=' + nom
+ + '&MACNouvelleMachine=' + mac
+ + '&typeNouvelleMachine=' + type,
+ Machines.actions.callback);
+}
+
+/*****************************
+ Machines.AJAX
+ *****************************/
+Machines.AJAX = {}
+
+Machines.AJAX.call = function(page, callBack) {
+ logDebug("calling AJAX : " + page);
+ var e = loadJSONDoc(page);
+ e.addCallback(callBack);
+ e.addErrback(this.errorHandler);
+ Crans.loading.display(true);
+
+}
+
+Machines.AJAX.errorHandler = function(d) {
+ //Machines.AJAX..modifPrix("Erreur", false);
+ logError("AJAX Error: " + d);
+ Crans.loading.display(false);
+}
+
diff --git a/intranet/modules/mesMachines/static/machines_icon_fixe.png b/intranet/modules/mesMachines/static/machines_icon_fixe.png
new file mode 100644
index 00000000..11ffbb71
Binary files /dev/null and b/intranet/modules/mesMachines/static/machines_icon_fixe.png differ
diff --git a/intranet/modules/mesMachines/static/machines_icon_wifi.png b/intranet/modules/mesMachines/static/machines_icon_wifi.png
new file mode 100644
index 00000000..caca9a1d
Binary files /dev/null and b/intranet/modules/mesMachines/static/machines_icon_wifi.png differ
diff --git a/intranet/modules/monCompte/main.py b/intranet/modules/monCompte/main.py
new file mode 100755
index 00000000..6e487a82
--- /dev/null
+++ b/intranet/modules/monCompte/main.py
@@ -0,0 +1,359 @@
+#! /usr/bin/env python
+# -*- coding: iso-8859-15 -*-
+# ##################################################################################################### #
+# MonCompte
+# ##################################################################################################### #
+# Description:
+#
+# Informations:
+#
+# Pages:
+#
+#
+# ##################################################################################################### #
+
+import cherrypy, sys, os, datetime
+# libraries crans
+import crans.cp as _crans_cp
+sys.path.append('/usr/scripts/gestion/')
+from config_mail import MailConfig
+
+if (cherrypy.config.configMap["global"]["server.environment"] == "development"):
+ from ldap_crans_test import *
+# print("monCompte : unsing test ldap : env=" + cherrypy.config.configMap["global"]["server.environment"])
+else:
+ from ldap_crans import *
+# print("monCompte : unsing prod ldap : env=" + cherrypy.config.configMap["global"]["server.environment"])
+
+from ClassesIntranet.ModuleBase import ModuleBase
+
+class main(ModuleBase):
+ def title(self):
+ return "Mon Compte"
+
+ def getCurrentAdministrativeYear(self):
+ '''
+ premiere partie de l''annee scolaire en cours
+ ex : le 5 juin 2006 retourne 2005
+ '''
+ now = datetime.datetime.now()
+ currentYear = int(now.strftime("%Y"))
+ currentMonth = int(now.strftime("%m"))
+ if currentMonth > 8:
+ administrativeYear = currentYear
+ else:
+ administrativeYear = currentYear - 1
+ return administrativeYear
+
+ ##########################
+ # affichage
+ ##########################
+ #
+ # methode qui affiche la template avec toutes les infos de
+ # l'adherent + les formulaires
+ #
+ def index(self, message = '', error = '', currentTab = 'mainTab'):
+ adh = cherrypy.session['LDAP'].search('uid=' + cherrypy.session['uid'])['adherent'][0]
+ t = {}
+ t['message'] = message
+ t['error'] = error
+
+
+ ############## info adherent ##############
+ adherent = {}
+ # nom, prenom, chambre, tel, solde, droits, mail
+ adherent['prenom'] = adh.prenom()
+ adherent['nom'] = adh.nom()
+ adherent['chambre'] = adh.chbre()
+ if adherent['chambre'] == "EXT":
+ adr = adh.adresse()
+ adherent['adresse'] = {}
+ adherent['adresse']['ligne1'] = adr[0]
+ adherent['adresse']['ligne2'] = adr[1]
+ adherent['adresse']['cp'] = adr[2]
+ adherent['adresse']['ville'] = adr[3]
+ adherent['telephone'] = adh.tel
+ adherent['solde'] = adh.solde
+ adherent['droits'] = u", ".join(adh.droits())
+ adherent['mail'] = adh.email()
+ # cotisation
+ administrativeYear = self.getCurrentAdministrativeYear()
+ if administrativeYear in adh.paiement():
+ adherent['cotisationOK'] = 'OK'
+ else:
+ adherent['cotisationOK'] = None
+ # carte etudiant
+ if administrativeYear in adh.carteEtudiant():
+ adherent['carteOK'] = 'OK'
+ else:
+ adherent['carteOK'] = None
+ # annee scolaire (ex 2001-2002)
+ adherent['anneeScolaire'] = str(administrativeYear) + '-' + str(administrativeYear + 1)
+ t['adherent'] = adherent
+
+ ############## info mail ##############
+ mailInfos = {}
+ try:
+ mailConfig = MailConfig(cherrypy.session['uid'])
+ mailInfos['forwarding_address'] = mailConfig['forward']
+ mailInfos['spam'] = {}
+ mailInfos['spam']['no'] = mailConfig['spam'] == 'accepte'
+ mailInfos['spam']['mark'] = mailConfig['spam'] == 'marque'
+ mailInfos['spam']['drop'] = mailConfig['spam'] == 'supprime'
+ except Exception, e:
+ t['mailError'] = u"Erreur:fichiers de configuration mail personnels"
+
+ mailInfos['alias'] = adh.alias()
+ mailInfos['contourneGreylist'] = adh.contourneGreylist()
+ mailInfos['rewriteMailHeaders'] = adh.rewriteMailHeaders()
+ t['mailInfos'] = mailInfos
+
+
+
+ return {
+ 'template' :'monCompte',
+ 'values' :t,
+ 'stylesheets' :['monCompte.css'],
+ 'scripts':['crans_domtab.js','moncompte.js','passwordGenerator.js'],
+ }
+ index.exposed = True
+
+
+
+ ##########################
+ # paypal
+ ##########################
+ #
+ # methode qui affiche successivement les
+ # templates du popup pour recharger son compte impression
+ # via paypal
+ #
+ def rechargerCompteImpression(self, etape = '1', combien = None):
+ adh = cherrypy.session['LDAP'].search('uid=' + cherrypy.session['uid'])['adherent'][0]
+ if (etape == "1"): # Introduction
+ return {
+ 'template' :'MonCompteRechargePaypal1',
+ 'standalone' :True,
+ 'values' :{},
+ }
+ elif (etape == "2"): # choix montant
+ return {
+ 'template' :'MonCompteRechargePaypal2',
+ 'standalone' :True,
+ 'values' :{},
+ }
+ elif (etape == "3"): # confirmer facture
+ # creer objet facture
+ f = Facture(adh)
+ # /!\ verifier que combien est un nombre
+ # et qu'il n'y a pas plus de 2 chiffres après le point...
+ # (ce serait bien aussi si on pouvait mettre une virgue a la place du point)
+ try:
+ # remplacage des virgules
+ combien = combien.replace(u',', u'.')
+ # convertissage
+ combien = float(combien)
+ # arrondissage-tronquage :
+ combien = float(int(combien*100)/100.0)
+ # nombre positif
+ if combien < 0:
+ raise ValueError
+ except Exception:
+ return {
+ 'template' :'MonCompteRechargePaypal2',
+ 'standalone' :True,
+ 'values' :{'error':"Le montant doit être un nombre positif !", 'combien':combien},
+ }
+ f.ajoute({'nombre': 1, 'code': 'SOLDE', 'designation': 'Credit du compte impression (intranet)', 'pu': combien})
+ cherrypy.session['freshFacture'] = f
+ pageData = {}
+ pageData['details'] = [
+ {
+ 'intitule':art['designation'],
+ 'quantite':art['nombre'],
+ 'prixUnitaire':art['pu'],
+ 'prixTotal':art['pu']*art['nombre'],
+ } for art in f.articles()]
+ pageData['total'] = f.total()
+ return {
+ 'template' :'MonCompteRechargePaypal3',
+ 'standalone' :True,
+ 'values' :pageData,
+ }
+ elif (etape == "4"):# payer maintenant ?
+ # sauver objet facture
+ f = cherrypy.session['freshFacture']
+ f.save()
+ return {
+ 'template' :'MonCompteRechargePaypal4',
+ 'standalone' :True,
+ 'values' :{'lienPaypal' : f.urlPaypal(useSandbox = cherrypy.config.get("paypal.useSandbox", False),
+ businessMail = cherrypy.config.get("paypal.businessAdress", "paypal@crans.org"),
+ return_page = "https://intranet.crans.org/monCompte/paypalReturn",
+ cancel_return_page = "https://intranet.crans.org/monCompte/paypalCancel",
+ )},
+ }
+ rechargerCompteImpression.exposed = True
+
+ def paypalReturn(self, **kw):
+ _crans_cp.log("retour de paypal avec les infos : %s" % " ".join( [ "[%s: %s]" % (str(a), str(kw[a])) for a in kw] ) )
+ return {
+ 'template' :'MonComptePaypalReturn',
+ 'standalone' :True,
+ 'values' :{},
+ }
+ paypalReturn.exposed = True
+
+ def paypalCancel(self, **kw):
+ _crans_cp.log("annulation de paypal avec les infos : %s" % " ".join( [ "[%s: %s]" % (str(a), str(kw[a])) for a in kw] ) )
+ return {
+ 'template' :'MonComptePaypalCancel',
+ 'standalone' :True,
+ 'values' :{},
+ }
+ paypalCancel.exposed = True
+
+
+
+ ###########################################################################
+ # methodes pour changer
+ # des valeurs
+ ###########################################################################
+ #
+ # En fait, les methodes recoivent les valeurs d'un formulaire
+ # (ou equivalent de javascript), font la modification puis
+ # appellent la methode principale d'affichage
+ # en lui passant eventuellement un message a afficher
+ # (pour indiquer la reussite ou non de l'operation)
+ #
+
+ ##########################
+ # Adherent:nom
+ ##########################
+ def changeNomAdherent(self, nouveauNom):
+ adh = cherrypy.session['LDAP'].search('uid=' + cherrypy.session['uid'], 'w')['adherent'][0]
+ try:
+ ancienNom = adh.nom()
+ adh.nom(nouveauNom)
+ adh.save()
+ except ValueError, e:
+ return self.index(error=e.args[0])
+ del adh
+ _crans_cp.log("Change nom : %s -> %s" % (ancienNom, nouveauNom), "MONCOMPTE")
+ return self.index(message=u'Modification réussie')
+ changeNomAdherent.exposed = True
+
+ ##########################
+ # Adherent:password
+ ##########################
+ def changePasswordAdherent(self, ancienPassword, nouveauPassword1, nouveauPassword2):
+ if ancienPassword=='':
+ msg = 'Erreur, mot de passe incorrect'
+ return self.index(error=msg)
+ if nouveauPassword1=='':
+ msg = 'Erreur, le nouveau mot de passe ne doit pas ètre vide.'
+ return self.index(error=msg)
+ if nouveauPassword1!=nouveauPassword2:
+ msg = 'Erreur, la confirmation ne correspond pas au nouveau mot de passe.'
+ return self.index(error=msg)
+
+ adh = cherrypy.session['LDAP'].search('uid=' + cherrypy.session['uid'],'w')['adherent'][0]
+ if adh.checkPassword(ancienPassword):
+ adh.changePasswd(nouveauPassword1)
+ adh.save()
+ msg = u'Changement effectué'
+ else:
+ msg = 'Erreur, mot de passe incorrect'
+ return self.index(error=msg)
+ del adh
+ _crans_cp.log("Change password", "MONCOMPTE")
+ return self.index(message=msg)
+ changePasswordAdherent.exposed = True
+
+
+ ##########################
+ # Adherent:prenom
+ ##########################
+ def changePrenomAdherent(self, nouveauPrenom):
+ adh = cherrypy.session['LDAP'].search('uid=' + cherrypy.session['uid'], 'w')['adherent'][0]
+ try:
+ ancienPrenom = adh.prenom()
+ adh.prenom(nouveauPrenom)
+ adh.save()
+ except ValueError, e:
+ return self.index(error=e.args[0])
+ del adh
+ _crans_cp.log("Change prenom : %s -> %s" % (ancienPrenom, nouveauPrenom), "MONCOMPTE")
+ return self.index(message=u'Modification réussie')
+ changePrenomAdherent.exposed = True
+
+ ##########################
+ # Adherent:tel
+ ##########################
+ def changeTelAdherent(self, nouveauTel):
+ adh = cherrypy.session['LDAP'].search('uid=' + cherrypy.session['uid'], 'w')['adherent'][0]
+ try:
+ ancienTel = adh.tel()
+ adh.tel(nouveauTel)
+ adh.save()
+ except ValueError, e:
+ return self.index(error=e.args[0])
+ del adh
+ _crans_cp.log("Change tel : %s -> %s" % (ancienTel, nouveauTel), "MONCOMPTE")
+ return self.index(message=u'Modification réussie')
+ changeTelAdherent.exposed = True
+
+ ##########################
+ # mail:alias:creation
+ ##########################
+ def newAlias(self, alias):
+ adh = cherrypy.session['LDAP'].search('uid=' + cherrypy.session['uid'],'w')['adherent'][0]
+ if adh.alias().__len__() >= 3 and adh.droits() == []:
+ return self.index(error=u"Vous avez plus de 2 alias. Demander a un cableur pour en rajouter.")
+ try:
+ adh.alias(alias)
+ adh.save()
+ del adh
+ except ValueError, e:
+ return self.index(error=e.args[0])
+ except RuntimeError:
+ return self.index(error=u"Vous possèdez déjà cet alias")
+ except EnvironmentError:
+ return self.index(error=u"Vous possèdez déjà cet alias")
+ _crans_cp.log("Nouvel alias : %s" % alias, "MONCOMPTE")
+ return self.index(message=u'Alias enregistré')
+ newAlias.exposed = True
+
+
+ ##########################
+ # mail:sauver
+ ##########################
+ def saveMailPrefs(self, forwarding_address=None, spanTreatment=None, contourneGreylist=False, rewriteMailHeaders=False):
+ if spanTreatment == 'no':
+ spanTreatment = 'accepte'
+ if spanTreatment == 'mark':
+ spanTreatment = 'marque'
+ if spanTreatment == 'drop':
+ spanTreatment = 'supprime'
+
+ if contourneGreylist == 'oui':
+ contourneGreylist = True
+ if rewriteMailHeaders == 'oui':
+ rewriteMailHeaders = True
+
+ try:
+ adh = cherrypy.session['LDAP'].search('uid=' + cherrypy.session['uid'],'w')['adherent'][0]
+ if forwarding_address!=None:
+ MailConfig(cherrypy.session['uid'], forward=forwarding_address, spam=spanTreatment)
+ adh.contourneGreylist(contourneGreylist)
+ adh.rewriteMailHeaders(rewriteMailHeaders)
+ adh.save()
+ del adh
+ except ValueError, e:
+ return self.index(error=e.args[0])
+ except Exception, e:
+ return self.index(error=u"Une erreur est survenue lors de lenregistrement. Vérifiez que l'adresse mail fournie est correcte.")
+ _crans_cp.log("Change mail prefs", "MONCOMPTE ACTION")
+ return self.index(message=u'Vos préférences ont été enregistrées')
+ saveMailPrefs.exposed = True
+
diff --git a/intranet/modules/monCompte/static/crans_domtab.js b/intranet/modules/monCompte/static/crans_domtab.js
new file mode 100644
index 00000000..ce6a1fce
--- /dev/null
+++ b/intranet/modules/monCompte/static/crans_domtab.js
@@ -0,0 +1,259 @@
+/*
+ DOMtab Version 3.1415927
+ Updated March the First 2006
+ written by Christian Heilmann
+ check blog for updates: http://www.wait-till-i.com
+ free to use, not free to resell
+*/
+
+domtab={
+ tabClass:'domtab', // class to trigger tabbing
+ listClass:'domtabs', // class of the menus
+ activeClass:'active', // class of current link
+ contentElements:'div', // elements to loop through
+ backToLinks:/#top/, // pattern to check "back to top" links
+ printID:'domtabprintview', // id of the print all link
+ showAllLinkText:'show all content', // text for the print all link
+ prevNextIndicator:'doprevnext', // class to trigger prev and next links
+ prevNextClass:'prevnext', // class of the prev and next list
+ prevLabel:'previous', // HTML content of the prev link
+ nextLabel:'next', // HTML content of the next link
+ prevClass:'prev', // class for the prev link
+ nextClass:'next', // class for the next link
+ init:function(){
+ var temp;
+ if(!document.getElementById || !document.createTextNode){return;}
+ var tempelm=document.getElementsByTagName('div');
+ for(var i=0;i');
+document.write('div.domtab>div{display:none;}<');
+document.write('/s'+'tyle>');
diff --git a/intranet/modules/monCompte/static/icon.png b/intranet/modules/monCompte/static/icon.png
new file mode 100644
index 00000000..f2551b9f
Binary files /dev/null and b/intranet/modules/monCompte/static/icon.png differ
diff --git a/intranet/modules/monCompte/static/monCompte.css b/intranet/modules/monCompte/static/monCompte.css
new file mode 100644
index 00000000..28d9ba70
--- /dev/null
+++ b/intranet/modules/monCompte/static/monCompte.css
@@ -0,0 +1,368 @@
+/********************************************
+ *
+********************************************/
+#globalDiv {
+ padding-left:100px;
+}
+
+/* style du titre au dessus des onglet et des titres pour les pages PayPal */
+div.domtab>h1,
+h2 {
+ font-size:1.4em;
+ margin:2px;
+}
+
+
+/********************************************
+ *
+********************************************/
+/* conteneur de l'ensemble */
+div.domtab{
+ padding:3px;
+ width:100%;
+ background:#fad163;
+ clear:left;
+}
+
+/* onglets */
+ul.domtabs{
+ float:left;
+ width:100%;
+ margin:0;
+ padding:0;
+ list-style-type:none;
+
+}
+ul.domtabs li{
+ float:left;
+}
+ul.domtabs a:link,
+ul.domtabs a:visited,
+ul.domtabs a:active,
+ul.domtabs a:hover{
+ font-weight:bold;
+ display:block;
+ padding:0.4em;
+ text-align:center;
+ background:#fad163;
+}
+
+ul.domtabs li.active a:link,
+ul.domtabs li.active a:visited,
+ul.domtabs li.active a:active,
+ul.domtabs li.active a:hover{
+ background:#fff7D7;
+ color:#000;
+ text-decoration:none;
+}
+
+/* les pages */
+div.domtab>div {
+ padding:0;
+ clear:both;
+ border:5px solid #fff7D7;
+}
+/* ancre des pages */
+.mark {
+ height:0;
+ clear:both;
+ display:none;
+}
+
+/********************************************
+ *
+********************************************/
+.tabbed_page {
+ padding:0;
+ margin:0;
+}
+
+ul.tabbed_page {
+ list-style-type:none;
+}
+
+dl.tabbed_page>dt,
+dl.tabbed_page>dd,
+ul.tabbed_page>li {
+ background:#fff7D7;
+ padding:10px;
+ margin:0 0 2px 0;
+ font-weight:bold;
+}
+dl.tabbed_page>dt.last,
+dl.tabbed_page>dd.last,
+ul.tabbed_page>li.last {
+ margin:0 0 0 0;
+}
+
+dl.tabbed_page>dt {
+ width:40%;
+ display:block;
+ height:100%;
+ float:left;
+ clear:left;
+}
+
+dl.tabbed_page>dd {
+ padding-left:45%;
+}
+
+span.actions {
+ display:block;
+ float:right;
+ font-size:0.9em;
+ font-weight:normal;
+}
+.tabbed_page span.actions a {
+ margin:2px 10px;
+}
+
+
+.tabbed_page dl,
+.tabbed_page dl dt,
+.tabbed_page dl dd {
+ margin:0;
+ padding:0;
+}
+
+.tabbed_page dl dt {
+ float:left;
+ margin-right:5px;
+}
+
+.tabbed_page dl dd,
+.tabbed_page p {
+ font-weight:normal;
+ margin:3px;
+}
+
+
+span.valide {
+ color:green;
+ font-weight:bold;
+}
+
+span.invalide {
+ color:red;
+ font-weight:bold;
+}
+
+.clear {
+ clear:both;
+}
+
+ul.tabbed_page li.centrer {
+ padding:10px;
+ margin-left:0;
+ text-align:center;
+}
+
+
+/********************************************
+ *
+********************************************/
+
+.textInputNote {
+ display:block;
+ padding-left:0;
+ font-size:0.8em;
+ font-weight:normal;
+}
+
+dd .textInputNote {
+ padding-left:0;
+}
+li .textInputNote {
+ padding-left:175px;
+}
+
+label.textInputLabel{
+ width:175px;
+ display:block;
+ float:left;
+}
+
+label.checkBoxLabel{
+ float:none;
+ padding-left:175px;
+}
+
+/********************************************
+ *
+********************************************/
+dl#machineList,
+dl#machineList>dt {
+ margin:0;
+ padding:0;
+}
+#machineList>dt {
+
+ font-size:1.2em;
+ font-weight:bold;
+ margin:5px 5px 5px 5px;
+ height:30px;
+ padding:10px 20px;
+ background:#fff7D7;
+}
+#machineList>dd {
+ margin:0 0 2px 0;
+}
+.linkToggle {
+ display:block;
+ float:left;
+ height:15px;
+ width:15px;
+ background:transparent url(../images/fl.png) top left;
+ margin-right:1px;
+}
+/********************************************
+ *
+********************************************/
+.machineDetails {
+ background: #fff7D7;/*/ url(../images/fondFacturesDetails.png) repeat-x top;*/
+ padding:0;
+ /*width:96%;*/
+ display:none;
+ margin:0;
+}
+
+dl.machineInfos dt, dl.machineInfos dd {
+ float:left;
+ margin-top:0;
+ padding:.1em;
+ display:block;
+ width:20%;
+}
+
+dl.machineInfos dt {
+ text-align:right;
+ width:20%;
+
+}
+/********************************************
+ *
+********************************************/
+ul.listeAlias {
+ list-style-type:none;
+ margin:0;
+ padding:0;
+}
+ul.listeAlias li span {
+ color:#666;
+}
+
+
+/********************************************
+ *
+********************************************/
+#loadings {
+ background:#cc0000;
+ position:fixed;
+ top:1px;
+ right:1px;
+ z-index:1000;
+ display:none;
+ padding:2px 3px;
+ color:white;
+}
+
+.messageText {
+ padding:2px 10px;
+ display:block;
+}
+#messagePlaceHolder {
+ height:0;
+ overflow:visible;
+ position:relative;
+ top:-4em;
+}
+
+.message {
+ padding:0;
+ background:#fad163;
+ width:300px;
+ text-align:center;
+ margin : 1px auto 10px auto;
+}
+.errorMessage {
+ display:block;
+ background:white;
+ border:2px #cc0000 solid;
+ padding:5px;
+ text-align:center;
+ min-width:230px;
+ max-width:430px;
+ font-weight:bold;
+ margin : 1px auto 10px auto;
+}
+
+/********************************************
+ *
+********************************************/
+div#popupInnerBody {
+ border:5px solid #fad163;
+ background: #fff7D7;
+ margin:5px;
+ padding:5px;
+}
+
+div#popupInnerBody .liens {
+ list-style-type:none;
+ float:right;
+ height:1em;
+ background: #fff7D7;
+ border-color:#fad163;
+ border-style: none solid solid solid;
+ border-width:3px;
+ margin:0;
+ padding:2px;
+}
+
+div#popupInnerBody .liens a {
+ display:block;
+ height:1em;
+ float : left;
+ margin:0 5px;
+}
+
+a { color:blue; }
+
+/********************************************
+ *
+********************************************/
+
+table.factureDetails {
+ padding:1%;
+ width:96%;
+ margin:0 1% 10px 1%;
+}
+
+
+.tdTotalDetail,
+.tdTotalDetailIntitule {
+ border-top:thin black solid;
+}
+
+.tdTotalDetailIntitule {
+ text-align:right;
+ font-weight:bold;
+}
+
+table.factureDetails th {
+ border-bottom:thin black solid;
+}
+table.factureDetails th,
+table.factureDetails td {
+ border-right:thin black solid;
+ margin:0;
+ padding:5px 20px;
+}
+
+
+
+/********************************************
+ * divers
+********************************************/
+.empty {
+ color:gray;
+}
diff --git a/intranet/modules/monCompte/static/moncompte.js b/intranet/modules/monCompte/static/moncompte.js
new file mode 100644
index 00000000..3abaac7e
--- /dev/null
+++ b/intranet/modules/monCompte/static/moncompte.js
@@ -0,0 +1,41 @@
+function askForName(oldName) {
+ var c = '';
+ while ( c == '')
+ c = prompt("Votre nom :",oldName);
+ if (c == null)
+ return false;
+ else
+ window.location.href= 'changeNomAdherent?nouveauNom=' + c;
+}
+
+
+function askForSurname(oldSurname) {
+ var c = '';
+ while ( c == '')
+ c = prompt("Votre prénom :",oldSurname);
+ if (c == null)
+ return false;
+ else
+ window.location.href= 'changePrenomAdherent?nouveauPrenom=' + c;
+}
+
+function askForTel(oldTel) {
+ var c = '';
+ while ( c == '')
+ c = prompt("Votre numéro de téléphone :",oldTel);
+ if (c == null)
+ return false;
+ else
+ window.location.href= 'changeTelAdherent?nouveauTel=' + c;
+}
+
+
+function newAlias() {
+ var c = '';
+ while ( c == '')
+ c = prompt("Nouvel alias :");
+ if (c == null)
+ return false;
+ else
+ window.location.href= 'newAlias?alias=' + c + "#mailTab";
+}
diff --git a/intranet/modules/monCompte/static/passwordGenerator.js b/intranet/modules/monCompte/static/passwordGenerator.js
new file mode 100644
index 00000000..18b6cf90
--- /dev/null
+++ b/intranet/modules/monCompte/static/passwordGenerator.js
@@ -0,0 +1,66 @@
+/************************************************************************
+ Password generator
+ ************************************************************************/
+
+function GeneratePassword() {
+
+ if (parseInt(navigator.appVersion) <= 3) {
+ alert("Sorry this only works in 4.0 browsers");
+ return false;
+ }
+
+ var length=8;
+ var sPassword = "";
+ length = 10;//document.aForm.charLen.options[document.aForm.charLen.selectedIndex].value;
+
+ var noPunction = false;//(document.aForm.punc.checked);
+ var randomLength = true;//(document.aForm.rLen.checked);
+
+ if (randomLength) {
+ length = Math.random();
+
+ length = parseInt(length * 100);
+ length = (length % 7) + 6
+ }
+
+
+ for (i=0; i < length; i++) {
+
+ numI = getRandomNum();
+ if (noPunction) { while (checkPunc(numI)) { numI = getRandomNum(); } }
+
+ sPassword = sPassword + String.fromCharCode(numI);
+ }
+
+ //document.aForm.passField.value = sPassword
+ c = prompt('Mot de passe généré : ', sPassword)
+ if (c!= null) {
+ document.changePasswordForm.nouveauPassword1.value = c
+ document.changePasswordForm.nouveauPassword2.value = c
+ }
+ return false;
+}
+
+function getRandomNum() {
+
+ // between 0 - 1
+ var rndNum = Math.random()
+
+ // rndNum from 0 - 1000
+ rndNum = parseInt(rndNum * 1000);
+
+ // rndNum from 33 - 127
+ rndNum = (rndNum % 94) + 33;
+
+ return rndNum;
+}
+
+function checkPunc(num) {
+
+ if ((num >=33) && (num <=47)) { return true; }
+ if ((num >=58) && (num <=64)) { return true; }
+ if ((num >=91) && (num <=96)) { return true; }
+ if ((num >=123) && (num <=126)) { return true; }
+
+ return false;
+}
diff --git a/intranet/modules/monCompte/templates/MonComptePaypalCancel.tmpl b/intranet/modules/monCompte/templates/MonComptePaypalCancel.tmpl
new file mode 100644
index 00000000..7bef45d6
--- /dev/null
+++ b/intranet/modules/monCompte/templates/MonComptePaypalCancel.tmpl
@@ -0,0 +1,22 @@
+#import cherrypy
+#set bugMail = cherrypy.config.get("mail.bugreport", "nounous@crans.org")
+
+
+#include "inc-paypal-head.tmpl"
+
+
+
+
Paiement annulé
+
Ton compte impressions sera crédité dés que la facture sera réglée.
+
Tu peux régler la facture plus tard en allant dans Mes Factures
+
En cas de problème, envoie un mail à $bugMail
+
+
+
+
+
+
+
+
diff --git a/intranet/modules/monCompte/templates/MonComptePaypalReturn.tmpl b/intranet/modules/monCompte/templates/MonComptePaypalReturn.tmpl
new file mode 100644
index 00000000..e96cd6c3
--- /dev/null
+++ b/intranet/modules/monCompte/templates/MonComptePaypalReturn.tmpl
@@ -0,0 +1,21 @@
+#import cherrypy
+#set bugMail = cherrypy.config.get("mail.bugreport", "nounous@crans.org")
+
+
+#include "inc-paypal-head.tmpl"
+
+
+