@@ -111,12 +111,12 @@ def main(global_config, **settings): | |||
# HTML Routes - Staff | |||
config.add_route('Live', '/Live') | |||
config.add_route('list_expenses', '/Staff/compta') | |||
config.add_route('list_task', '/Staff') | |||
config.add_route('handle_pole', '/Staff/poles{sep:/*}{pole_id:(\d+)?}') | |||
config.add_route('handle_task', '/Staff/tasks{sep:/*}{task_id:(\d+)?}') | |||
config.add_route('action_task', '/Staff/{action:(\w+)}/{task_id:(\d+)}') | |||
config.add_route('action_task_area', '/Staff/pole/{action:(\w+)}/{pole_id:(\d+)}') | |||
config.add_route('list_expenses', '/{year:\d+}/Staff/compta') | |||
config.add_route('list_task', '/{year:\d+}/Staff') | |||
config.add_route('handle_pole', '/{year:\d+}/Staff/poles{sep:/*}{pole_id:(\d+)?}') | |||
config.add_route('handle_task', '/{year:\d+}/Staff/tasks{sep:/*}{task_id:(\d+)?}') | |||
config.add_route('action_task', '/{year:\d+}/Staff/{action:(\w+)}/{task_id:(\d+)}') | |||
config.add_route('action_task_area', '/{year:\d+}/Staff/pole/{action:(\w+)}/{pole_id:(\d+)}') | |||
config.add_route('list_salles', '/ListSalles') | |||
config.add_route('handle_salle', '/Salles{sep:/*}{salle_id:(\d+)?}') | |||
@@ -8,13 +8,14 @@ from wtforms.validators import ValidationError | |||
strip_filter = lambda x: x.strip() if x else None | |||
from wtforms.csrf.session import SessionCSRF | |||
from datetime import timedelta | |||
from jm2l.const import CurrentYear | |||
class MyBaseForm(Form): | |||
class Meta: | |||
csrf = True | |||
csrf_class = SessionCSRF | |||
csrf_secret = b'lJDQtOAMC2qe89doIn8u3Mch_DgeLSKO' | |||
csrf_time_limit = timedelta(minutes=20) | |||
csrf_time_limit = timedelta(minutes=60) | |||
class BlogCreateForm(MyBaseForm): | |||
title = TextField('Entry title', [validators.Length(min=1, max=255)], | |||
@@ -53,6 +54,7 @@ class StaffArea(MyBaseForm): | |||
description = TextAreaField('Description', [validators.optional(), validators.Length(max=1000000)], | |||
filters=[strip_filter] | |||
) | |||
year_uid = HiddenField('year', default=str(CurrentYear)) | |||
class EditStaffArea(StaffArea): | |||
uid = HiddenField() | |||
@@ -64,12 +66,13 @@ class StaffTasks(MyBaseForm): | |||
due_date = DateField(u'Date prévue', format='%d/%m/%Y') | |||
description = TextAreaField('Description', [validators.optional(), validators.Length(max=1000000)], | |||
filters=[strip_filter]) | |||
year_uid = HiddenField('year', default=str(CurrentYear)) | |||
class EditStaffTasks(StaffTasks): | |||
uid = HiddenField() | |||
class DossPresse(MyBaseForm): | |||
year_uid = HiddenField() | |||
year_uid = HiddenField() | |||
doss_presse = TextAreaField('Dossier de Presse', [validators.optional(), validators.Length(max=1000000)], | |||
filters=[strip_filter]) | |||
@@ -82,7 +85,7 @@ class TiersMember(MyBaseForm): | |||
class Meta: | |||
csrf = False | |||
year_uid = SelectField(u'Année', coerce=int, choices=zip(range(2006,2016),range(2006,2016))) | |||
year_uid = SelectField(u'Année', coerce=int, choices=zip(range(2006,CurrentYear+1),range(2006,CurrentYear+1))) | |||
user_uid = TextField(u'user') | |||
role = TextField(u'Role') | |||
@@ -90,7 +93,7 @@ class TiersRole(MyBaseForm): | |||
class Meta: | |||
csrf = False | |||
year_uid = SelectField(u'Année', coerce=int, choices=zip(range(2006,2016),range(2006,2016))) | |||
year_uid = SelectField(u'Année', coerce=int, choices=zip(range(2006,CurrentYear+1),range(2006,CurrentYear+1))) | |||
tiers_role = SelectField(u'Role', choices=TIERS_ROLE) | |||
class TiersChoice(MyBaseForm): | |||
@@ -39,6 +39,7 @@ Base = declarative_base() | |||
class TasksArea(Base): | |||
__tablename__ = 'staff_tasks_area' | |||
uid = Column(Integer, primary_key=True) | |||
year_uid = Column(Integer, ForeignKey('jm2l_year.year_uid'), default=CurrentYear) | |||
name = Column(Unicode(80)) | |||
description = Column(UnicodeText) | |||
@@ -50,6 +51,7 @@ class Tasks(Base): | |||
__tablename__ = 'staff_tasks' | |||
uid = Column(Integer, primary_key=True) | |||
area_uid = Column(Integer, ForeignKey('staff_tasks_area.uid') ) | |||
year_uid = Column(Integer, ForeignKey('jm2l_year.year_uid'), default=CurrentYear) | |||
due_date = Column(DateTime, default=None) | |||
closed_by = Column(Integer, ForeignKey('users.uid') ) | |||
closed_date = Column(DateTime, default=None) | |||
@@ -3,7 +3,7 @@ | |||
<% | |||
from slugify import slugify | |||
%> | |||
<a style="float:right;" class="btn btn-mini btn-info" role="button" href="/Staff/poles"> | |||
<a style="float:right;" class="btn btn-mini btn-info" role="button" href="/${year}/Staff/poles"> | |||
<i class="icon-plus-sign icon-white"></i> Ajouter un Pôle d'activité | |||
</a> | |||
<h3>Liste des tâches JM2L Staff</h3> | |||
@@ -24,7 +24,7 @@ from slugify import slugify | |||
% for Num, Entity in enumerate(sorted(tasks.keys(), key=lambda x:x.name)): | |||
<div class="tab-pane fade ${["","active "][Num==0]} in" id="${slugify(Entity.name)}"> | |||
<a style="float:right;" class="btn btn-mini btn-info" role="button" href="/Staff/poles/${Entity.uid}"> | |||
<a style="float:right;" class="btn btn-mini btn-info" role="button" href="/${year}/Staff/poles/${Entity.uid}"> | |||
<i class="icon-pencil icon-white"></i> Editer le pôle | |||
</a> | |||
<h4>${Entity.name}</h4> | |||
@@ -35,7 +35,7 @@ from slugify import slugify | |||
<thead> | |||
<tr> | |||
<th colspan="2" style="text-align:center;"> | |||
<a style="float:right;" class="btn btn-mini btn-info" role="button" href="${request.route_path('handle_task', sep="", task_id="", _query={"pole_id":Entity.uid})}"> | |||
<a style="float:right;" class="btn btn-mini btn-info" role="button" href="${request.route_path('handle_task', sep="", task_id="", year=year, _query={"pole_id":Entity.uid})}"> | |||
<i class="icon-plus-sign icon-white"></i> Ajouter une tâche | |||
</a> | |||
Liste des tâches | |||
@@ -54,11 +54,11 @@ from slugify import slugify | |||
<tr> | |||
<td> | |||
% if task.closed: | |||
<a href="/Staff/tasks/${task.uid}"> | |||
<a href="/${year}/Staff/tasks/${task.uid}"> | |||
<span class="name" style="text-decoration: line-through;">${task.name}</span> | |||
</a> | |||
% else: | |||
<a href="/Staff/tasks/${task.uid}"> | |||
<a href="/${year}/Staff/tasks/${task.uid}"> | |||
<span class="name">${task.name}</span> | |||
</a> | |||
<span style="float:right;"> | |||
@@ -70,9 +70,9 @@ from slugify import slugify | |||
<td style="position: relative;width:70px;"> | |||
<div class="actions"> | |||
% if task.closed: | |||
[ <a href="/Staff/open/${task.uid}">ré-ouvrir</a> ] | |||
[ <a href="/${year}/Staff/open/${task.uid}">ré-ouvrir</a> ] | |||
% else: | |||
[ <a href="/Staff/close/${task.uid}">c'est fait</a> ] | |||
[ <a href="/${year}/Staff/close/${task.uid}">c'est fait</a> ] | |||
% endif | |||
</div> | |||
</td> | |||
@@ -97,7 +97,7 @@ from slugify import slugify | |||
$('a[data-toggle="tab"]') | |||
.on('shown', function(e) { | |||
//stateObj = { tab: $(e.target).attr('href').substr(1) }; | |||
//history.replaceState(stateObj, "", "/Staff" + $(e.target).attr('href') ); | |||
//history.replaceState(stateObj, "", "/${year}/Staff" + $(e.target).attr('href') ); | |||
location.hash = $(e.target).attr('href'); | |||
}); | |||
@@ -6,7 +6,8 @@ | |||
<h1>Add a new task</h1> | |||
<form action="/Staff/new" method="post"> | |||
<form action="/${year}/Staff/new" method="post"> | |||
<input type="text" maxlength="100" name="name"> | |||
<input type="text" maxlength="100" name="name"> | |||
<input type="submit" class="btn btn-primary" name="add" value="ADD" class="button"> | |||
</form> | |||
@@ -19,11 +19,11 @@ | |||
<div class="row-fluid"> | |||
<div class="span10 offset1"> | |||
<a class="btn" href="${request.route_path('list_task', _anchor=form.name.data)}"> | |||
<a class="btn" href="${request.route_path('list_task', year=year, _anchor=form.name.data)}"> | |||
<i class="icon-arrow-left"></i> Retour à la liste | |||
</a> | |||
% if 'uid' in form._fields.keys(): | |||
<a class="btn btn-danger btn-mini pull-right" href="${request.route_path('action_task_area', action='delete', pole_id=form.uid.data)}"> | |||
<a class="btn btn-danger btn-mini pull-right" href="${request.route_path('action_task_area', year=year, action='delete', pole_id=form.uid.data)}"> | |||
<i class="icon-remove icon-white"></i> Supprimer ce pôle | |||
</a> | |||
<h3>Editer un Pôle</h3> | |||
@@ -38,10 +38,10 @@ DicForm = { | |||
%> | |||
% if 'uid' in form._fields.keys(): | |||
<form action="/Staff/poles/${form.uid.data}" method="post"> | |||
<form action="/${year}/Staff/poles/${form.uid.data}" method="post"> | |||
${form.uid()} | |||
%else: | |||
<form action="/Staff/poles" method="post"> | |||
<form action="/${year}/Staff/poles" method="post"> | |||
%endif | |||
${helpers.DisplayForm(form, DicForm)} | |||
@@ -29,11 +29,11 @@ | |||
<div class="row-fluid"> | |||
<div class="span10 offset1"> | |||
<a class="btn" href="${request.route_path('list_task', _anchor=area)}"> | |||
<a class="btn" href="${request.route_path('list_task', year=year, _anchor=area)}"> | |||
<i class="icon-arrow-left"></i> Retour à la liste | |||
</a> | |||
% if 'uid' in form._fields.keys(): | |||
<a class="btn btn-danger btn-mini pull-right" href="${request.route_path('action_task', action='delete', task_id=form.uid.data)}"> | |||
<a class="btn btn-danger btn-mini pull-right" href="${request.route_path('action_task', year=year, action='delete', task_id=form.uid.data)}"> | |||
<i class="icon-remove icon-white"></i> Supprimer cette tâche | |||
</a> | |||
%endif | |||
@@ -56,10 +56,10 @@ DicForm = { | |||
%> | |||
% if 'uid' in form._fields.keys(): | |||
<form action="/Staff/tasks/${form.uid.data}" method="post"> | |||
<form action="/${year}/Staff/tasks/${form.uid.data}" method="post"> | |||
${form.uid()} | |||
%else: | |||
<form action="/Staff/tasks" method="post"> | |||
<form action="/${year}/Staff/tasks" method="post"> | |||
%endif | |||
${helpers.DisplayForm(form, DicForm)} | |||
@@ -120,12 +120,12 @@ ${helpers.uploader_js()} | |||
<ul class="dropdown-menu pull-right"> | |||
% if request.user: | |||
% if request.user.Staff: | |||
<li><a href="/Staff">Partie Staff</a></li> | |||
<li><a href="/${DisplayYear}/Staff">Partie Staff</a></li> | |||
<li><a href="/ListParticipant">Gérer les intervenants</a></li> | |||
<li><a href="/ListSalles">Gérer les salles</a></li> | |||
<li><a href="/entities">Gérer les entités</a></li> | |||
<li><a href="/ListOrga">Participations à l'orga</a></li> | |||
<li><a href="/Staff/compta">Comptabilité</a></li> | |||
<li><a href="/${DisplayYear}/ListOrga">Participations à l'orga</a></li> | |||
<li><a href="/${DisplayYear}/Staff/compta">Comptabilité</a></li> | |||
<li role="separator" class="divider"></li> | |||
% endif | |||
<li><a href="/MesJM2L">Mon profil</a></li> | |||
@@ -92,7 +92,7 @@ Voici ce qu'il y'a dans la liste des tâches qui te sont assignées: | |||
% if not t.closed: | |||
<tr> | |||
<td>${t.due_date.strftime('%d %B %Y').decode('utf-8', 'xmlcharrefreplace')}</td><td>${t.area.name}</td> | |||
<td><a href="http://jm2l.linux-azur.org/Staff/tasks/${t.uid}">${t.name}</a> | |||
<td><a href="http://jm2l.linux-azur.org/2017/Staff/tasks/${t.uid}">${t.name}</a> | |||
% endif | |||
% endfor | |||
</table> | |||
@@ -103,7 +103,7 @@ Voici ce qu'il y'a dans la liste des tâches qui te sont assignées: | |||
% if not t.closed: | |||
<tr> | |||
<td>${t.due_date.strftime('%d %B %Y').decode('utf-8', 'xmlcharrefreplace')}</td><td>${t.area.name}</td> | |||
<td><a href="http://jm2l.linux-azur.org/Staff/tasks/${t.uid}">${t.name}</a> | |||
<td><a href="http://jm2l.linux-azur.org/2017/Staff/tasks/${t.uid}">${t.name}</a> | |||
% endif | |||
% endfor | |||
</table> | |||
@@ -378,7 +378,7 @@ def index_page(request): | |||
@view_config(route_name='edit_index', renderer="jm2l:templates/Staff/EditIndex.mako") | |||
def edit_index(request): | |||
year = int(request.matchdict.get('year', None)) | |||
year = int(request.matchdict.get('year', CurrentYear)) | |||
if not request.user.Staff: | |||
# Don't answer to users that aren't logged | |||
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.') | |||
@@ -447,6 +447,7 @@ def static_plan(request): | |||
## =-=- Here, We handle HTTP requests - Staff Logged Part -=-= | |||
@view_config(route_name='list_task', renderer='jm2l:templates/Staff/list.mako') | |||
def list_view(request): | |||
year = int(request.matchdict.get('year', CurrentYear)) | |||
if request.user is None: | |||
# Don't answer to users that aren't logged | |||
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.') | |||
@@ -454,17 +455,19 @@ def list_view(request): | |||
# Don't answer to users that aren't logged | |||
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.') | |||
DicTask = {} | |||
taskgroup = DBSession.query( TasksArea ).all() | |||
taskgroup = DBSession.query( TasksArea ).filter( TasksArea.year_uid == year).all() | |||
for grp in taskgroup: | |||
tasks = DBSession.query( Tasks )\ | |||
.filter( Tasks.area_uid==grp.uid )\ | |||
.filter( Tasks.area_uid==grp.uid ) \ | |||
.filter( Tasks.year_uid == year) \ | |||
.order_by(Tasks.closed, Tasks.due_date).all() | |||
DicTask[grp] = tasks | |||
return {'tasks': DicTask } | |||
return {'tasks': DicTask, 'year':year } | |||
@view_config(route_name='list_expenses', renderer='jm2l:templates/Staff/compta.mako') | |||
def expenses(request): | |||
year = int(request.matchdict.get('year', CurrentYear)) | |||
if request.user is None: | |||
# Don't answer to users that aren't logged | |||
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.') | |||
@@ -510,11 +513,12 @@ def expenses(request): | |||
dic_out[tab_path[4]]['Justif']['files'].append( name ) | |||
dic_out[tab_path[4]]['Justif']['thumb'].append( name + ".jpg" ) | |||
return dict(found=dic_out) | |||
return dict(found=dic_out, year=year ) | |||
@view_config(route_name='handle_task', renderer='jm2l:templates/Staff/tasks.mako') | |||
def tasks(request): | |||
year = int(request.matchdict.get('year', CurrentYear)) | |||
if request.user is None: | |||
# Don't answer to users that aren't logged | |||
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.') | |||
@@ -529,7 +533,8 @@ def tasks(request): | |||
pole_id = None | |||
# Get areas from db | |||
Areas = DBSession.query(TasksArea.uid, TasksArea.name)\ | |||
Areas = DBSession.query(TasksArea.uid, TasksArea.name) \ | |||
.filter(TasksArea.year_uid == year) \ | |||
.order_by('name').all() | |||
# Get users from db | |||
Users = DBSession.query(User)\ | |||
@@ -561,17 +566,20 @@ def tasks(request): | |||
if request.method=='POST' and form.validate(): | |||
form.populate_obj(TmpTask) | |||
TmpTask.closed = False | |||
if not TmpTask.year_uid: | |||
TmpTask.year_uid = year; | |||
if 'uid' in form._fields.keys(): | |||
DBSession.merge(TmpTask) | |||
else: | |||
DBSession.add(TmpTask) | |||
DBSession.flush() | |||
return HTTPFound(location=request.route_url('list_task')+"#"+slugify(TmpTask.area.name)) | |||
return HTTPFound(location=request.route_url('list_task', year=year)+"#"+slugify(TmpTask.area.name)) | |||
return {'form':form, 'area':TmpTask.area and slugify(TmpTask.area.name) or ''} | |||
return {'form':form, 'area':TmpTask.area and slugify(TmpTask.area.name) or '', 'year':year} | |||
@view_config(route_name='handle_pole', renderer='jm2l:templates/Staff/pole.mako') | |||
def tasks_area(request): | |||
year = int(request.matchdict.get('year', CurrentYear)) | |||
if request.user is None: | |||
# Don't answer to users that aren't logged | |||
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.') | |||
@@ -589,15 +597,18 @@ def tasks_area(request): | |||
form = StaffArea(request.POST, Pole, meta={'csrf_context': request.session}) | |||
if request.method == 'POST' and form.validate(): | |||
form.populate_obj(Pole) | |||
if not Pole.year_uid: | |||
Pole.year_uid = year; | |||
if 'uid' in form._fields.keys(): | |||
DBSession.merge(Pole) | |||
else: | |||
DBSession.add(Pole) | |||
return HTTPFound(location=request.route_url('list_task')+"#"+slugify(Pole.name)) | |||
return {'form':form } | |||
return HTTPFound(location=request.route_url('list_task', year=year)+"#"+slugify(Pole.name)) | |||
return {'form':form, 'year':year } | |||
@view_config(route_name='action_task') | |||
def action_task(request): | |||
year = int(request.matchdict.get('year', CurrentYear)) | |||
if request.user is None: | |||
# Don't answer to users that aren't logged | |||
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.') | |||
@@ -618,10 +629,11 @@ def action_task(request): | |||
if action=='delete': | |||
request.session.flash(('info', u'La tâche a été supprimée !')) | |||
DBSession.delete(Task) | |||
return HTTPFound(location=request.route_url('list_task')+"#"+slugify(Task.area.name)) | |||
return HTTPFound(location=request.route_url('list_task', year=year)+"#"+slugify(Task.area.name)) | |||
@view_config(route_name='action_task_area') | |||
def action_task_area(request): | |||
year = int(request.matchdict.get('year', CurrentYear)) | |||
if request.user is None: | |||
# Don't answer to users that aren't logged | |||
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.') | |||
@@ -636,7 +648,7 @@ def action_task_area(request): | |||
if action=='delete': | |||
request.session.flash(('info', u'Le pôle a été supprimé !')) | |||
DBSession.delete(Pole) | |||
return HTTPFound(location=request.route_url('list_task')) | |||
return HTTPFound(location=request.route_url('list_task', year=year)) | |||
@view_config(route_name='list_salles', renderer='jm2l:templates/Salles/list.mako') | |||
def list_salles(request): | |||