merge dev
authorOlivier Larchevêque <olivier.larcheveque@auf.org>
Wed, 10 Aug 2011 16:10:47 +0000 (12:10 -0400)
committerOlivier Larchevêque <olivier.larcheveque@auf.org>
Wed, 10 Aug 2011 16:10:47 +0000 (12:10 -0400)
1  2 
buildout.cfg
project/dae/models.py
project/rh/models.py
project/settings.py
project/urls.py

diff --combined buildout.cfg
@@@ -12,7 -12,7 +12,7 @@@ find-links = http://pypi.auf.org/simple
      http://pypi.auf.org/simple/auf.django.metadata/
      http://pypi.auf.org/django-alphafilter/
  
 -develop = src/auf.django.emploi
 +develop = src/*
  
  eggs =
      django
@@@ -21,6 -21,7 +21,7 @@@
      auf.django.skin
      auf.django.workflow
      auf.django.admingroup
+     auf.django.emploi
      datamaster_modeles
      auf.django.auth
      django-reversion
@@@ -31,7 -32,6 +32,7 @@@
      django-form-utils
      django-tinymce
      django-simple-captcha
 +    django-qbe
  
  # LA PROD ne dispose que de reportlab 2.1, incompatible avec
  # les versions de pisa assez évoluées pour un bon rendu.
@@@ -46,10 -46,11 +47,11 @@@ django = 1.2.
  south = 0.7
  auf.django.skin = 0.15dev
  auf.django.auth = 0.5.5dev
+ auf.django.metadata = 0.2dev
  django-reversion = 1.3.3
  auf.django.workflow = 0.14dev
  django-ajax-selects = 1.1.4
- django-alphafilter = 0.5.3auf2
+ django-alphafilter = 0.5.3auf4
  #reportlab = 2.5
  #html5lib = 0.90
  #pyPDF = 1.13
diff --combined project/dae/models.py
@@@ -52,32 -52,32 +52,32 @@@ class Poste(PosteWorkflow, models.Model
      # Modèle existant
      id_rh = models.ForeignKey(rh.Poste, null=True, related_name='+',
                              editable=False,
 -                            verbose_name="Mise à jour du poste")
 -    nom = models.CharField(verbose_name="Titre du poste", max_length=255)
 +                            verbose_name=u"Mise à jour du poste")
 +    nom = models.CharField(verbose_name=u"Titre du poste", max_length=255)
      implantation = models.ForeignKey(ref.Implantation)
      type_poste = models.ForeignKey(rh.TypePoste, null=True, related_name='+')
      service = models.ForeignKey(rh.Service, related_name='+',
                              verbose_name=u"Direction/Service/Pôle support")
      responsable = models.ForeignKey(rh.Poste, related_name='+',
 -                            verbose_name="Poste du responsable")
 +                            verbose_name=u"Poste du responsable")
  
      # Contrat
      regime_travail = models.DecimalField(max_digits=12, decimal_places=2,
                              default=REGIME_TRAVAIL_DEFAULT, 
 -                            verbose_name="Temps de travail", 
 +                            verbose_name=u"Temps de travail", 
                              help_text="% du temps complet")
      regime_travail_nb_heure_semaine = models.DecimalField(max_digits=12,
                              decimal_places=2,
                              default=REGIME_TRAVAIL_NB_HEURE_SEMAINE_DEFAULT,
 -                            verbose_name="Nb. heures par semaine")
 +                            verbose_name=u"Nb. heures par semaine")
  
      # Recrutement
 -    local = models.BooleanField(verbose_name="Local", default=True, blank=True)
 -    expatrie = models.BooleanField(verbose_name="Expatrié", default=False, 
 +    local = models.BooleanField(verbose_name=u"Local", default=True, blank=True)
 +    expatrie = models.BooleanField(verbose_name=u"Expatrié", default=False, 
                              blank=True)
 -    mise_a_disposition = models.BooleanField(verbose_name="Mise à disposition")
 +    mise_a_disposition = models.BooleanField(verbose_name=u"Mise à disposition")
      appel = models.CharField(max_length=10, default='interne',
 -                            verbose_name="Appel à candidature",
 +                            verbose_name=u"Appel à candidature",
                              choices=POSTE_APPEL_CHOICES)
  
      # Rémunération
      # Méta
      date_creation = models.DateTimeField(auto_now_add=True)
      date_modification = models.DateTimeField(auto_now=True)
-     date_debut = models.DateField(verbose_name=u"Date de début",
-                                     help_text=HELP_TEXT_DATE)
+     date_debut = models.DateField(verbose_name="Date de début",
+                                     help_text=HELP_TEXT_DATE,
+                                     null=True, blank=True)
      date_fin = models.DateField(null=True, blank=True,
 -                                    verbose_name="Date de fin",
 +                                    verbose_name=u"Date de fin",
                                      help_text=HELP_TEXT_DATE)
      actif = models.BooleanField(default=True)
  
@@@ -371,18 -372,29 +372,29 @@@ class PostePiece(models.Model)
      Ex.: Description de poste
      """
      poste = models.ForeignKey("Poste")
 -    nom = models.CharField(verbose_name="Nom", max_length=255)
 -    fichier = models.FileField(verbose_name="Fichier", 
 +    nom = models.CharField(verbose_name=u"Nom", max_length=255)
 +    fichier = models.FileField(verbose_name=u"Fichier", 
                              upload_to=poste_piece_dispatch, 
                              storage=storage_prive)
  
  class PosteComparaison(models.Model):
      poste = models.ForeignKey('Poste', related_name='comparaisons_internes')
      implantation = models.ForeignKey(ref.Implantation, null=True, blank=True, related_name="+")
-     nom = models.CharField(verbose_name=u"Poste", max_length=255, null=True, blank=True)
+     statut = models.ForeignKey(rh.Statut, related_name='+', verbose_name='Statut', null=True, blank=True, )
+     classement = models.ForeignKey(rh.Classement, related_name='+', verbose_name='Classement', null=True, blank=True, )
+     nom = models.CharField(verbose_name="Poste", max_length=255, null=True, blank=True)
      montant = models.IntegerField(null=True)
      devise = models.ForeignKey(rh.Devise, default=5, related_name='+', null=True, blank=True)
-     montant_euros = models.IntegerField(null=True)
+     def taux_devise(self):
+         liste_taux = self.devise.tauxchange_set.order_by('-annee').filter(implantation=self.implantation)
+         if len(liste_taux) == 0:
+             raise Exception(u"La devise %s n'a pas de taux pour l'implantation %s" % (self.devise, self.implantation))
+         else:
+             return liste_taux[0].taux
+     def montant_euros(self):
+         return round(float(self.montant) * float(self.taux_devise()), 2)
  
  
  ### EMPLOYÉ/PERSONNE
@@@ -398,9 -410,9 +410,9 @@@ class Employe(models.Model)
  
      # Modèle existant
      id_rh = models.ForeignKey(rh.Employe, null=True, related_name='+', 
 -                            verbose_name='Employé')
 +                            verbose_name=u'Employé')
      nom = models.CharField(max_length=255)
 -    prenom = models.CharField(max_length=255, verbose_name='Prénom')
 +    prenom = models.CharField(max_length=255, verbose_name=u'Prénom')
      genre = models.CharField(max_length=1, choices=GENRE_CHOICES)
  
      def __unicode__(self):
@@@ -428,64 -440,65 +440,65 @@@ class Dossier(DossierWorkflow, models.M
      statut = models.ForeignKey(rh.Statut, related_name='+')
      organisme_bstg = models.ForeignKey(rh.OrganismeBstg, 
              null=True, blank=True,
 -            verbose_name="Organisme", 
 +            verbose_name=u"Organisme", 
              help_text="Si détaché (DET) ou mis à disposition (MAD), \
                      préciser l'organisme.",
              related_name='+')
      organisme_bstg_autre = models.CharField(max_length=255,
 -        verbose_name="Autre organisme",
 +        verbose_name=u"Autre organisme",
          help_text="indiquer l'organisme ici s'il n'est pas dans la liste",
          null=True,
          blank=True,)
  
      # Données antérieures de l'employé
+     # la devise??
      statut_anterieur = models.ForeignKey(
              rh.Statut, related_name='+', null=True, blank=True,
 -            verbose_name='Statut antérieur')
 +            verbose_name=u'Statut antérieur')
      classement_anterieur = models.ForeignKey(
              rh.Classement, related_name='+', null=True, blank=True,
 -            verbose_name='Classement précédent')
 +            verbose_name=u'Classement précédent')
      salaire_anterieur = models.DecimalField(
              max_digits=12, decimal_places=2, null=True, default=None,
 -            blank=True, verbose_name='Salaire précédent')
 +            blank=True, verbose_name=u'Salaire précédent')
  
      # Données du titulaire précédent
      employe_anterieur = models.ForeignKey(
              rh.Employe, related_name='+', null=True, blank=True,
 -            verbose_name='Employé précédent')
 +            verbose_name=u'Employé précédent')
      statut_titulaire_anterieur = models.ForeignKey(
              rh.Statut, related_name='+', null=True, blank=True,
 -            verbose_name='Statut titulaire précédent')
 +            verbose_name=u'Statut titulaire précédent')
      classement_titulaire_anterieur = models.ForeignKey(
              rh.Classement, related_name='+', null=True, blank=True,
 -            verbose_name='Classement titulaire précédent')
 +            verbose_name=u'Classement titulaire précédent')
      salaire_titulaire_anterieur = models.DecimalField(
              max_digits=12, decimal_places=2, default=None, null=True,
 -            blank=True, verbose_name='Salaire titulaire précédent')
 +            blank=True, verbose_name=u'Salaire titulaire précédent')
  
      # Recrutement
      remplacement = models.BooleanField()
      statut_residence = models.CharField(max_length=10, default='local', 
 -                            verbose_name="Statut",
 +                            verbose_name=u"Statut",
                              choices=STATUT_RESIDENCE_CHOICES)
  
      # Rémunération
      classement = models.ForeignKey(rh.Classement, related_name='+',
                              null=True, blank=True,
 -                            verbose_name='Classement proposé')
 +                            verbose_name=u'Classement proposé')
      salaire = models.DecimalField(max_digits=12, decimal_places=2,
 -                            verbose_name='Salaire de base',
 +                            verbose_name=u'Salaire de base',
                              null=True, default=None)
      devise = models.ForeignKey(rh.Devise, default=5, related_name='+')
      regime_travail = models.DecimalField(max_digits=12, 
                              decimal_places=2,
                              default=REGIME_TRAVAIL_DEFAULT,
 -                            verbose_name="Régime de travail",
 +                            verbose_name=u"Régime de travail",
                              help_text="% du temps complet")
      regime_travail_nb_heure_semaine = models.DecimalField(max_digits=12,
                              decimal_places=2, 
                              default=REGIME_TRAVAIL_NB_HEURE_SEMAINE_DEFAULT,
 -                            verbose_name="Nb. heures par semaine")
 +                            verbose_name=u"Nb. heures par semaine")
  
      # Contrat
      type_contrat = models.ForeignKey(rh.TypeContrat, related_name='+')
@@@ -633,8 -646,8 +646,8 @@@ class DossierPiece(models.Model)
      Ex.: Lettre de motivation.
      """
      dossier = models.ForeignKey("Dossier")
 -    nom = models.CharField(verbose_name="Nom", max_length=255)
 -    fichier = models.FileField(verbose_name="Fichier", 
 +    nom = models.CharField(verbose_name=u"Nom", max_length=255)
 +    fichier = models.FileField(verbose_name=u"Fichier", 
                              upload_to=dossier_piece_dispatch, 
                              storage=storage_prive)
  
@@@ -644,12 -657,24 +657,24 @@@ class DossierComparaison(models.Model)
      Photo d'une comparaison salariale au moment de l'embauche.
      """
      dossier = models.ForeignKey('Dossier', related_name='comparaisons')
+     statut = models.ForeignKey(rh.Statut, related_name='+', verbose_name='Statut', null=True, blank=True, )
+     classement = models.ForeignKey(rh.Classement, related_name='+', verbose_name='Classement', null=True, blank=True, )
      implantation = models.ForeignKey(ref.Implantation, null=True, blank=True)
      poste = models.CharField(max_length=255, null=True, blank=True)
      personne = models.CharField(max_length=255, null=True, blank=True)
      montant = models.IntegerField(null=True)
      devise = models.ForeignKey(rh.Devise, default=5, related_name='+', null=True, blank=True)
-     montant_euros = models.IntegerField(null=True)
+     def taux_devise(self):
+         liste_taux = self.devise.tauxchange_set.order_by('-annee').filter(implantation=self.dossier.poste.implantation)
+         if len(liste_taux) == 0:
+             raise Exception(u"La devise %s n'a pas de taux pour l'implantation %s" % (self.devise, self.dossier.poste.implantation))
+         else:
+             return liste_taux[0].taux
+     def montant_euros(self):
+         return round(float(self.montant) * float(self.taux_devise()), 2)
  
  
  ### RÉMUNÉRATION
diff --combined project/rh/models.py
@@@ -6,7 -6,7 +6,7 @@@ from django.conf import setting
  from auf.django.metadata.models import AUFMetadata
  from auf.django.metadata.managers import NoDeleteManager
  import datamaster_modeles.models as ref
+ from validators import validate_date_passee
  
  # Constantes
  HELP_TEXT_DATE = "format: aaaa-mm-jj"
@@@ -60,9 -60,9 +60,9 @@@ class Poste_(AUFMetadata)
  
      # Identification
      nom = models.CharField(max_length=255, 
 -                            verbose_name="Titre du poste", )
 +                            verbose_name = u"Titre du poste", )
      nom_feminin = models.CharField(max_length=255,
 -                            verbose_name="Titre du poste (au féminin)",
 +                            verbose_name = u"Titre du poste (au féminin)",
                              null=True)
      implantation = models.ForeignKey(ref.Implantation, 
                              db_column='implantation', related_name='+')
                              null=True)
      service = models.ForeignKey('Service', db_column='service', null=True,
                              related_name='+',
 -                            verbose_name="Direction/Service/Pôle support",
 +                            verbose_name = u"Direction/Service/Pôle support",
                              default=1)  # default = Rectorat
      responsable = models.ForeignKey('Poste', db_column='responsable', 
                              related_name='+', null=True,
 -                            verbose_name="Poste du responsable",
 +                            verbose_name = u"Poste du responsable",
                              default=149)    # default = Recteur
                                  
      # Contrat
      regime_travail = models.DecimalField(max_digits=12, decimal_places=2,
                              default=REGIME_TRAVAIL_DEFAULT, null=True,
 -                            verbose_name="Temps de travail", 
 +                            verbose_name = u"Temps de travail", 
                              help_text="% du temps complet")
      regime_travail_nb_heure_semaine = models.DecimalField(max_digits=12,
                              decimal_places=2, null=True,
                              default=REGIME_TRAVAIL_NB_HEURE_SEMAINE_DEFAULT,
 -                            verbose_name="Nb. heures par semaine")
 +                            verbose_name = u"Nb. heures par semaine")
  
      # Recrutement
 -    local = models.NullBooleanField(verbose_name="Local", default=True, 
 +    local = models.NullBooleanField(verbose_name = u"Local", default=True, 
                              null=True, blank=True)
 -    expatrie = models.NullBooleanField(verbose_name="Expatrié", default=False, 
 +    expatrie = models.NullBooleanField(verbose_name = u"Expatrié", default=False, 
                              null=True, blank=True)
      mise_a_disposition = models.NullBooleanField(
 -                            verbose_name="Mise à disposition",
 +                            verbose_name = u"Mise à disposition",
                              null=True, default=False)
      appel = models.CharField(max_length=10, null=True,
 -                            verbose_name="Appel à candidature",
 +                            verbose_name = u"Appel à candidature",
                              choices=POSTE_APPEL_CHOICES,
                              default='interne')
  
  
      # Autres Metadata
      date_validation = models.DateTimeField(null=True, blank=True)   # de dae
-     date_debut = models.DateField(verbose_name = u"Date de début", null=True,
-                             help_text=HELP_TEXT_DATE)
-     date_fin = models.DateField(verbose_name = u"Date de fin",
+     date_debut = models.DateField(verbose_name="Date de début",
+                             help_text=HELP_TEXT_DATE,
+                             null=True, blank=True)
+     date_fin = models.DateField(verbose_name="Date de fin",
                              help_text=HELP_TEXT_DATE,
                              null=True, blank=True)
  
      class Meta:
          abstract = True
          ordering = ['implantation__nom', 'nom']
 -        verbose_name = "Poste"
 -        verbose_name_plural = "Postes"
 +        verbose_name = u"Poste"
 +        verbose_name_plural = u"Postes"
  
      def __unicode__(self):
          representation = u'%s - %s [%s]' % (self.implantation, self.nom, 
@@@ -232,8 -233,8 +233,8 @@@ class PostePiece(models.Model)
      """
      poste = models.ForeignKey('Poste', db_column='poste', 
                              related_name='pieces')
 -    nom = models.CharField(verbose_name="Nom", max_length=255)
 -    fichier = models.FileField(verbose_name="Fichier", 
 +    nom = models.CharField(verbose_name = u"Nom", max_length=255)
 +    fichier = models.FileField(verbose_name = u"Fichier", 
                              upload_to=poste_piece_dispatch, 
                              storage=storage_prive)
  
@@@ -249,10 -250,19 +250,19 @@@ class PosteComparaison(models.Model)
      """
      poste = models.ForeignKey('Poste', related_name='comparaisons_internes')
      implantation = models.ForeignKey(ref.Implantation, null=True, blank=True, related_name="+")
 -    nom = models.CharField(verbose_name="Poste", max_length=255, null=True, blank=True)
 +    nom = models.CharField(verbose_name = u"Poste", max_length=255, null=True, blank=True)
      montant = models.IntegerField(null=True)
      devise = models.ForeignKey("Devise", default=5, related_name='+', null=True, blank=True)
-     montant_euros = models.IntegerField(null=True)
+     def taux_devise(self):
+         liste_taux = self.devise.tauxchange_set.order_by('-annee').filter(implantation=self.implantation)
+         if len(liste_taux) == 0:
+             raise Exception(u"La devise %s n'a pas de taux pour l'implantation %s" % (self.devise, self.implantation))
+         else:
+             return liste_taux[0].taux
+     def montant_euros(self):
+         return round(float(self.montant) * float(self.taux_devise()), 2)
  
  
  class PosteCommentaire(Commentaire):
@@@ -280,34 -290,35 +290,35 @@@ class Employe(AUFMetadata)
      """
      # Identification
      nom = models.CharField(max_length=255)
 -    prenom = models.CharField(max_length=255, verbose_name="Prénom")
 +    prenom = models.CharField(max_length=255, verbose_name = u"Prénom")
      nom_affichage = models.CharField(max_length=255, 
 -                            verbose_name="Nom d'affichage",
 +                            verbose_name = u"Nom d'affichage",
                              null=True, blank=True)
      nationalite = models.ForeignKey(ref.Pays, to_field='code', 
                              db_column='nationalite',
                              related_name='employes_nationalite',
 -                            verbose_name="Nationalité")
 +                            verbose_name = u"Nationalité")
      date_naissance = models.DateField(help_text=HELP_TEXT_DATE,
 -                            verbose_name="Date de naissance",
 +                            verbose_name = u"Date de naissance",
+                             validators=[validate_date_passee],
                              null=True, blank=True)
      genre = models.CharField(max_length=1, choices=GENRE_CHOICES)
      
      # Infos personnelles
      situation_famille = models.CharField(max_length=1, 
                              choices=SITUATION_CHOICES,
 -                            verbose_name="Situation familiale",
 +                            verbose_name = u"Situation familiale",
                              null=True, blank=True)
 -    date_entree = models.DateField(verbose_name="Date d'entrée à l'AUF",
 +    date_entree = models.DateField(verbose_name = u"Date d'entrée à l'AUF",
                              help_text=HELP_TEXT_DATE, 
                              null=True, blank=True)
      
      # Coordonnées
      tel_domicile = models.CharField(max_length=255, 
 -                            verbose_name="Tél. domicile",
 +                            verbose_name = u"Tél. domicile",
                              null=True, blank=True)
      tel_cellulaire = models.CharField(max_length=255, 
 -                            verbose_name="Tél. cellulaire",
 +                            verbose_name = u"Tél. cellulaire",
                              null=True, blank=True)
      adresse = models.CharField(max_length=255, null=True, blank=True)
      ville = models.CharField(max_length=255, null=True, blank=True)
  
      class Meta:
          ordering = ['nom_affichage','nom','prenom']
 -        verbose_name = "Employé"
 -        verbose_name_plural = "Employés"
 +        verbose_name = u"Employé"
 +        verbose_name_plural = u"Employés"
          
      def __unicode__(self):
          return u'%s' % (self.get_nom())
          if not nom_affichage:
              nom_affichage = u'%s %s' % (self.nom.upper(), self.prenom)
          return nom_affichage
+         
+     def civilite(self):
+         civilite = u''
+         if self.genre.upper() == u'M':
+             civilite = u'M.'
+         elif self.genre.upper() == u'F':
+             civilite = u'Mme'
+         return civilite
  
  class EmployePiece(models.Model):
      """Documents relatifs à un employé.
      """
      employe = models.ForeignKey('Employe', db_column='employe', 
                              related_name='+')
 -    nom = models.CharField(verbose_name="Nom", max_length=255)
 -    fichier = models.FileField(verbose_name="Fichier", 
 +    nom = models.CharField(verbose_name = u"Nom", max_length=255)
 +    fichier = models.FileField(verbose_name = u"Fichier", 
                              upload_to=dossier_piece_dispatch, 
                              storage=storage_prive)
  
@@@ -366,32 -385,33 +385,33 @@@ class AyantDroit(AUFMetadata)
      # Identification
      nom = models.CharField(max_length=255)
      prenom = models.CharField(max_length=255,
 -                            verbose_name="Prénom",)
 +                            verbose_name = u"Prénom",)
      nom_affichage = models.CharField(max_length=255, 
 -                            verbose_name="Nom d'affichage",
 +                            verbose_name = u"Nom d'affichage",
                              null=True, blank=True)
      nationalite = models.ForeignKey(ref.Pays, to_field='code', 
                              db_column='nationalite',
                              related_name='ayantdroits_nationalite',
 -                            verbose_name="Nationalité")
 +                            verbose_name = u"Nationalité")
      date_naissance = models.DateField(help_text=HELP_TEXT_DATE,
 -                            verbose_name="Date de naissance",
 +                            verbose_name = u"Date de naissance",
+                             validators=[validate_date_passee],
                              null=True, blank=True)
      genre = models.CharField(max_length=1, choices=GENRE_CHOICES)
      
      # Relation
      employe = models.ForeignKey('Employe', db_column='employe', 
                              related_name='ayantdroits',
 -                            verbose_name="Employé")
 +                            verbose_name = u"Employé")
      lien_parente = models.CharField(max_length=10, 
                              choices=LIEN_PARENTE_CHOICES,
 -                            verbose_name="Lien de parenté",
 +                            verbose_name = u"Lien de parenté",
                              null=True, blank=True)
  
      class Meta:
          ordering = ['nom_affichage']
 -        verbose_name = "Ayant droit"
 -        verbose_name_plural = "Ayants droit"
 +        verbose_name = u"Ayant droit"
 +        verbose_name_plural = u"Ayants droit"
          
      def __unicode__(self):
          return u'%s' % (self.get_nom())
@@@ -431,15 -451,15 +451,15 @@@ class Dossier_(AUFMetadata)
      """
      # Identification
      employe = models.ForeignKey('Employe', db_column='employe', 
-                             related_name='+',
-                             verbose_name = u"Employé")
+                             related_name='dossiers',
 -                            verbose_name="Employé")
++                            verbose_name=u"Employé")
      poste = models.ForeignKey('Poste', db_column='poste', related_name='+')
      statut = models.ForeignKey('Statut', related_name='+', default=3,
                              null=True)
      organisme_bstg = models.ForeignKey('OrganismeBstg', 
                              db_column='organisme_bstg',
                              related_name='+',
 -                            verbose_name="Organisme", 
 +                            verbose_name = u"Organisme", 
                              help_text="Si détaché (DET) ou \
                                      mis à disposition (MAD), \
                                      préciser l'organisme.",
      # Recrutement
      remplacement = models.BooleanField(default=False)
      statut_residence = models.CharField(max_length=10, default='local', 
 -                            verbose_name="Statut", null=True,
 +                            verbose_name = u"Statut", null=True,
                              choices=STATUT_RESIDENCE_CHOICES)
     
      # Rémunération
      regime_travail = models.DecimalField(max_digits=12, null=True,
                              decimal_places=2,
                              default=REGIME_TRAVAIL_DEFAULT,
 -                            verbose_name="Régime de travail",
 +                            verbose_name = u"Régime de travail",
                              help_text="% du temps complet")
      regime_travail_nb_heure_semaine = models.DecimalField(max_digits=12,
                              decimal_places=2, null=True,
                              default=REGIME_TRAVAIL_NB_HEURE_SEMAINE_DEFAULT,
 -                            verbose_name="Nb. heures par semaine")
 +                            verbose_name = u"Nb. heures par semaine")
  
      # Occupation du Poste par cet Employe (anciennement "mandat")
 -    date_debut = models.DateField(verbose_name="Date de début d'occupation \
 +    date_debut = models.DateField(verbose_name = u"Date de début d'occupation \
                              de poste",
                              help_text=HELP_TEXT_DATE)
 -    date_fin = models.DateField(verbose_name="Date de fin d'occupation \
 +    date_fin = models.DateField(verbose_name = u"Date de fin d'occupation \
                              de poste",
                              help_text=HELP_TEXT_DATE,
                              null=True, blank=True)
      
      class Meta:
          abstract = True
-         ordering = ['employe__nom_affichage', 'employe__nom', 'poste__nom']
-         verbose_name = u"Dossier"
-         verbose_name_plural = u"Dossiers"
+         ordering = ['employe__nom', ]
+         verbose_name = "Dossier"
+         verbose_name_plural = "Dossiers"
          
      def __unicode__(self):
          poste = self.poste.nom
@@@ -494,19 -514,14 +514,14 @@@ class Dossier(Dossier_)
      __doc__ = Dossier_.__doc__
  
  
- class Dossier(Dossier_):
-     __doc__ = Dossier_.__doc__
  class DossierPiece(models.Model):
      """Documents relatifs au Dossier (à l'occupation de ce poste par employé).
      Ex.: Lettre de motivation.
      """
      dossier = models.ForeignKey('Dossier', db_column='dossier', 
                              related_name='+')
 -    nom = models.CharField(verbose_name="Nom", max_length=255)
 -    fichier = models.FileField(verbose_name="Fichier", 
 +    nom = models.CharField(verbose_name = u"Nom", max_length=255)
 +    fichier = models.FileField(verbose_name = u"Fichier", 
                              upload_to=dossier_piece_dispatch, 
                              storage=storage_prive)
  
@@@ -520,6 -535,27 +535,27 @@@ class DossierCommentaire(Commentaire)
      dossier = models.ForeignKey('Dossier', db_column='dossier', 
                              related_name='+')
  
+ class DossierComparaison(models.Model):
+     """
+     Photo d'une comparaison salariale au moment de l'embauche.
+     """
+     dossier = models.ForeignKey('Dossier', related_name='comparaisons')
+     implantation = models.ForeignKey(ref.Implantation, related_name="+", null=True, blank=True)
+     poste = models.CharField(max_length=255, null=True, blank=True)
+     personne = models.CharField(max_length=255, null=True, blank=True)
+     montant = models.IntegerField(null=True)
+     devise = models.ForeignKey('Devise', default=5, related_name='+', null=True, blank=True)
+     def taux_devise(self):
+         liste_taux = self.devise.tauxchange_set.order_by('-annee').filter(implantation=self.dossier.poste.implantation)
+         if len(liste_taux) == 0:
+             raise Exception(u"La devise %s n'a pas de taux pour l'implantation %s" % (self.devise, self.dossier.poste.implantation))
+         else:
+             return liste_taux[0].taux
+     def montant_euros(self):
+         return round(float(self.montant) * float(self.taux_devise()), 2)
  
  ### RÉMUNÉRATION
      
@@@ -529,11 -565,11 +565,11 @@@ class RemunerationMixin(AUFMetadata)
                          related_name='%(app_label)s_%(class)s_remunerations')
      type = models.ForeignKey('TypeRemuneration', db_column='type', 
                              related_name='+',
 -                            verbose_name="Type de rémunération")
 +                            verbose_name = u"Type de rémunération")
      type_revalorisation = models.ForeignKey('TypeRevalorisation', 
                              db_column='type_revalorisation', 
                              related_name='+',
 -                            verbose_name="Type de revalorisation",
 +                            verbose_name = u"Type de revalorisation",
                              null=True, blank=True)
      montant = models.FloatField(null=True, blank=True,
                              default=0)
      commentaire = models.CharField(max_length=255, null=True, blank=True)
      # date_debut = anciennement date_effectif
      date_debut = models.DateField(help_text=HELP_TEXT_DATE,
 -                            verbose_name="Date de début",
 +                            verbose_name = u"Date de début",
                              null=True, blank=True)
      date_fin = models.DateField(help_text=HELP_TEXT_DATE,
 -                            verbose_name="Date de fin",
 +                            verbose_name = u"Date de fin",
                              null=True, blank=True)
      
      class Meta: 
@@@ -585,8 -621,8 +621,8 @@@ class Remuneration_(RemunerationMixin)
  
      class Meta:
          abstract = True
 -        verbose_name = "Rémunération"
 -        verbose_name_plural = "Rémunérations"
 +        verbose_name = u"Rémunération"
 +        verbose_name_plural = u"Rémunérations"
  
  
  class Remuneration(Remuneration_):
@@@ -612,17 -648,17 +648,17 @@@ class Contrat(AUFMetadata)
                              related_name='+')
      type_contrat = models.ForeignKey('TypeContrat', db_column='type_contrat', 
                              related_name='+',
 -                            verbose_name="Type de contrat")
 +                            verbose_name = u"Type de contrat")
      date_debut = models.DateField(help_text=HELP_TEXT_DATE,
 -                            verbose_name="Date de début")
 +                            verbose_name = u"Date de début")
      date_fin = models.DateField(help_text=HELP_TEXT_DATE,
 -                            verbose_name="Date de fin",
 +                            verbose_name = u"Date de fin",
                              null=True, blank=True)
  
      class Meta:
          ordering = ['dossier__employe__nom_affichage']
 -        verbose_name = "Contrat"
 -        verbose_name_plural = "Contrats"
 +        verbose_name = u"Contrat"
 +        verbose_name_plural = u"Contrats"
          
      def __unicode__(self):
          return u'%s - %s' % (self.dossier, self.id)
@@@ -648,16 -684,16 +684,16 @@@ class Evenement_(AUFMetadata)
                              related_name='+')
      nom = models.CharField(max_length=255)
      date_debut = models.DateField(help_text=HELP_TEXT_DATE,
 -                            verbose_name="Date de début")
 +                            verbose_name = u"Date de début")
      date_fin = models.DateField(help_text=HELP_TEXT_DATE,
 -                            verbose_name="Date de fin",
 +                            verbose_name = u"Date de fin",
                              null=True, blank=True)
  
      class Meta:
          abstract = True
          ordering = ['nom']
 -        verbose_name = "Évènement"
 -        verbose_name_plural = "Évènements"
 +        verbose_name = u"Évènement"
 +        verbose_name_plural = u"Évènements"
                              
      def __unicode__(self):
          return u'%s' % (self.nom)
@@@ -674,15 -710,15 +710,15 @@@ class EvenementRemuneration_(Remunerati
      """
      evenement = models.ForeignKey("Evenement", db_column='evenement',
                              related_name='+',
 -                            verbose_name="Évènement")
 +                            verbose_name = u"Évènement")
      # TODO : le champ dossier hérité de Remuneration doit être dérivé
      # de l'Evenement associé
  
      class Meta:
          abstract = True
          ordering = ['evenement', 'type__nom', '-date_fin']
 -        verbose_name = "Évènement - rémunération"
 -        verbose_name_plural = "Évènements - rémunérations"
 +        verbose_name = u"Évènement - rémunération"
 +        verbose_name_plural = u"Évènements - rémunérations"
  
  
  class EvenementRemuneration(EvenementRemuneration_):
@@@ -706,8 -742,8 +742,8 @@@ class FamilleEmploi(AUFMetadata)
      
      class Meta:
          ordering = ['nom']
 -        verbose_name = "Famille d'emploi"
 -        verbose_name_plural = "Familles d'emploi"
 +        verbose_name = u"Famille d'emploi"
 +        verbose_name_plural = u"Familles d'emploi"
      
      def __unicode__(self):
          return u'%s' % (self.nom)
@@@ -717,19 -753,19 +753,19 @@@ class TypePoste(AUFMetadata)
      """
      nom = models.CharField(max_length=255)
      nom_feminin = models.CharField(max_length=255,
 -                            verbose_name="Nom féminin")
 +                            verbose_name = u"Nom féminin")
      
      is_responsable = models.BooleanField(default=False,
 -                            verbose_name="Poste de responsabilité")
 +                            verbose_name = u"Poste de responsabilité")
      famille_emploi = models.ForeignKey('FamilleEmploi', 
                              db_column='famille_emploi',
                              related_name='+',
 -                            verbose_name="Famille d'emploi")
 +                            verbose_name = u"Famille d'emploi")
  
      class Meta:
          ordering = ['nom']
 -        verbose_name = "Type de poste"
 -        verbose_name_plural = "Types de poste"
 +        verbose_name = u"Type de poste"
 +        verbose_name_plural = u"Types de poste"
          
      def __unicode__(self):
          return u'%s' % (self.nom)
@@@ -754,15 -790,15 +790,15 @@@ class TypeRemuneration(AUFMetadata)
      nom = models.CharField(max_length=255)
      type_paiement = models.CharField(max_length=30, 
                              choices=TYPE_PAIEMENT_CHOICES,
 -                            verbose_name="Type de paiement")
 +                            verbose_name = u"Type de paiement")
      nature_remuneration = models.CharField(max_length=30, 
                              choices=NATURE_REMUNERATION_CHOICES,
 -                            verbose_name="Nature de la rémunération")
 +                            verbose_name = u"Nature de la rémunération")
                              
      class Meta:
          ordering = ['nom']
 -        verbose_name = "Type de rémunération"
 -        verbose_name_plural = "Types de rémunération"
 +        verbose_name = u"Type de rémunération"
 +        verbose_name_plural = u"Types de rémunération"
  
      def __unicode__(self):
          return u'%s' % (self.nom)
@@@ -775,8 -811,8 +811,8 @@@ class TypeRevalorisation(AUFMetadata)
      
      class Meta:
          ordering = ['nom']
 -        verbose_name = "Type de revalorisation"
 -        verbose_name_plural = "Types de revalorisation"
 +        verbose_name = u"Type de revalorisation"
 +        verbose_name_plural = u"Types de revalorisation"
  
      def __unicode__(self):
          return u'%s' % (self.nom)
@@@ -788,8 -824,8 +824,8 @@@ class Service(AUFMetadata)
          
      class Meta:
          ordering = ['nom']
 -        verbose_name = "Service"
 -        verbose_name_plural = "Services"
 +        verbose_name = u"Service"
 +        verbose_name_plural = u"Services"
  
      def __unicode__(self):
          return u'%s' % (self.nom)
@@@ -815,8 -851,8 +851,8 @@@ class OrganismeBstg(AUFMetadata)
  
      class Meta:
          ordering = ['type', 'nom']
 -        verbose_name = "Organisme BSTG"
 -        verbose_name_plural = "Organismes BSTG"
 +        verbose_name = u"Organisme BSTG"
 +        verbose_name_plural = u"Organismes BSTG"
  
      def __unicode__(self):
          return u'%s (%s)' % (self.nom, self.get_type_display())
@@@ -830,8 -866,8 +866,8 @@@ class Statut(AUFMetadata)
  
      class Meta:
          ordering = ['code']
 -        verbose_name = "Statut d'employé"
 -        verbose_name_plural = "Statuts d'employé"
 +        verbose_name = u"Statut d'employé"
 +        verbose_name_plural = u"Statuts d'employé"
          
      def __unicode__(self):
          return u'%s : %s' % (self.code, self.nom)
@@@ -859,9 -895,9 +895,9 @@@ class Classement_(AUFMetadata)
      """
      # Identification
      type = models.CharField(max_length=10, choices=TYPE_CLASSEMENT_CHOICES)
 -    echelon = models.IntegerField(verbose_name="Échelon")
 -    degre = models.IntegerField(verbose_name="Degré")
 -    coefficient = models.FloatField(default=0, verbose_name="Coéfficient",
 +    echelon = models.IntegerField(verbose_name = u"Échelon")
 +    degre = models.IntegerField(verbose_name = u"Degré")
 +    coefficient = models.FloatField(default=0, verbose_name = u"Coéfficient",
                                      null=True)
      # Méta
      # annee # au lieu de date_debut et date_fin
      class Meta:
          abstract = True
          ordering = ['type','echelon','degre','coefficient']
 -        verbose_name = "Classement"
 -        verbose_name_plural = "Classements"
 +        verbose_name = u"Classement"
 +        verbose_name_plural = u"Classements"
  
      def __unicode__(self):
          return u'%s.%s.%s (%s)' % (self.type, self.echelon, self.degre,
@@@ -888,14 -924,14 +924,14 @@@ class TauxChange_(AUFMetadata)
      # Identification
      devise = models.ForeignKey('Devise', db_column='devise',
                              related_name='+')
 -    annee = models.IntegerField(verbose_name="Année")
 -    taux = models.FloatField(verbose_name="Taux vers l'euro")
 +    annee = models.IntegerField(verbose_name = u"Année")
 +    taux = models.FloatField(verbose_name = u"Taux vers l'euro")
  
      class Meta:
          abstract = True
          ordering = ['-annee', 'devise__code']
 -        verbose_name = "Taux de change"
 -        verbose_name_plural = "Taux de change"
 +        verbose_name = u"Taux de change"
 +        verbose_name_plural = u"Taux de change"
      
      def __unicode__(self):
          return u'%s : %s € (%s)' % (self.devise, self.taux, self.annee)
@@@ -931,8 -967,8 +967,8 @@@ class ValeurPoint_(AUFMetadata)
      class Meta:
          ordering = ['-annee', 'implantation__nom']
          abstract = True
 -        verbose_name = "Valeur du point"
 -        verbose_name_plural = "Valeurs du point"
 +        verbose_name = u"Valeur du point"
 +        verbose_name_plural = u"Valeurs du point"
  
      # TODO : cette fonction n'était pas présente dans la branche dev, utilité?
      def get_tauxchange_courant(self):
@@@ -963,8 -999,8 +999,8 @@@ class Devise(AUFMetadata)
  
      class Meta:
          ordering = ['code']
 -        verbose_name = "Devise"
 -        verbose_name_plural = "Devises"
 +        verbose_name = u"Devise"
 +        verbose_name_plural = u"Devises"
          
      def __unicode__(self):
          return u'%s - %s' % (self.code, self.nom)
@@@ -977,8 -1013,8 +1013,8 @@@ class TypeContrat(AUFMetadata)
  
      class Meta:
          ordering = ['nom']
 -        verbose_name = "Type de contrat"
 -        verbose_name_plural = "Types de contrat"
 +        verbose_name = u"Type de contrat"
 +        verbose_name_plural = u"Types de contrat"
  
      def __unicode__(self):
          return u'%s' % (self.nom)
@@@ -1002,5 -1038,5 +1038,5 @@@ class ResponsableImplantation(AUFMetada
          
      class Meta:
          ordering = ['implantation__nom']
 -        verbose_name = "Responsable d'implantation"
 -        verbose_name_plural = "Responsables d'implantation"
 +        verbose_name = u"Responsable d'implantation"
 +        verbose_name_plural = u"Responsables d'implantation"
diff --combined project/settings.py
@@@ -5,7 -5,7 +5,7 @@@ import socke
  from conf import *
  
  
- PROJET_TITRE = "SGRH"
+ PROJET_TITRE = "Ressources humaines"
  
  # Rapports d'erreurs
  EMAIL_SUBJECT_PREFIX = '[auf_rh_dae - %s] ' % socket.gethostname()
@@@ -61,7 -61,7 +61,8 @@@ INSTALLED_APPS = 
      'django.contrib.messages',
      'django.contrib.sessions',
      'django.contrib.admin',
 +    'django_qbe',
+     'auf.django.emploi',
      'auf.django.admingroup',
      'ajax_select',
      'south',
@@@ -87,8 -87,11 +88,11 @@@ TEMPLATE_CONTEXT_PROCESSORS = 
      'django.contrib.messages.context_processors.messages',
      'django.core.context_processors.request',
      'auf.django.skin.context_processors.auf',
-     'project.context_processors.utilisateur',
+     #'project.context_processors.utilisateur',
+     'project.context_processors.this_employe',
      'project.context_processors.user_is_admin',
+     'dae.context_processors.user_in_dae_groupes',
+     'recrutement.context_processors.user_in_recrutement_groupes',
  )
  
  AUTHENTICATION_BACKENDS = (
diff --combined project/urls.py
@@@ -2,6 -2,7 +2,7 @@@
  from django.conf.urls.defaults import patterns, include, handler500, url
  from django.conf import settings
  from django.contrib import admin
+ from auf.django.emploi import settings as sett
  
  admin.autodiscover()
  
@@@ -9,36 -10,28 +10,34 @@@ handler500 # Pyflake
  
  urlpatterns = patterns(
      '',
 +    (r'^$', 'project.views.index'),
-     url(r'^qbe/', include('django_qbe.urls')),
 +    #url(r'^private_files/', include('private_files.urls')),
 +    url(r'^captcha/', include('captcha.urls')),
 +    url(r'^admin_tools/', include('admin_tools.urls')),
++
+     # système
+     url(r'^$', 'project.views.accueil', name='accueil'),
      (r'^admin/', include(admin.site.urls)),
+     url(r'^api/(?P<method>[a-z_-]+)/$', 'recrutement.api.api', 
+             name='recrutement_api'),
      (r'^connexion/$', 'django.contrib.auth.views.login'),
      (r'^deconnexion/$', 'django.contrib.auth.views.logout'),
-     (r'^dae/', include('project.dae.urls')),
-     (r'^recrutement/', include('project.recrutement.urls')),
-     url(r'^recrutement/affecter_evaluateurs_candidats/$', 
-         'recrutement.views.affecter_evaluateurs_candidats', 
-         name='affecter_evaluateurs_candidats'),
-     url(r'^recrutement/affecter_evaluateurs_offre_emploi/$', 
-         'recrutement.views.affecter_evaluateurs_offre_emploi', 
-         name='affecter_evaluateurs_offre_emploi'),
-     url(r'^recrutement/envoyer_courriel_candidats/$', 
-         'recrutement.views.envoyer_courriel_candidats', 
-         name='envoyer_courriel_candidats'),
-     url(r'^recrutement/selectionner_template/$', 
-         'recrutement.views.selectionner_template', 
-         name='selectionner_template'),
-     url(r'^recrutement/pieces/$', 'recrutement.views.postuler_appel_offre', 
-         name='pieces'),
-     url(r'^recrutement/postuler_appel_offre/$', 
-         'recrutement.views.postuler_appel_offre', name='postuler_appel_offre'),
-     (r'^tinymce/', include('tinymce.urls')),    
-     (r'^', include('project.rh.urls')),
+     #url(r'^private_files/', include('private_files.urls')),
+     url(r'^captcha/', include('captcha.urls')),
+     url(r'^admin_tools/', include('admin_tools.urls')),
+     (r'^tinymce/', include('tinymce.urls')),
      (r'^prive/(?P<path>.*)$', 'django.views.static.serve', 
          {'document_root': settings.PRIVE_MEDIA_ROOT}),
+     url(r'^404$', 'project.views.erreur404', name='404'),
+     url(r'^500$', 'project.views.erreur500', name='500'),
+     url(r'^550$', 'project.views.erreur550', name='550'),
+     # apps
+     (r'^dae/', include('project.dae.urls')),
+     (r'^recrutement/', include('recrutement.urls')),
+     (r'^', include('project.rh.urls')),
++    url(r'^qbe/', include('django_qbe.urls')),
  )
  
  if settings.DEBUG: