diff --git a/development.ini b/development.ini index 5141ce0..db3d97b 100644 --- a/development.ini +++ b/development.ini @@ -22,6 +22,7 @@ sqlalchemy.url = mysql://phuoc:phuoc!@localhost/bddevfac?charset=utf8 # sqlalchemy.url = mysql://root:cni/@srvbd/bddevfac?charset=utf8 mondumas.admin_email = ctphuoc@bbox.fr +mondumas.DEVFAC14 = mondumas:static/img/DEVFAC14/ # Mailer configuration mail.host = smtp.free.fr diff --git a/mondumas.egg-info/PKG-INFO b/mondumas.egg-info/PKG-INFO index 24f21d2..442dec3 100644 --- a/mondumas.egg-info/PKG-INFO +++ b/mondumas.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: mondumas -Version: 0.1 +Version: 1.0 Summary: mondumas Home-page: UNKNOWN Author: @@ -9,16 +9,16 @@ License: UNKNOWN Description: # README # - Application web permettant aux personnels de l'entreprise Dumas d'accéder aux dossiers des clients + Application web permettant aux personnels de l'entreprise Dumas d'accéder aux dossiers des clients - Développé avec : + Développé avec : - Pyramid Framework - MySQL - Chameleon - * [Exemple d'une comptabilité simple] (http://perso.numericable.fr/assoc1901/droit/comptabilite1.htm) + * [Exemple d'une comptabilité simple] (http://perso.numericable.fr/assoc1901/droit/comptabilite1.htm) * [Learn Markdown](https://bitbucket.org/tutorials/markdowndemo) diff --git a/mondumas.egg-info/SOURCES.txt b/mondumas.egg-info/SOURCES.txt index 416ba65..c757d95 100644 --- a/mondumas.egg-info/SOURCES.txt +++ b/mondumas.egg-info/SOURCES.txt @@ -21,10 +21,12 @@ mondumas.egg-info/top_level.txt mondumas/models/__init__.py mondumas/models/agenda.py mondumas/models/default.py +mondumas/models/dossier.py mondumas/models/parametres.py mondumas/scripts/__init__.py mondumas/views/__init__.py mondumas/views/agenda.py mondumas/views/default.py +mondumas/views/dossier.py mondumas/views/notfound.py mondumas/views/parametres.py \ No newline at end of file diff --git a/mondumas.egg-info/requires.txt b/mondumas.egg-info/requires.txt index 2555866..fbe21fc 100644 --- a/mondumas.egg-info/requires.txt +++ b/mondumas.egg-info/requires.txt @@ -1,16 +1,17 @@ -SQLAlchemy -docutils -mysqlclient pyramid pyramid_chameleon pyramid_debugtoolbar pyramid_layout pyramid_mailer pyramid_tm -python-dateutil +SQLAlchemy transaction -waitress zope.sqlalchemy +waitress +mysqlclient +python-dateutil +docutils +user-agents [testing] WebTest>=1.3.1 diff --git a/mondumas/layout.py b/mondumas/layout.py index 988c0c2..1f564fe 100644 --- a/mondumas/layout.py +++ b/mondumas/layout.py @@ -3,8 +3,10 @@ from pyramid_layout.layout import layout_config from .security import groupfinder from .views.default import ( to_euro, + to_euroz, to_percent, to_decimal, + to_decz, ) @layout_config(template='templates/layouts/global_layout.pt') @@ -22,6 +24,12 @@ class GlobalLayout(object): def to_euro(self, x): return to_euro(x) + def to_euroz(self, x): + return to_euroz(x) + + def to_decz(self, x): + return to_euroz(x) + def to_percent(self, x): return to_percent(x) diff --git a/mondumas/models/agenda.py b/mondumas/models/agenda.py index 4341cf4..f8f9a9b 100644 --- a/mondumas/models/agenda.py +++ b/mondumas/models/agenda.py @@ -20,42 +20,20 @@ def execute_query(request, query, params): mark_changed(request.dbsession) transaction.commit() -def get_users_agenda(request): - """ lire la liste des users ayant un agenda""" - query = "SELECT * FROM p_users WHERE cd_uti != 'N' and agenda != 0 AND actif != 0 ORDER BY nom;" - results = request.dbsession.execute(query).fetchall() - return results - -def get_dossier_by_no(request,nodossier): - societe = nodossier[0:2] - no_id = nodossier[3:] - query = """ -SELECT d.*, c.*, a.NOM as nom_cabinet, e.NOM as nom_expert FROM dem_devis d -INNER JOIN clients c ON d.societe = c.societe and d.cd_cli = c.cd_cli -INNER JOIN p_cabinet a ON d.cabinet = a.code -INNER JOIN p_experts e ON d.cabinet = e.code_cab and d.expert = e.code_exp -where d.societe = '%s' and d.no_id=%s;""" % (societe, no_id); - results = request.dbsession.execute(query).first() - return results - -def get_dossier_rdv_by_no(request,nodossier, nolig): - societe = nodossier[0:2] - no_id = nodossier[3:] - - if nolig == '0': - query = "SELECT * FROM dem_lig where societe = '%s' and no_id=%s;" % (societe, no_id) +def get_users_agenda(request, user): + if user == '': + """ lire la liste des users ayant un agenda""" + query = "SELECT * FROM p_users WHERE cd_uti != 'N' and agenda != 0 AND actif != 0 ORDER BY nom;" results = request.dbsession.execute(query).fetchall() else: - query = "SELECT * FROM dem_lig where societe = '%s' and no_id=%s and nolig=%s;" % (societe, no_id, nolig) - results = request.dbsession.execute(query).first() - + """ lire le user ayant un agenda""" + query = "SELECT * FROM p_users WHERE cd_uti = :user and agenda != 0 AND actif != 0 ORDER BY nom;" + results = request.dbsession.execute(query, {'user': user}).first() return results -def get_documents_byChantier(request,nodossier): - societe = nodossier[0:2] - no_id = nodossier[3:] - - query = "CALL spGET_DOSSIERS_byNumeo('%s',%s);" % (societe, no_id) +def get_types_rdv(request): + """ lire la liste des types de rendez-vous""" + query = "SELECT * FROM p_types_rdv ORDER BY LIB;" results = request.dbsession.execute(query).fetchall() return results @@ -66,7 +44,7 @@ def get_rendez_vous(request, itc): datedeb = d.strftime('%Y-%m-01') # lire les rdv de l'ITC - query = """SELECT CONCAT(l.societe,"-",l.no_id) as nodossier, l.rdv_debut, l.rdv_fin, e.c_nom, e.c_ville FROM dem_lig l + query = """SELECT CONCAT(l.societe,"-",l.no_id) as nodossier, l.nolig, l.rdv_debut, l.rdv_fin, e.c_qualite, e.c_nom, e.c_ville, e.c_cp FROM dem_lig l INNER JOIN dem_devis e ON l.societe=e.societe AND l.no_id=e.no_id WHERE l.datevi >= :datedeb AND l.liste=:itc ORDER BY l.datevi, l.heurevi """ @@ -80,20 +58,36 @@ def delete_rdv(request, nodossier, nolig): query = "DELETE FROM dem_lig where societe = '%s' and no_id=%s and nolig=%s;" % (societe, no_id, nolig) execute_query(request, query, {}) -def update_rdv(request, nodossier, nolig, comment, commentvi, date_rdv): +def update_rdv(request, nodossier, nolig, new_values): societe = nodossier[0:2] no_id = nodossier[3:] - # formater les champs - ddate = datetime.strptime(date_rdv, '%d-%m-%Y %H:%M') - datevi = ddate.strftime("%Y-%m-%d") - heurevi = date_rdv[-5:] - auj = date.today().strftime("%Y-%m-%d") + # formater date et heure de visite + if new_values['rdv_debut']: + ddate = datetime.strptime(new_values['rdv_debut'], '%d-%m-%Y %H:%M') + new_values['DATEVI'] = ddate.strftime("%Y-%m-%d") + new_values['HEUREVI'] = ddate.strftime("%H:%M") - if nolig == '0': - query = "INSERT INTO dem_devis SET societe='%s',no_id=%s,date='%s',datevi='%s',heurevi='%s',comment='%s',commentvi='%s'" % (societe, no_id,auj,datevi, heurevi, comment, commentvi) - else: - query = "UPDATE dem_ligs SET datevi='%s', heurevi='%s', comment='%s', commentvi='%s' where societe = '%s' and no_id=%s and nolig=%s;" % (datevi, heurevi, comment, commentvi, societe, no_id, nolig) + del new_values['rdv_debut'] + s = '' + for param in new_values.keys(): + if s: + s += ",%s=:%s" % (param, param) + else: + s = "%s=:%s" % (param, param) - execute_query(request, query, {}) + new_values['societe'] = societe + new_values['no_id'] = no_id + new_values['nolig'] = nolig + query = "UPDATE dem_lig SET %s WHERE societe = :societe AND NO_ID = :no_id AND NOLIG = :nolig ;" % s + execute_query(request, query, new_values) + +def create_rdv(request, nodossier, dateRDV, heureRDV, type_rdv, agenda, logged_in): + societe = nodossier[0:2] + no_id = nodossier[3:] + + query = """ +INSERT INTO dem_lig (societe, NO_ID, DATE, COMMENT, DATEVI, HEUREVI, LISTE, USERMAJ) VALUES +(:societe, :no_id, CURRENT_DATE, :type_rdv, :dateRDV, :heureRDV, :agenda, :logged_in) ;""" + execute_query(request, query, {'societe': societe, 'no_id' :no_id, 'dateRDV': dateRDV, 'heureRDV': heureRDV, 'type_rdv': type_rdv, 'agenda': agenda, 'logged_in':logged_in}) diff --git a/mondumas/models/default.py b/mondumas/models/default.py index 32c02da..aaa863d 100644 --- a/mondumas/models/default.py +++ b/mondumas/models/default.py @@ -35,25 +35,24 @@ def get_member_by_id(request, mbr_id): return results def update_membre_mdp_oublie(request, login): - import base64 - import uuid - # get a UUID - URL safe, Base64 - r_uuid = base64.urlsafe_b64encode(uuid.uuid4().bytes) - r_uuid = r_uuid.replace('=', '') - query = "UPDATE p_users SET mdp_oublie=:r_uuid, mdp_oublie_date=now() WHERE CD_UTI=:login;" - execute_query(request, query, {'r_uuid':r_uuid, 'login':login}) - return r_uuid + + uid = uuid.uuid1() + urlslug = base64.urlsafe_b64encode(uid.bytes).decode("utf-8").rstrip('=\n').replace('/', '_') + query = "UPDATE p_users SET mdp_oublie=:urlslug, mdp_oublie_date=now() WHERE CD_UTI=:login;" + execute_query(request, query, {'urlslug':urlslug, 'login':login}) + + return urlslug def update_membre_mdp(request, login, password): """Update password for member login""" query = "UPDATE p_users SET mdp = SHA1(:password), mdp_oublie=NULL, mdp_oublie_date=NULL WHERE cd_uti=:login;" execute_query(request, query, {'login': login, 'password': password}) -def update_last_connection(request, login): +def update_last_connection(request, login, ua_string): """Update last connection for login """ - query = "UPDATE p_users SET dern_cnx_le=NOW() WHERE cd_uti=:login;" - execute_query(request, query, {'login': login}) + query = "UPDATE p_users SET dern_cnx_le=NOW(), ua_string=:ua_string WHERE cd_uti=:login;" + execute_query(request, query, {'login': login, 'ua_string': ua_string}) def update_membre(request, cd_uti, new_values): # formater les champs @@ -81,9 +80,3 @@ def delete_membre(request, cd_uti): query = "DELETE FROM p_users WHERE cd_uti = :cd_uti ;" execute_query(request, query, {'cd_uti': cd_uti}) -def get_chantiers_byName(request, societe, name, tous): - - query = "CALL spGET_CHANTIERS_byName('%s','%s');" % (societe, name) - results = request.dbsession.execute(query).fetchall() - return results - diff --git a/mondumas/models/dossier.py b/mondumas/models/dossier.py new file mode 100644 index 0000000..a907564 --- /dev/null +++ b/mondumas/models/dossier.py @@ -0,0 +1,161 @@ +# -*- coding: utf8 -*- +from sqlalchemy import text +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import ( + scoped_session, + sessionmaker, +) +from zope.sqlalchemy import ( + ZopeTransactionExtension, + mark_changed +) + +from datetime import * +import transaction + +def execute_query(request, query, params): + """Execute query and mark session as changed""" + request.dbsession.execute(query, params) + mark_changed(request.dbsession) + transaction.commit() + +def get_chantiers_byName(request, societe, name, tous): + + query = "CALL spGET_CHANTIERS_byName('%s','%s');" % (societe, name) + results = request.dbsession.execute(query).fetchall() + return results + +def get_dossier_by_no(request,nodossier): + societe = nodossier[0:2] + no_id = nodossier[3:] + query = """ +SELECT d.*, c.*, a.NOM as nom_cabinet, e.NOM as nom_expert FROM dem_devis d +INNER JOIN clients c ON d.societe = c.societe and d.cd_cli = c.cd_cli +INNER JOIN p_cabinet a ON d.cabinet = a.code +INNER JOIN p_experts e ON d.cabinet = e.code_cab and d.expert = e.code_exp +where d.societe = '%s' and d.no_id=%s;""" % (societe, no_id); + results = request.dbsession.execute(query).first() + return results + +def get_devis_by_no(request,nodossier): + societe = nodossier[0:2] + type_doc = nodossier[3:5] + no_id = nodossier[5:] + + if type_doc == 'DE': + query = """ + SELECT d.*, c.*, a.NOM as nom_cabinet, e.NOM as nom_expert FROM devis d + INNER JOIN clients c ON d.societe = c.societe and d.cd_cli = c.cd_cli + INNER JOIN p_cabinet a ON d.cabinet = a.code + INNER JOIN p_experts e ON d.cabinet = e.code_cab and d.expert = e.code_exp + WHERE d.societe = :societe and d.no_id=:no_id;""" + elif type_doc == 'FA': + query = """ + SELECT d.*, c.*, a.NOM as nom_cabinet, e.NOM as nom_expert FROM facture d + INNER JOIN clients c ON d.societe = c.societe and d.cd_cli = c.cd_cli + INNER JOIN p_cabinet a ON d.cabinet = a.code + INNER JOIN p_experts e ON d.cabinet = e.code_cab and d.expert = e.code_exp + WHERE d.societe = :societe and d.no_id=:no_id;""" + else: + query = """ + SELECT d.*, c.*, a.NOM as nom_cabinet, e.NOM as nom_expert FROM proforma d + INNER JOIN clients c ON d.societe = c.societe and d.cd_cli = c.cd_cli + INNER JOIN p_cabinet a ON d.cabinet = a.code + INNER JOIN p_experts e ON d.cabinet = e.code_cab and d.expert = e.code_exp + WHERE d.societe = :societe and d.no_id=:no_id;""" + + results = request.dbsession.execute(query, {'societe': societe, 'no_id': no_id}).first() + return results + +def get_dossier_rdv_by_no(request,nodossier, nolig): + societe = nodossier[0:2] + no_id = nodossier[3:] + + if nolig == '0': + query = "SELECT * FROM dem_lig WHERE societe = :societe AND no_id = :no_id;" + results = request.dbsession.execute(query, {'societe': societe, 'no_id': no_id}).fetchall() + else: + query = """ +SELECT l.*, d.C_QUALITE, d.C_NOM FROM dem_lig l INNER JOIN dem_devis d ON l.societe = d.societe and l.no_id = d.no_id +where l.societe = '%s' and l.no_id=%s and l.nolig=%s;""" % (societe, no_id, nolig) + results = request.dbsession.execute(query).first() + + return results + +def get_documents_byChantier(request,nodossier): + societe = nodossier[0:2] + no_id = nodossier[3:] + + query = "CALL spGET_DOSSIERS_byNumeo('%s',%s);" % (societe, no_id) + results = request.dbsession.execute(query).fetchall() + return results + +def update_suivi(request, nodossier, nolig, new_values): + societe = nodossier[0:2] + no_id = nodossier[3:] + + new_values['societe'] = societe + new_values['NO_ID'] = no_id + s = '' + for param in new_values.keys(): + if s: + s += ",%s=:%s" % (param, param) + else: + s = "%s=:%s" % (param, param) + + if nolig == '0': + query = "INSERT INTO dem_lig SET %s" % s + else: + new_values['nolig'] = nolig + query = "UPDATE dem_lig SET %s WHERE societe = :societe AND NO_ID = :no_id AND NOLIG = :nolig ;" % s + + execute_query(request, query, new_values) + +def get_similaires_byChantier(request, societe, C_NOM, C_ADR, C_CP, C_VILLE): + + query = """ +SELECT CONCAT(societe,'-',NO_ID) AS nodossier, dem_devis.* FROM dem_devis +WHERE societe<>:societe AND C_NOM=:C_NOM AND C_ADR=:C_ADR AND C_CP=:C_CP AND C_VILLE=:C_VILLE;""" + results = request.dbsession.execute(query, {'societe': societe, 'C_NOM': C_NOM, 'C_ADR': C_ADR, 'C_CP': C_CP, 'C_VILLE': C_VILLE}).fetchall() + + return results + +def get_devis_lig_by_no(request,nodossier): + + societe = nodossier[0:2] + type_doc = nodossier[3:5] + no_id = nodossier[5:] + + if type_doc == 'DE': + query = "SELECT * FROM devis_lig WHERE societe = :societe and no_id=:no_id;" + elif type_doc == 'FA': + query = "SELECT * FROM facture_lig WHERE societe = :societe and no_id=:no_id;" + else: + query = "SELECT * FROM proforma_lig WHERE societe = :societe and no_id=:no_id;" + + results = request.dbsession.execute(query, {'societe': societe, 'no_id': no_id}).fetchall() + return results + +def get_docs_attaches(request, nomrep, nodossier): + societe = nodossier[0:2] + nochantier = int(nodossier[3:]) + + query = "SELECT * FROM dossier_attaches WHERE nomrep = :nomrep AND societe = :societe AND nochantier = :nochantier ORDER BY cree_le;" + results = request.dbsession.execute(query, {'nomrep': nomrep, 'societe': societe, 'nochantier': nochantier}).fetchall() + + return results + +def update_dossier(request, nodossier, new_values): + societe = nodossier[0:2] + nochantier = int(nodossier[3:]) + + s = '' + for param in new_values.keys(): + if s: + s += ",%s=:%s" % (param, param) + else: + s = "%s=:%s" % (param, param) + new_values['societe'] = societe + new_values['nochantier'] = nochantier + query = u"UPDATE dem_devis SET %s WHERE societe=:societe AND no_id=:nochantier" % s + execute_query(request, query, new_values) diff --git a/mondumas/models/parametres.py b/mondumas/models/parametres.py index f184bb5..a34999e 100644 --- a/mondumas/models/parametres.py +++ b/mondumas/models/parametres.py @@ -32,3 +32,25 @@ def get_last_emailing(request): results = request.dbsession.execute(query, {}) return results.fetchall() +def get_orphans_DE(request, societe): + + query = "SELECT * FROM devis WHERE societe = '%s' AND nochantier = 0 ORDER BY date desc LIMIT 50 ;" % (societe) + results = request.dbsession.execute(query).first() + return results + +def get_dossiers_byChantier(request, societe, name): + + query = "CALL spGET_DOSSIERS_byChantier('%s','%s','%s');" % (societe, 'DE', name.replace("'","''")) + results = request.dbsession.execute(query).fetchall() + return results + +def update_nochantier(request, societe, nodossier, nochantier): + x = nodossier.split('-') + type = x[0] + no_id = int(x[1]) + + if type == 'DE': + query = "UPDATE devis SET nochantier = :nochantier WHERE societe = :societe and no_id = :no_id;" + else: + query = "UPDATE facture SET nochantier = :nochantier WHERE societe = :societe and no_id = :no_id;" + execute_query(request, query, {'societe': societe, 'no_id': no_id, 'nochantier': nochantier}) diff --git a/mondumas/routes.py b/mondumas/routes.py index 4311cda..deeb331 100644 --- a/mondumas/routes.py +++ b/mondumas/routes.py @@ -1,19 +1,29 @@ def includeme(config): config.add_static_view('static', 'static', cache_max_age=3600) - config.add_route('home', '/') - config.add_route('agenda', '/agenda') - config.add_route('planning', '/planning') - config.add_route('chantier_lookup', '/chantier_lookup') - config.add_route('changer_mdp', '/changer_mdp') - config.add_route('dossier_view', '/dossier_view/{nodossier}') + # agenda + config.add_route('agenda', '/agenda/{date}') + config.add_route('planning', '/planning/{date}') config.add_route('rdv_edit','/rdv_edit/{nodossier}/{nolig}') + # default + config.add_route('home', '/') + config.add_route('changer_mdp', '/changer_mdp') config.add_route('envoyer_mdp', '/envoyer_mdp') config.add_route('login', '/login') config.add_route('logout', '/logout') config.add_route('redefinir_mdp', '/redefinir_mdp/{lien}') + config.add_route('suivi_edit','/suivi_edit/{nodossier}/{nolig}') + # dossier + config.add_route('dossier_edit', '/dossier_edit/{nodossier}') + config.add_route('dossier_lookup', '/chantier_lookup') + config.add_route('dossier_select', '/dossier_select/{date}') + config.add_route('dossier_selected', '/dossier_selected/{goto}/{date}/{nodossier}') + config.add_route('dossier_view', '/dossier_view/{nodossier}') + config.add_route('devis_view', '/devis_view/{nodossier}') # parametres config.add_route('parametres', '/parametres') config.add_route('dashboard', '/dashboard') config.add_route('last_emailing', '/last_emailing') + config.add_route('orphans_de', '/orphans_de/{societe}') config.add_route('user_edit', '/user_edit/{cd_uti}') config.add_route('users_list', '/users_list') + config.add_route('users_ua', '/users_ua') diff --git a/mondumas/static/css/style.less b/mondumas/static/css/style.less index 5f41384..d5acee2 100644 --- a/mondumas/static/css/style.less +++ b/mondumas/static/css/style.less @@ -46,6 +46,14 @@ color: #000000 !important; } +.modal-dialog { + position: absolute; + margin-left: 200px; + height: 500px; + top: 80px; + +} + #footer { text-align: center; color: #428BCA; @@ -97,3 +105,23 @@ .logo-small { font-size: 50px; } +.bg-PE { + background-color: #ffffb3 !important; + color: black; +} +.bg-ME { + background-color: #ffe44d !important; + color: black; +} +.bg-PL { + background-color: #b3ff66 !important; + color: black; +} +.bg-PO { + background-color: #b1dae7 !important; + color: black; +} +.bg-CD { + background-color: #ffb3cc !important; + color: black; +} diff --git a/mondumas/static/img/link2DEVFAC14.txt b/mondumas/static/img/link2DEVFAC14.txt new file mode 100644 index 0000000..150f17b --- /dev/null +++ b/mondumas/static/img/link2DEVFAC14.txt @@ -0,0 +1,5 @@ +-- Windows 10, lecteur local +mklink /J DEVFAC14 C:\DEVFAC14 + +-- Windows server, lecteur réseau +mklink /D DEVFAC14 \\SRVTSE\DEVFAC14 diff --git a/mondumas/templates/agenda/agenda.pt b/mondumas/templates/agenda/agenda.pt index ff577bc..a8e2ac3 100644 --- a/mondumas/templates/agenda/agenda.pt +++ b/mondumas/templates/agenda/agenda.pt @@ -1,14 +1,12 @@
-
+
-
-
-
- +
+ +
+ +
+
-

