[#2245] Liste des DAE finalisées
authorEric Mc Sween <eric.mcsween@auf.org>
Fri, 4 Nov 2011 17:30:36 +0000 (13:30 -0400)
committerEric Mc Sween <eric.mcsween@auf.org>
Fri, 4 Nov 2011 17:33:01 +0000 (13:33 -0400)
project/dae/models.py
project/dae/templates/dae/embauches_finalisees.html [new file with mode: 0644]
project/dae/templates/dae/pagination.html [new file with mode: 0644]
project/dae/templates/dae/sort_header.html [new file with mode: 0644]
project/dae/templatetags/dae.py
project/dae/urls.py
project/dae/views.py
project/media/css/dae.css
project/settings.py
project/templates/menu.html

index f617a69..56cc0f2 100644 (file)
@@ -79,9 +79,9 @@ class Poste(PosteWorkflow, models.Model):
                             blank=True, null=True)
     classement_max = models.ForeignKey(rh.Classement, related_name='+',
                             blank=True, null=True)
-    valeur_point_min = models.ForeignKey(rh.ValeurPoint, related_name='+', 
+    valeur_point_min = models.ForeignKey(rh.ValeurPoint, related_name='+',
                             blank=True, null=True)
-    valeur_point_max = models.ForeignKey(rh.ValeurPoint, related_name='+', 
+    valeur_point_max = models.ForeignKey(rh.ValeurPoint, related_name='+',
                             blank=True, null=True)
     devise_min = models.ForeignKey(rh.Devise, default=5, related_name='+')
     devise_max = models.ForeignKey(rh.Devise, default=5, related_name='+')
@@ -162,7 +162,7 @@ class Poste(PosteWorkflow, models.Model):
             return []
         postes = [p for p in self.id_rh.poste1.all()]
         return sorted(postes, key=lambda poste: poste.id, reverse=True)
-            
+
     def get_complement_nom(self):
         """
         Inspecte les modèles rh v1 pour trouver dans le dernier dossier 
@@ -426,7 +426,7 @@ GENRE_CHOICES = (
 class Employe(models.Model):
 
     # Modèle existant
-    id_rh = models.ForeignKey(rh.Employe, null=True, related_name='+', 
+    id_rh = models.ForeignKey(rh.Employe, null=True, related_name='+',
                             verbose_name='Employé')
     nom = models.CharField(max_length=255)
     prenom = models.CharField(max_length=255, verbose_name='Prénom')
@@ -455,9 +455,9 @@ class Dossier(DossierWorkflow, models.Model):
     employe = models.ForeignKey('Employe', related_name='+', editable=False)
     poste = models.ForeignKey('Poste', related_name='dossiers', editable=False)
     statut = models.ForeignKey(rh.Statut, related_name='+')
-    organisme_bstg = models.ForeignKey(rh.OrganismeBstg, 
+    organisme_bstg = models.ForeignKey(rh.OrganismeBstg,
             null=True, blank=True,
-            verbose_name="Organisme", 
+            verbose_name="Organisme",
             help_text="Si détaché (DET) ou mis à disposition (MAD), \
                     préciser l'organisme.",
             related_name='+')
@@ -497,7 +497,7 @@ class Dossier(DossierWorkflow, models.Model):
 
     # Recrutement
     remplacement = models.BooleanField()
-    statut_residence = models.CharField(max_length=10, default='local', 
+    statut_residence = models.CharField(max_length=10, default='local',
                             verbose_name="Statut",
                             choices=STATUT_RESIDENCE_CHOICES)
 
@@ -509,13 +509,13 @@ class Dossier(DossierWorkflow, models.Model):
                             verbose_name='Salaire de base',
                             null=True, default=None)
     devise = models.ForeignKey(rh.Devise, default=5, related_name='+')
-    regime_travail = models.DecimalField(max_digits=12, 
+    regime_travail = models.DecimalField(max_digits=12,
                             decimal_places=2,
                             default=REGIME_TRAVAIL_DEFAULT,
                             verbose_name="Régime de travail",
                             help_text="% du temps complet")
     regime_travail_nb_heure_semaine = models.DecimalField(max_digits=12,
-                            decimal_places=2, 
+                            decimal_places=2,
                             default=REGIME_TRAVAIL_NB_HEURE_SEMAINE_DEFAULT,
                             verbose_name="Nb. heures par semaine")
 
@@ -550,13 +550,13 @@ class Dossier(DossierWorkflow, models.Model):
                                     verbose_name=u'Compte comptabilité',
                                     choices=COMPTE_COMPTA_CHOICES)
     compte_courriel = models.BooleanField()
-    
+
     # Méta
     date_creation = models.DateTimeField(auto_now_add=True)
+
     # Managers
     objects = DossierManager()
-   
+
     def __unicode__(self):
         return u'[%s] %s - %s' % (self.poste.implantation, self.poste.nom, self.employe)
 
diff --git a/project/dae/templates/dae/embauches_finalisees.html b/project/dae/templates/dae/embauches_finalisees.html
new file mode 100644 (file)
index 0000000..a418c52
--- /dev/null
@@ -0,0 +1,48 @@
+{% extends "base.html" %}
+{% load dae %}
+
+{% block title %}RH - DAE - Embauches{% endblock %}
+{% block titre %}Ressources humaines{% endblock %}
+{% block sous_titre %}Demande d'autorisation d'engagement{% endblock %}
+{% block extrahead %}
+<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/dae.css" />
+<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/tablesorter.css" />
+<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery-1.5.1.min.js"></script>
+<script type="text/javascript">
+  $(document).ready(function() {
+    $('table.tablesorter thead th').click(function() {
+      window.location.href = $(this).find('a').attr('href');
+    });
+  });
+</script>
+{% endblock %}
+
+{% block main %}
+<h1>Liste des demandes d'autorisation d'engagement finalisées</h1>
+
+<table class="listing tablesorter">
+  <thead>
+    <tr>
+      {% sort_header "region" "Région" %}
+      {% sort_header "implantation" "Implantation" %}
+      {% sort_header "poste" "Poste" %}
+      {% sort_header "personne" "Personne" %}
+      {% sort_header "debut_contrat" "Début du contrat" %}
+      {% sort_header "fin_contrat" "Fin du contrat" %}
+    </tr>
+  </thead>
+  <tbody>
+    {% for dossier in embauches.object_list %}
+    <tr>
+      <td>{{ dossier.poste.implantation|region_ou_service }}</td>
+      <td>{{ dossier.poste.implantation }}</td>
+      <td><a href="{% url embauche_consulter dossier.id %}">{{ dossier.poste.nom }}</a></td>
+      <td><a href="{% url embauche_consulter dossier.id %}">{{ dossier.employe }}</a></td>
+      <td>{{ dossier.date_debut_contrat|date:"d-m-Y" }}</td>
+      <td>{{ dossier.date_fin_contrat|date:"d-m-Y" }}</td>
+    </tr>
+    {% endfor %}
+  </tbody>
+</table>
+{% pagination embauches %}
+{% endblock %}
diff --git a/project/dae/templates/dae/pagination.html b/project/dae/templates/dae/pagination.html
new file mode 100644 (file)
index 0000000..cf060dc
--- /dev/null
@@ -0,0 +1,13 @@
+<div class="pagination">
+  {% if page.has_previous %}
+  <a href="?{{ previous_qs }}">« Précédent</a>
+  {% else %}
+  « Précédent
+  {% endif %}
+  | {{ page.start_index }} - {{ page.end_index }} de {{ page.paginator.count }} |
+  {% if page.has_next %}
+  <a href="?{{ next_qs }}">Suivant »</a>
+  {% else %}
+  Suivant »
+  {% endif %}
+</div>
diff --git a/project/dae/templates/dae/sort_header.html b/project/dae/templates/dae/sort_header.html
new file mode 100644 (file)
index 0000000..92e92c6
--- /dev/null
@@ -0,0 +1 @@
+<th class="{{ cls }}"><a href="?{{ qs }}">{{ title }}</a></th>
index cdfc638..45ead51 100644 (file)
@@ -40,3 +40,29 @@ def region_ou_service(implantation):
 @register.filter
 def basename(path):
     return os.path.basename(path)
+
+@register.inclusion_tag('dae/sort_header.html', takes_context=True)
+def sort_header(context, field, title):
+    """Génère une entête qu'on peut cliquer pour trier la colonne correspondante dans une table."""
+    qs = context['request'].GET.copy()
+    current = qs.get('tri', None)
+    if current == field:
+        cls = 'header headerSortUp'
+        qs['tri'] = '-' + field
+    elif current == '-' + field:
+        cls = 'header headerSortDown'
+        qs['tri'] = field
+    else:
+        cls = 'header'
+        qs['tri'] = field
+    return {'title': title, 'qs': qs.urlencode(), 'cls': cls}
+
+@register.inclusion_tag('dae/pagination.html', takes_context=True)
+def pagination(context, page):
+    """Génère la navigation permettant de se promener de page en page."""
+    qs = context['request'].GET
+    previous_qs = qs.copy()
+    previous_qs['page'] = page.previous_page_number()
+    next_qs = qs.copy()
+    next_qs['page'] = page.next_page_number()
+    return {'page': page, 'previous_qs': previous_qs.urlencode(), 'next_qs': next_qs.urlencode()}
index 78a9f7f..f72ab26 100644 (file)
@@ -14,6 +14,7 @@ urlpatterns = patterns(
 
     # embauche
     url(r'^embauches$', 'embauches_liste', name='dae_embauches_liste'),
+    url(r'^embauches-finalisees$', 'embauches_finalisees', name='embauches_finalisees'),
     url(r'^embauche$', 'embauche_choisir_poste', name='embauche'),
     url(r'^embauche/consulter/(?P<dossier_id>.*)$', 'embauche_consulter', name='embauche_consulter'),
     url(r'^embauche/(?P<key>.*)/(?P<dossier_id>.*)$', 'embauche', name='embauche'),
index 8366f9f..920c72a 100644 (file)
@@ -9,6 +9,7 @@ from simplejson import dumps
 import warnings
 
 from django.core.urlresolvers import reverse
+from django.core.paginator import Paginator, InvalidPage
 from django.http import Http404, HttpResponse, HttpResponseGone
 from django.shortcuts import redirect, render_to_response, get_object_or_404
 from django.views.static import serve
@@ -33,7 +34,7 @@ from decorators import dae_groupe_requis, \
                        dossier_est_modifiable, \
                        poste_est_modifiable, get_contrat
 from forms import *
-from workflow import POSTE_ETAT_DRH_FINALISATION, ETATS_VALIDE
+from workflow import POSTE_ETAT_DRH_FINALISATION, ETATS_VALIDE, DOSSIER_ETAT_FINALISE
 from decorators import redirect_interdiction
 
 def devises():
@@ -330,6 +331,43 @@ def embauches_liste(request):
     vars['embauches_en_cours'] = dae.Dossier.objects.ma_region_ou_service(request.user).order_by('-date_creation')
     return render_to_response('dae/embauches_liste.html', vars, RequestContext(request))
 
+@dae_groupe_requis
+def embauches_finalisees(request):
+    """Liste des embauches finalisées."""
+    embauches = dae.Dossier.objects.ma_region_ou_service(request.user) \
+            .filter(etat=DOSSIER_ETAT_FINALISE)
+
+    # Tri
+    tri = request.GET.get('tri', None)
+    if tri.startswith('-'):
+        dir = '-'
+        tri = tri[1:]
+    else:
+        dir = ''
+    if tri == 'region':
+        embauches = embauches.order_by(dir + 'poste__implantation__region__nom')
+    elif tri == 'implantation':
+        embauches = embauches.order_by(dir + 'poste__implantation__nom')
+    elif tri == 'poste':
+        embauches = embauches.order_by(dir + 'poste__nom')
+    elif tri == 'personne':
+        embauches = embauches.order_by(dir + 'employe__nom', 'employe__prenom')
+    elif tri == 'date_debut':
+        embauches = embauches.order_by(dir + 'debut_contrat')
+    elif tri == 'date_fin':
+        embauches = embauches.order_by(dir + 'fin_contrat')
+
+    # Pagination
+    paginator = Paginator(embauches, 20)
+    try:
+        page = paginator.page(request.GET.get('page', 1))
+    except InvalidPage:
+        page = paginator.page(1)
+
+    return render_to_response('dae/embauches_finalisees.html', {
+        'embauches': page
+    }, RequestContext(request))
+
 def employe(request, key):
     """ Récupération AJAX de l'employé pour la page d'embauche. """
     data = dict(employe=key)
index 727777f..7e15c6c 100644 (file)
@@ -16,3 +16,5 @@ h2.section {width:100%; background-color: #D0E8F8; text-align: center; color: #5
 .bouton-action {border:1px #BBD8EC solid; font-size: 14px; font-weight: bold; margin: 12px 0; padding: 4px 8px; color: #BBD8EC; margin-left: 6px;}
 #type_intervention li {float: left; list-style: none; font-size: 1.6em; margin: 0 1em 0 0;}
 .justifications h4 {font-weight: bold; }
+.pagination { text-align: center; }
+table.listing { width: 100%; }
index cf8ef80..21751f5 100644 (file)
@@ -67,11 +67,10 @@ INSTALLED_APPS = (
     'ajax_select',
     'south',
     'reversion',
-    'project.rh', 
+    'project.rh',
     'auf.django.workflow',
     'project.rh_v1',
     'project.dae',
-    #'project.budget',
     'alphafilter',
     'project.recrutement',
     'form_utils',
index 6076c2f..3ed89f2 100644 (file)
@@ -7,22 +7,25 @@
     <li class="{% menu_actif request '^dae$' %}">
         <a href="{% url dae_index %}">DAE</a>
         <ul>
-        {% if request.user|peut_ajouter %}
-        <li class="{% menu_actif request '^poste$' %}">
-            <a href="{% url poste %}">Poste : formulaire</a>
-        </li>
-        {% endif %}
-        <li class="{% menu_actif request '^postes$' %}">
-            <a href="{% url dae_postes_liste %}">Postes : voir et valider</a>
-        </li>
-        {% if request.user|peut_ajouter %}
-        <li class="{% menu_actif request '^embauche$' %}">
-            <a href="{% url embauche %}">Embauche : formulaire</a>
-        </li>
-        {% endif %}
-        <li class="{% menu_actif request '^embauches$' %}">
-            <a href="{% url dae_embauches_liste %}">Embauches : voir et valider</a>
-        </li>
+          {% if request.user|peut_ajouter %}
+          <li class="{% menu_actif request '^poste$' %}">
+          <a href="{% url poste %}">Poste : formulaire</a>
+          </li>
+          {% endif %}
+          <li class="{% menu_actif request '^postes$' %}">
+          <a href="{% url dae_postes_liste %}">Postes : voir et valider</a>
+          </li>
+          {% if request.user|peut_ajouter %}
+          <li class="{% menu_actif request '^embauche$' %}">
+          <a href="{% url embauche %}">Embauche : formulaire</a>
+          </li>
+          {% endif %}
+          <li class="{% menu_actif request '^embauches$' %}">
+          <a href="{% url dae_embauches_liste %}">Embauches : voir et valider</a>
+          </li>
+          <li class="{% menu_actif request '^embauches_finalisees$' %}">
+          <a href="{% url embauches_finalisees %}">Embauches finalisées</a>
+          </li>
         </ul>
     </li>
     {% else %}