- RDV Peinture  - RDV Menuiserie  - RDV Plomberie  - RDV Plomberie  -

+
+ +
+ + +
+
- -
-
+
+


+

+ RDV Peinture  + RDV Menuiserie  + RDV Plomberie  + RDV Polynet  + RDV Couleurs & Déco  +


- + + + +
diff --git a/mondumas/templates/agenda/planning.pt b/mondumas/templates/agenda/planning.pt index d86b583..6c706af 100644 --- a/mondumas/templates/agenda/planning.pt +++ b/mondumas/templates/agenda/planning.pt @@ -1,38 +1,30 @@
-
+
-
-
- -
-

- RDV Peinture  - RDV Menuiserie  - RDV Plomberie  - RDV Plomberie  -

-
-
-
-


+

+ RDV Peinture  + RDV Menuiserie  + RDV Plomberie  + RDV Polynet  + RDV Couleurs & Déco  +


- +
+
+ + +
+
diff --git a/mondumas/templates/chantier_lookup.pt b/mondumas/templates/dossier/dossier_lookup.pt similarity index 96% rename from mondumas/templates/chantier_lookup.pt rename to mondumas/templates/dossier/dossier_lookup.pt index 8d08ef4..4be5bd0 100644 --- a/mondumas/templates/chantier_lookup.pt +++ b/mondumas/templates/dossier/dossier_lookup.pt @@ -73,6 +73,7 @@ + +
+ diff --git a/mondumas/templates/layouts/global_layout.pt b/mondumas/templates/layouts/global_layout.pt index d02b8ab..7b25be0 100644 --- a/mondumas/templates/layouts/global_layout.pt +++ b/mondumas/templates/layouts/global_layout.pt @@ -14,6 +14,7 @@ + @@ -33,6 +34,7 @@ + @@ -95,7 +97,8 @@ diff --git a/mondumas/templates/parametres/orphans_de.pt b/mondumas/templates/parametres/orphans_de.pt new file mode 100644 index 0000000..ae37821 --- /dev/null +++ b/mondumas/templates/parametres/orphans_de.pt @@ -0,0 +1,156 @@ + +
+ +
+ +
+
+ +
+ +
+
+
+ + + +
+ +
+ + + + + + + + + +

CHANTIER

+

${devis.C_QUALITE} ${devis.C_NOM}

+ ${devis.C_ADR}
+ ${devis.C_ADR2}
+ ${devis.C_CP} ${devis.C_VILLE}
+
+ Police
+ Sinistre
+
+ ${devis.NOPOL}
+ ${devis.NOSIN}
+
+
+
+ + + + + +
+

CLIENT

+ NO DEVIS
+ DATE
+
+

${devis.NOMCLI}

+ ${devis.NO_ID}
+ ${devis.DATE.strftime('%d-%m-%Y')} +
+
+
+ +
+
+ +
+ +
+
+ +   (Veuillez cocher un ou plusieurs dossiers pour mettre à jour leur no de chantier) +
+
+
+ +
+ + + + + + + + + + + + + +
NuméroDateClientChantierMontantSinistreCh.
+
+
+
+ + + +
+ diff --git a/mondumas/templates/parametres/parametres.pt b/mondumas/templates/parametres/parametres.pt index 5bd4ec7..b09b4b0 100644 --- a/mondumas/templates/parametres/parametres.pt +++ b/mondumas/templates/parametres/parametres.pt @@ -7,10 +7,18 @@

UTILISATEURS

+
+ +

CONNEXIONS

+

TABLEAU de BORD

+
+ +

DEVIS ORPHELINS

+


diff --git a/mondumas/templates/parametres/user_edit.pt b/mondumas/templates/parametres/user_edit.pt index f9a9c68..074c5ce 100644 --- a/mondumas/templates/parametres/user_edit.pt +++ b/mondumas/templates/parametres/user_edit.pt @@ -11,9 +11,9 @@ data-fv-icon-validating="glyphicon glyphicon-refresh">
- +
-
- +
-
-
diff --git a/mondumas/templates/parametres/users_list.pt b/mondumas/templates/parametres/users_list.pt index 4b0804e..034f51c 100644 --- a/mondumas/templates/parametres/users_list.pt +++ b/mondumas/templates/parametres/users_list.pt @@ -16,7 +16,6 @@ Email Agenda Rôle - Dern cnx Etat diff --git a/mondumas/templates/parametres/users_ua.pt b/mondumas/templates/parametres/users_ua.pt new file mode 100644 index 0000000..d6a1d86 --- /dev/null +++ b/mondumas/templates/parametres/users_ua.pt @@ -0,0 +1,46 @@ + +
+ +

+ + Retour + + Nouveau utilisateur +

+ + + + + + + + + + +
Dern cnxLoginNom, PrénomAppareil utilisé
+ +
+
+ + + +
+
+ + diff --git a/mondumas/templates/security.py b/mondumas/templates/security.py deleted file mode 100644 index c27e419..0000000 --- a/mondumas/templates/security.py +++ /dev/null @@ -1,11 +0,0 @@ -from .models.default import get_member_by_id - -def groupfinder(userid, request): - member = get_member_by_id(request, userid) - - if member: - # Roles administrateur ? - if member.access == 9: - return ['group:administrators'] - else: - return [] # it means that userid is logged in (it returns None if userid isn't logged in) diff --git a/mondumas/views/agenda.py b/mondumas/views/agenda.py index 99415f9..2c81e2c 100644 --- a/mondumas/views/agenda.py +++ b/mondumas/views/agenda.py @@ -21,87 +21,98 @@ from ..security import groupfinder import json from ..models.agenda import * -from ..models.default import * +from ..models.dossier import * @view_config(route_name='rdv_edit', renderer='../templates/agenda/rdv_edit.pt', permission='view') def rdv_edit(request): + + logged_in = request.authenticated_userid.upper() nodossier = request.matchdict['nodossier'] nolig = request.matchdict['nolig'] + + # creation d'un rdv ? + if nolig == '0': + # lire le user avec agenda + agenda = get_users_agenda(request, logged_in) + if agenda: + aujourdhui = datetime.now() + create_rdv(request, nodossier, aujourdhui.strftime("%Y-%m-%d"), aujourdhui.strftime("%H:00"), 'RDV DEVIS', logged_in, logged_in) + request.session.flash(u"Le rendez-vous a été CREE avec succès.", 'success') + else: + request.session.flash(u"Vous ne pouvez pas créer de rendez-vous.", 'danger') + return HTTPFound(location=request.route_url('dossier_view', nodossier=nodossier)) + url = request.route_url("rdv_edit", nodossier=nodossier, nolig=nolig) message = '' - if nolig == '0': - # nouveau - comment = '' - commentvi = '' - date_rdv = datetime.now() - page_title= 'Nouveau rendez-vous' - else: - # lire le rendez-vous - rdv = get_dossier_rdv_by_no(request, nodossier, nolig) - if not rdv: - request.session.flash(u"Rendez-vous non trouvé : %s" % nodossier, 'warning') - return HTTPFound(location=request.route_url('dossier_view', nodossier=nodossier)) + # lire le rendez-vous + rdv = get_dossier_rdv_by_no(request, nodossier, nolig) + if not rdv: + request.session.flash(u"Rendez-vous non trouvé : %s" % nodossier, 'warning') + return HTTPFound(location=request.route_url('agenda', date='today')) - comment = rdv.COMMENT - commentvi = rdv.COMMENTVI - date_rdv = rdv.rdv_debut - page_title= u"Modification du rdv du %s" % (rdv.rdv_debut.strftime('%d-%m-%Y %H:%M')) + # memorize nodossier et nom dossier + request.session['mem_nodossier'] = nodossier + request.session['mem_nomdossier'] = '%s %s' % (rdv.C_QUALITE, rdv.C_NOM) + page_title= u"Modification du rdv du %s" % (rdv.rdv_debut.strftime('%d-%m-%Y %H:%M')) if 'form.submitted' in request.params: - comment = request.params['comment'] - commentvi = request.params['commentvi'] - date_rdv = request.params['date_rdv'] + new_values = {} + for param, db_value in rdv.items(): + if param in request.params and request.params[param] != db_value: + new_values[param] = request.params[param] - update_rdv(request, nodossier, nolig, comment, commentvi, date_rdv) - request.session.flash(u"Le rendez-vous a été mis à jour avec succès.", 'success') - return HTTPFound(location=request.route_url('dossier_view', nodossier=nodossier)) + if new_values: + new_values['USERMAJ'] = logged_in.upper() + + update_rdv(request, nodossier, nolig, new_values) + request.session.flash(u"Le rendez-vous a été mis à jour avec succès.", 'success') + + return HTTPFound(location=request.route_url('agenda', date=rdv.rdv_debut.strftime('%Y-%m-%d'))) if 'form.deleted' in request.params: delete_rdv(request, nodossier, nolig) request.session.flash(u"Le rendez-vous a été supprimé avec succès.", 'success') - return HTTPFound(location=request.route_url('dossier_view', nodossier=nodossier)) + return HTTPFound(location=request.route_url('agenda', date=rdv.rdv_debut.strftime('%Y-%m-%d'))) return { 'page_title': page_title, 'url': url, + 'logged_in': logged_in, 'nodossier': nodossier, 'nolig': nolig, - 'comment': comment, - 'commentvi': commentvi, - 'date_rdv': date_rdv, + 'rdv': rdv, 'message': message, } -@view_config(route_name='dossier_view', renderer='../templates/agenda/dossier_view.pt', permission='view') -def dossier_view(request): - nodossier = request.matchdict['nodossier'] - url = request.route_url("dossier_view", nodossier=nodossier) - - dossier = get_dossier_by_no(request, nodossier) - if dossier is None: - request.session.flash(u"Le dossier no %s est introuvable" % (nodossier), 'danger') - return HTTPFound(location=request.route_url("chantier_lookup")) - # lire tous le suivi du dossier - details = get_dossier_rdv_by_no(request, nodossier, '0') - # lire toutes les dossiers du chantiers - documents = get_documents_byChantier(request, nodossier) - return { - 'page_title': u"Dossier : %s" % (nodossier), - 'nodossier': nodossier, - 'dossier': dossier, - 'details': details, - 'documents': documents, - } - - @view_config(route_name='agenda', renderer='../templates/agenda/agenda.pt', permission='view') def agenda(request): + + message = '' + # récupérer les paramètres de l'appel de la view + datePlan = request.matchdict['date'] logged_in = request.authenticated_userid + + if datePlan == 'today': + datePlan = date.today().strftime('%Y-%m-%d') + url = request.route_url('agenda', date=datePlan) + url_select = request.route_url('dossier_select', date=datePlan) + + # recall code et nom élève + if 'mem_nodossier' in request.session: + mem_nodossier = request.session['mem_nodossier'] + mem_nomdossier = request.session['mem_nomdossier'] + else: + mem_nodossier = 'Aucun' + mem_nomdossier = u'dossier sélectionné' + + # liste des types de rdv + types_rdv = get_types_rdv(request) + type_rdv = u'RDV DEVIS' # liste des users avec agenda - agendas = get_users_agenda(request) + agendas = get_users_agenda(request, '') # le user a-t-il un agenda ? agenda = 'JMD' @@ -114,30 +125,42 @@ def agenda(request): if 'agenda' in request.params: agenda = request.params["agenda"] - rows = get_rendez_vous(request, agenda) + # -- CREER un rendez-vous + if 'form.submitted' in request.params and mem_nodossier != 'Aucun': + dateRDV = request.params['dateRDV'] + heureRDV = request.params['heureRDV'] + type_rdv = request.params['type_rdv'] + + create_rdv(request, mem_nodossier, dateRDV, heureRDV, type_rdv, agenda, logged_in.upper()) + request.session.flash(u"Le rendez-vous a été CREE avec succès.", 'success') + rows = get_rendez_vous(request, agenda) + # construire la liste des events events = [] for row in rows: # déterminer la couleur de l'event selon la societe societe = row.nodossier[0:2] if societe == "PE": - color = "LightYellow" + color = "#ffffb3" + elif societe == "ME": + color = "#ffe44d" elif societe == "PL": - color = "LightGreen" + color = "#b3ff66" elif societe == "PO": - color = "LightBlue" + color = "#b1dae7" else: - color = "Gold" + color = "#ffb3cc" json_event = { - 'title': row.c_nom, + 'title': '%s %s' % (row.c_qualite, row.c_nom), + 'description': '%s %s' % (row.c_cp, row.c_ville.capitalize()), 'start': row.rdv_debut.strftime('%Y-%m-%d %H:%M:%S'), 'end': row.rdv_fin.strftime('%Y-%m-%d %H:%M:%S'), 'allDay': False, 'color': color, 'textColor': 'Black', - 'url': 'dossier_view/%s' % (row.nodossier), + 'url': '/rdv_edit/%s/%s' % (row.nodossier, row.nolig), } events.append(json_event) @@ -147,17 +170,24 @@ def agenda(request): 'fullcalendar_events': json.dumps(events), 'agendas': agendas, 'agenda': agenda, + 'types_rdv': types_rdv, + 'type_rdv': type_rdv, + 'message': message, + 'mem_nodossier': mem_nodossier, + 'mem_nomdossier': mem_nomdossier, + 'url': url, + 'url_select': url_select, + 'datePlan': datePlan, } @view_config(route_name='planning', renderer='../templates/agenda/planning.pt', permission='view') def planning(request): - logged_in = request.authenticated_userid - + # construire la liste des ressources # {"id":"a","title":"Auditorium A"} ressources = [] # liste des users avec agenda - users = get_users_agenda(request) + users = get_users_agenda(request, '') for row in users: json_ressources = { 'id': row.CD_UTI, @@ -169,31 +199,30 @@ def planning(request): events = [] for user in users: rows = get_rendez_vous(request, user.CD_UTI) - for row in rows: - event_url = 'dossier_view/%s' % (row.nodossier) - event_title = row.c_nom - + for row in rows: # déterminer la couleur de l'event selon la societe societe = row.nodossier[0:2] if societe == "PE": - color = "LightYellow" + color = "#ffffb3" + elif societe == "ME": + color = "#ffe44d" elif societe == "PL": - color = "LightGreen" + color = "#b3ff66" elif societe == "PO": - color = "LightBlue" + color = "#b1dae7" else: - color = "Gold" + color = "#ffb3cc" json_event = { 'resourceId': user.CD_UTI, - 'title': event_title, - 'description': row.c_ville.capitalize(), + 'title': row.c_nom, + 'description': '%s %s' % (row.c_cp, row.c_ville.capitalize()), 'start': row.rdv_debut.strftime('%Y-%m-%d %H:%M:%S'), 'end': row.rdv_fin.strftime('%Y-%m-%d %H:%M:%S'), 'allDay': False, 'color': color, 'textColor': 'Black', - 'url': event_url, + 'url': '/dossier_view/%s' % (row.nodossier), } events.append(json_event) diff --git a/mondumas/views/default.py b/mondumas/views/default.py index 5d97fef..d2f0190 100644 --- a/mondumas/views/default.py +++ b/mondumas/views/default.py @@ -18,13 +18,14 @@ from pyramid_mailer import get_mailer from pyramid_mailer.message import Message, Attachment from datetime import * import hashlib - from sqlalchemy.exc import DBAPIError from ..security import groupfinder +from user_agents import parse import json from ..models.default import * +from ..models.agenda import * def to_decimal(x): import decimal @@ -37,6 +38,21 @@ def to_euro(x): #else: return (u"%.2f €" % x).replace('.', ',') +def to_euroz(x): + """Takes a float and returns a string""" + if x == 0: + return "" + else: + return (u"%.2f €" % x).replace('.', ',') + +def to_decz(x): + """Takes a decimal and returns a string""" + if x == 0: + return "" + else: + return (u"%.2f" % x).replace('.', ',') + + def to_sha1(message): return hashlib.sha1(message.encode('utf-8')).hexdigest() @@ -52,14 +68,14 @@ def to_percent(x): return (u"%.2f " % x).replace('.', ',') + "%" -@view_config(route_name='home', renderer='../templates/home.pt', permission='view') +@view_config(route_name='home', renderer='../templates/default/home.pt', permission='view') def home(request): return { 'page_title': 'Bienvenue', 'project': 'mondumas', } -@view_config(route_name='envoyer_mdp', renderer='../templates/envoyer_mdp.pt') +@view_config(route_name='envoyer_mdp', renderer='../templates/default/envoyer_mdp.pt') def envoyer_mdp(request): url = request.route_url('envoyer_mdp') message = u'' @@ -92,7 +108,7 @@ Le lien suivant vous dirigera vers une page où vous pourrez ré-initialiser vot 'message': message, } -@view_config(route_name='changer_mdp', renderer='../templates/changer_mdp.pt', permission='view') +@view_config(route_name='changer_mdp', renderer='../templates/default/changer_mdp.pt', permission='view') def changer_mdp(request): url = request.route_url('changer_mdp') logged_in = request.authenticated_userid @@ -117,7 +133,7 @@ def changer_mdp(request): 'message': message, } -@view_config(route_name='redefinir_mdp', renderer='../templates/redefinir_mdp.pt') +@view_config(route_name='redefinir_mdp', renderer='../templates/default/redefinir_mdp.pt') def redefinir_mdp(request): lien = request.matchdict["lien"] url = request.route_url('redefinir_mdp', lien=lien) @@ -144,8 +160,8 @@ def redefinir_mdp(request): } -@view_config(route_name='login', renderer='../templates/login.pt', permission='view') -@forbidden_view_config(renderer='../templates/login.pt') +@view_config(route_name='login', renderer='../templates/default/login.pt', permission='view') +@forbidden_view_config(renderer='../templates/default/login.pt') def login(request): current_route_path = request.current_route_path() @@ -166,10 +182,14 @@ def login(request): if record : # mot de passe hash valide ? if record.mdp == to_sha1(password): - update_last_connection(request, login) + # get user agent string from request + ua_string = request.user_agent + user_agent = parse(ua_string) + update_last_connection(request, login, str(user_agent)) + # force le commit car il ne se fait pas automatiquement après l'update transaction.commit() - + headers = remember(request, login) return HTTPFound(location=came_from, headers=headers) @@ -213,43 +233,3 @@ gestion.entreprise-dumas.com mailer.send_immediately(message) -@view_config(route_name='chantier_lookup', renderer='../templates/chantier_lookup.pt', permission='view') -def chantier_lookup(request): - - # recherche chantier - url = request.route_url('chantier_lookup') - - message = u'' - societes = ['PE','ME','PL','PO','CD'] - societe = 'PE' - liste=[] - name = u'' - cb_tous = "non" - if 'form.submitted' in request.params: - name = request.params['name'] - societe = request.params['societe'] - # si afficher tous les fiches ? - if 'cb_tous' in request.params: - cb_tous = "oui" - chantiers = get_chantiers_byName(request, societe, name, True) - else: - cb_tous = "non" - chantiers = get_chantiers_byName(request, societe, name, False) - if len(chantiers) == 0: - message = u"Chantier non trouvé : %s" % name - # construire la liste - for item in chantiers: - d = ('%s-%s' % (societe, item.numero),item.date.strftime('%d-%m-%Y'), item.nomcli, item.chantier, to_euro(item.montant), - item.nosin, item.status) - liste.append(d) - - return { - 'page_title': u"Rechercher un chantier", - 'url': url, - 'message': message, - 'dt_data': json.dumps(liste), - 'societes': societes, - 'societe': societe, - 'name': name, - 'cb_tous': cb_tous, - } diff --git a/mondumas/views/dossier.py b/mondumas/views/dossier.py new file mode 100644 index 0000000..ad51044 --- /dev/null +++ b/mondumas/views/dossier.py @@ -0,0 +1,249 @@ +# -*- coding: utf8 -*- +from pyramid.response import Response +from pyramid.renderers import render, get_renderer +from pyramid.view import ( + view_config, + forbidden_view_config, +) +from pyramid.security import ( + remember, + forget, +) +from pyramid.httpexceptions import ( + HTTPFound, + HTTPNotFound, + HTTPForbidden, +) +from pyramid_mailer import get_mailer +from pyramid_mailer.message import Message, Attachment +from datetime import * +import hashlib + +from sqlalchemy.exc import DBAPIError +from ..security import groupfinder + +import json + +from ..views.default import * +from ..models.default import * +from ..models.dossier import * + +@view_config(route_name='dossier_lookup', renderer='../templates/dossier/dossier_lookup.pt', permission='view') +@view_config(route_name='dossier_select', renderer='../templates/dossier/dossier_lookup.pt', permission='view') +def dossier_lookup(request): + + if 'dossier_select' in request.current_route_path() : + # récupérer les paramètres de l'appel de la view + datePlan = request.matchdict['date'] + # sélectionner dossier -> goto planning + goto_url = '/dossier_selected/agenda/%s/' % datePlan + url = request.route_url('dossier_select', date=datePlan) + else: + # recherche dossier -> goto fiche dossier + goto_url = '/dossier_selected/dossier_view/%s/' % date.today().strftime('%Y-%m-%d') + url = request.route_url('dossier_lookup') + + message = u'' + societes = ['PE','ME','PL','PO','CD'] + societe = 'PE' + liste=[] + name = u'' + cb_tous = "non" + + if 'form.submitted' in request.params: + name = request.params['name'] + societe = request.params['societe'] + # si afficher tous les fiches ? + if 'cb_tous' in request.params: + cb_tous = "oui" + chantiers = get_chantiers_byName(request, societe, name, True) + else: + cb_tous = "non" + chantiers = get_chantiers_byName(request, societe, name, False) + if len(chantiers) == 0: + message = u"Chantier non trouvé : %s" % name + # construire la liste + for item in chantiers: + d = ('%s-%s' % (societe, item.numero),item.date.strftime('%d-%m-%Y'), item.nomcli, item.chantier, to_euro(item.montant), + item.nosin, item.status) + liste.append(d) + + return { + 'page_title': u"Rechercher un chantier", + 'url': url, + 'goto_url': goto_url, + 'message': message, + 'dt_data': json.dumps(liste), + 'societes': societes, + 'societe': societe, + 'name': name, + 'cb_tous': cb_tous, + } + +@view_config(route_name='dossier_view', renderer='../templates/dossier/dossier_view.pt', permission='view') +def dossier_view(request): + nodossier = request.matchdict['nodossier'] + societe = nodossier[0:2] + + url = request.route_url("dossier_view", nodossier=nodossier) + + dossier = get_dossier_by_no(request, nodossier) + if dossier is None: + request.session.flash(u"Le dossier no %s est introuvable" % (nodossier), 'danger') + return HTTPFound(location=request.route_url("dossier_lookup")) + # lire tous le suivi du dossier + details = get_dossier_rdv_by_no(request, nodossier, '0') + # lire toutes les dossiers du chantiers + documents = get_documents_byChantier(request, nodossier) + # lire toutes les dossiers similaires + similaires = get_similaires_byChantier(request, dossier.societe, dossier.C_NOM, dossier.C_ADR, dossier.C_CP, dossier.C_VILLE) + # lire tous les documents attachés + docs_attaches = get_docs_attaches(request, 'DOCS_ATTACHES', nodossier) + # select background color according to society + bg_color = "bg-%s" % societe + + return { + 'page_title': u"Dossier : %s" % (nodossier), + 'nodossier': nodossier, + 'dossier': dossier, + 'details': details, + 'documents': documents, + 'similaires': similaires, + 'docs_attaches': docs_attaches, + 'docs_url': request.static_url(request.registry.settings['mondumas.DEVFAC14']), + 'bg_color': bg_color, + } + +@view_config(route_name='devis_view', renderer='../templates/dossier/devis_view.pt', permission='view') +def devis_view(request): + nodossier = request.matchdict['nodossier'] + societe = nodossier[0:2] + url = request.route_url("devis_view", nodossier=nodossier) + + type_doc = nodossier[3:5] + if type_doc == 'DE': + page_title = u"Devis no : %s" % (nodossier) + elif type_doc == 'FA': + page_title = u"Facture no : %s" % (nodossier) + else: + page_title = u"Proforma no : %s" % (nodossier) + + dossier = get_devis_by_no(request, nodossier) + if dossier is None: + request.session.flash(u"Le document no %s est introuvable" % (nodossier), 'danger') + return HTTPFound(location=request.route_url("dossier_lookup")) + # lire tous les lignes du devis + details = get_devis_lig_by_no(request, nodossier) + # select background color according to society + bg_color = "bg-%s" % societe + + return { + 'page_title': page_title, + 'nodossier': nodossier, + 'dossier': dossier, + 'details': details, + 'bg_color': bg_color, + } + +@view_config(route_name='dossier_selected', permission='view') +def dossier_selected(request): + + # récupérer les paramètres de l'appel de la view + goto = request.matchdict['goto'] + datePlan = request.matchdict['date'] + nodossier = request.matchdict['nodossier'] + + # fiche dossier + dossier = get_dossier_by_no(request, nodossier) + # memorize nodossier et nom dossier + request.session['mem_nodossier'] = nodossier + request.session['mem_nomdossier'] = '%s %s' % (dossier.C_QUALITE, dossier.C_NOM) + if goto == 'dossier_view': + return HTTPFound(location=request.route_url('dossier_view', nodossier=nodossier)) + else: + return HTTPFound(location=request.route_url('agenda', date=datePlan)) + +@view_config(route_name='suivi_edit', renderer='../templates/dossier/suivi_edit.pt', permission='view') +def suivi_edit(request): + + logged_in = request.authenticated_userid + nodossier = request.matchdict['nodossier'] + nolig = request.matchdict['nolig'] + url = request.route_url("suivi_edit", nodossier=nodossier, nolig=nolig) + + message = '' + if nolig == '0': + # nouveau + suivi = {} + suivi['COMMENT'] = '' + suivi['USERMAJ'] = logged_in.upper() + suivi['DATEMAJ'] = datetime.now() + page_title= 'Nouveau suivi' + else: + # lire le suivi + suivi = get_dossier_rdv_by_no(request, nodossier, nolig) + if not suivi: + request.session.flash(u"Suivi non trouvé : %s" % nodossier, 'warning') + return HTTPFound(location=request.route_url('dossier_view', nodossier=nodossier)) + + page_title= u"Modification du suivi %s" % (nolig) + + if 'form.submitted' in request.params: + new_values = {} + for param, db_value in suivi.items(): + if param in request.params and request.params[param] != db_value: + new_values[param] = request.params[param] + + if new_values: + new_values['USERMAJ'] = logged_in.upper() + new_values['DATE'] = date.today() + + update_suivi(request, nodossier, nolig, new_values) + request.session.flash(u"Le suivi a été mis à jour avec succès.", 'success') + + return HTTPFound(location=request.route_url('dossier_view', nodossier=nodossier)) + + if 'form.deleted' in request.params: + delete_rdv(request, nodossier, nolig) + request.session.flash(u"Le suivi a été supprimé avec succès.", 'success') + return HTTPFound(location=request.route_url('dossier_view', nodossier=nodossier)) + + return { + 'page_title': page_title, + 'logged_in': logged_in, + 'url': url, + 'nodossier': nodossier, + 'nolig': nolig, + 'suivi': suivi, + 'message': message, + } + +@view_config(route_name='dossier_edit', renderer='../templates/dossier/dossier_edit.pt', permission='view') +def dossier_edit(request): + logged_in = request.authenticated_userid + nodossier = request.matchdict['nodossier'] + url = request.route_url('dossier_edit', nodossier=nodossier) + + dossier = get_dossier_by_no(request, nodossier) + if not dossier: + request.session.flash(u"Le dossier no %s est introuvable" % (nodossier), 'danger') + return HTTPFound(location=request.route_url('dossier_lookup')) + + if 'form.submitted' in request.params: + new_values = {} + for param, db_value in dossier.items(): + if param in request.params and request.params[param] != db_value: + new_values[param] = request.params[param] + + if new_values: + update_dossier(request, nodossier, new_values) + request.session.flash(u"Le dossier a été mis à jour avec succès.", 'success') + return HTTPFound(location=request.route_url('dossier_view', nodossier=nodossier)) + + return { + 'page_title': u"Modifier le dossier : %s" % nodossier, + 'url': url, + 'dossier': dossier, + 'nodossier': nodossier, + } + diff --git a/mondumas/views/notfound.py b/mondumas/views/notfound.py index c1225f1..3a50f21 100644 --- a/mondumas/views/notfound.py +++ b/mondumas/views/notfound.py @@ -1,7 +1,7 @@ # -*- coding: utf8 -*- from pyramid.view import notfound_view_config -@notfound_view_config(renderer='../templates/404.pt') +@notfound_view_config(renderer='../templates/default/404.pt') def notfound_view(request): request.response.status = 404 return { diff --git a/mondumas/views/parametres.py b/mondumas/views/parametres.py index 0a7ebd9..5470e38 100644 --- a/mondumas/views/parametres.py +++ b/mondumas/views/parametres.py @@ -22,6 +22,7 @@ import json from ..models.parametres import * from ..models.default import * +from ..views.default import * @view_config(route_name='parametres', renderer='../templates/parametres/parametres.pt', permission='manage') def parametres(request): @@ -39,12 +40,7 @@ def users_list(request): # construire la liste liste=[] - for item in items: - if item.dern_cnx_le: - der_cnx_le = item.dern_cnx_le.strftime('%d/%m/%Y - %H:%M') - else: - der_cnx_le = "" - + for item in items: if item.actif == 0: etat = 'Inactif' else: @@ -59,7 +55,7 @@ def users_list(request): else: role = 'Gestion' - d = (item.CD_UTI, item.NOM, item.email, item.agenda, role, der_cnx_le, etat) + d = (item.CD_UTI, item.NOM, item.email, item.agenda, role, etat) liste.append(d) return { @@ -67,6 +63,28 @@ def users_list(request): 'dt_data': json.dumps(liste), } +@view_config(route_name='users_ua', renderer='../templates/parametres/users_ua.pt', permission='manage') +def users_ua(request): + # lire les utilisateurs + items = get_member_by_id(request, '0') + + # construire la liste + liste=[] + for item in items: + # utilisateur a au moins une connexion ? + if item.dern_cnx_le: + der_cnx_le = item.dern_cnx_le.strftime('%d/%m/%Y - %H:%M') + + d = (der_cnx_le, item.CD_UTI, item.NOM, item.ua_string) + liste.append(d) + + return { + 'page_title': u'Liste des connexions', + 'dt_data': json.dumps(liste), + } + + + @view_config(route_name='user_edit', renderer='../templates/parametres/user_edit.pt', permission='manage') def user_edit(request): cd_uti = request.matchdict['cd_uti'] @@ -77,8 +95,8 @@ def user_edit(request): if cd_uti == '0': # nouveau individu = {} - individu['cd_uti'] = '0' - individu['nom'] = '' + individu['CD_UTI'] = '0' + individu['NOM'] = '' individu['email'] = '' individu['access'] = '0 | Production' individu['actif'] = 1 @@ -97,7 +115,7 @@ def user_edit(request): for param, db_value in individu.items(): if param in request.params and request.params[param] != db_value: new_values[param] = request.params[param] - + # actif coché ? if 'actif' in request.params: new_values['actif'] = 1 @@ -163,3 +181,59 @@ def last_emailing(request): 'page_title': u'Liste des derniers emailing', 'dt_data': json.dumps(liste), } + +@view_config(route_name='orphans_de', renderer='../templates/parametres/orphans_de.pt', permission='manage') +def orphans_de(request): + + societe = request.matchdict['societe'] + url = request.route_url('orphans_de', societe=societe) + message = u'' + societes = ['PE','ME','PL','PO','CD'] + nochantier = '0' + + # prendre en compte les paramètres de saisie + if 'societe' in request.params: + societe = request.params["societe"] + url = request.route_url('orphans_de', societe=societe) + + if 'form.nochantier' in request.params: + message = '' + nochantier = request.params['nochantier'] + + # oui, NestedMultiDict([('form.submitted', u''), ('id0', u'271246'), ('id1', u'370929')]) + for param in request.params: + if param[:2] == 'id': + update_nochantier(request, societe, request.params[param], int(nochantier)) + message = u"Le numéro de chantier est mis à jour avec succès" + + # lire le premier devis orphelin + devis = get_orphans_DE(request, societe) + + # lire tous les dossiers de ce chantier + dossiers = get_dossiers_byChantier(request, societe, '%s;%s;%s' % (devis.C_NOM, devis.C_ADR, devis.C_VILLE)) + liste=[] + nochantiers=[] + # construire la liste + for item in dossiers: + dossier_id = '%s-%s' % (item.TYPE, item.numero) + if item.nochantier != 0: + nochantiers.append(item.nochantier) + nochantier = item.nochantier + d = (dossier_id, dossier_id, item.date.strftime('%d-%m-%Y'), item.nomcli, item.chantier, to_euro(item.montant), + item.nosin, item.nochantier) + liste.append(d) + + if len(nochantiers) == 0: + nochantiers.append(1) + + return { + 'page_title': u"DEVIS orphelins", + 'url': url, + 'message': message, + 'devis': devis, + 'dt_data': json.dumps(liste), + 'societes': societes, + 'societe': societe, + 'nochantiers': nochantiers, + 'nochantier': nochantier, + } diff --git a/nssm.exe b/nssm.exe new file mode 100644 index 0000000..6ccfe3c Binary files /dev/null and b/nssm.exe differ diff --git a/production.ini b/production.ini index 4fb9a6b..3a0bf87 100644 --- a/production.ini +++ b/production.ini @@ -16,12 +16,12 @@ pyramid.includes = pyramid_layout pyramid_mailer pyramid_tm - pyramid_exclog sqlalchemy.url = mysql://root:cni/@srvbd/bddevfac?charset=utf8 sqlalchemy.pool_recycle = 3600 mondumas.admin_email = phuoc@caotek.fr +mondumas.DEVFAC14 = mondumas:static/img/DEVFAC14/ # Mailer configuration mail.host = smtp.orange.fr @@ -84,12 +84,6 @@ qualname = sqlalchemy.engine # "level = DEBUG" logs SQL queries and results. # "level = WARN" logs neither. (Recommended for production systems.) -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - [formatter_generic] format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/pyramidsvc.py b/pyramidsvc.py deleted file mode 100644 index acb43c5..0000000 --- a/pyramidsvc.py +++ /dev/null @@ -1,51 +0,0 @@ -# uncomment the next import line to get print to show up or see early -# exceptions if there are errors then run -# python -m win32traceutil -# to see the output -#import win32traceutil -import win32serviceutil - -PORT_TO_BIND = 9180 -CONFIG_FILE = 'production.ini' -SERVER_NAME = 'gestion.entreprise-dumas.com' - -SERVICE_NAME = "Pyramid_Service" -SERVICE_DISPLAY_NAME = "Pyramid Web Service" -SERVICE_DESCRIPTION = """Permet de laner l'application Pyramid comme un servcie.""" - -class PyWebService(win32serviceutil.ServiceFramework): - """Python Web Service.""" - - _svc_name_ = SERVICE_NAME - _svc_display_name_ = SERVICE_DISPLAY_NAME - _svc_deps_ = None # sequence of service names on which this depends - # Only exists on Windows 2000 or later, ignored on Windows NT - _svc_description_ = SERVICE_DESCRIPTION - - def SvcDoRun(self): - from cherrypy import wsgiserver - from pyramid.paster import get_app - from pyramid.paster import setup_logging - import os, sys - - path = os.path.dirname(os.path.abspath(__file__)) - - os.chdir(path) - - app = get_app(CONFIG_FILE) - setup_logging(CONFIG_FILE) - - - self.server = wsgiserver.CherryPyWSGIServer( - ('0.0.0.0', PORT_TO_BIND), app, - server_name=SERVER_NAME) - - self.server.start() - - - def SvcStop(self): - self.server.stop() - - -if __name__ == '__main__': - win32serviceutil.HandleCommandLine(PyWebService) diff --git a/setup.py b/setup.py index a78b8a1..5d3cf2a 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,6 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', - # 'pyramid_jinja2', 'pyramid_chameleon', 'pyramid_debugtoolbar', 'pyramid_layout', @@ -23,6 +22,7 @@ requires = [ 'mysqlclient', 'python-dateutil', 'docutils', + 'user-agents', ] tests_require = [ @@ -32,7 +32,7 @@ tests_require = [ ] setup(name='mondumas', - version='0.1', + version='1.0', description='mondumas', long_description=README + '\n\n' + CHANGES, classifiers=[