merge rh et dev
authorOlivier Larchevêque <olivier.larcheveque@auf.org>
Fri, 6 May 2011 19:49:55 +0000 (15:49 -0400)
committerOlivier Larchevêque <olivier.larcheveque@auf.org>
Fri, 6 May 2011 19:49:55 +0000 (15:49 -0400)
project/dae/models.py
project/rh/admin.py [new file with mode: 0644]
project/rh/models.py
project/rh_v1/models.py
project/settings.py

index 71a2862..5752fe5 100644 (file)
@@ -10,23 +10,16 @@ from managers import DossierManager, PosteManager
 import datamaster_modeles.models as ref
 from rh_v1 import models as rh
 
-STATUT_RESIDENCE_CHOICES = (
-    ('local', 'Local'),
-    ('expat', 'Expatrié'),
-)
 
-POSTE_APPEL_CHOICES = (
-    ('interne', 'Interne'),
-    ('externe', 'Externe'),
-)
+# Constantes
+HELP_TEXT_DATE = "format: aaaa-mm-jj"
+REGIME_TRAVAIL_DEFAULT=100.00
+REGIME_TRAVAIL_NB_HEURE_SEMAINE_DEFAULT=35.00
 
-POSTE_STATUT_CHOICES = (
-    ('MAD', 'Mise à disposition'),
-    ('DET', 'Détachement'),
-)
 
 # Upload de fichiers
-storage_prive = FileSystemStorage(settings.PRIVE_MEDIA_ROOT, base_url=settings.PRIVE_MEDIA_URL)
+storage_prive = FileSystemStorage(settings.PRIVE_MEDIA_ROOT, 
+                            base_url=settings.PRIVE_MEDIA_URL)
 
 def poste_piece_dispatch(instance, filename):
     path = "poste/%s/%s" % (instance.poste_id, filename)
@@ -37,55 +30,55 @@ def dossier_piece_dispatch(instance, filename):
     return path
 
 
-class PostePiece(models.Model):
-    poste = models.ForeignKey("Poste")
-    nom = models.CharField(verbose_name="Nom", max_length=255)
-    fichier = models.FileField(verbose_name="Fichier", upload_to=poste_piece_dispatch, storage=storage_prive)
+### POSTE
+
+POSTE_APPEL_CHOICES = (
+    ('interne', 'Interne'),
+    ('externe', 'Externe'),
+)
 
 
 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")
+                            editable=False,
+                            verbose_name="Mise à jour du poste")
     nom = models.CharField(verbose_name="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")
+                            verbose_name=u"Direction/Service/Pôle support")
     responsable = models.ForeignKey(rh.Poste, related_name='+',
-                                verbose_name="Poste du responsable")
+                            verbose_name="Poste du responsable")
 
+    # Contrat
     regime_travail = models.DecimalField(max_digits=12, decimal_places=2,
-                                default=100, 
-                                verbose_name="Temps de travail", 
-                                help_text="% du temps complet")
+                            default=REGIME_TRAVAIL_DEFAULT, 
+                            verbose_name="Temps de travail", 
+                            help_text="% du temps complet")
     regime_travail_nb_heure_semaine = models.DecimalField(max_digits=12,
-                                decimal_places=2,
-                                default=35,
-                                verbose_name="Nb. heures par semaine")
+                            decimal_places=2,
+                            default=REGIME_TRAVAIL_NB_HEURE_SEMAINE_DEFAULT,
+                            verbose_name="Nb. heures par semaine")
 
     # Recrutement
     local = models.BooleanField(verbose_name="Local", default=True, blank=True)
-    expatrie = models.BooleanField(verbose_name="Expatrié", default=False, blank=True)
-
-    # TODO null?
+    expatrie = models.BooleanField(verbose_name="Expatrié", default=False, 
+                            blank=True)
     mise_a_disposition = models.BooleanField(verbose_name="Mise à disposition")
     appel = models.CharField(max_length=10, default='interne',
-                             verbose_name="Appel à candidature",
-                             choices=POSTE_APPEL_CHOICES)
+                            verbose_name="Appel à candidature",
+                            choices=POSTE_APPEL_CHOICES)
 
     # Rémunération
-    classement_min = models.ForeignKey(rh.Classement, related_name='+')
-    classement_max = models.ForeignKey(rh.Classement, related_name='+')
-
-    # En fait, les coefficient n'ont pas de valeur dans ces cas, les couts sont calculés
-    # et mis dans les coûts globals
-    #coefficient_min = models.FloatField(null=True) # pour classement "hors grille"
-    #coefficient_max = models.FloatField(null=True) # pour classement "hors grille"
-
-    valeur_point_min = models.ForeignKey(rh.ValeurPoint, related_name='+', blank=True, null=True)
-    valeur_point_max = models.ForeignKey(rh.ValeurPoint, related_name='+', blank=True, null=True)
+    classement_min = models.ForeignKey(rh.Classement, related_name='+',
+                            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='+', 
+                            blank=True, null=True)
+    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='+')
     salaire_min = models.DecimalField(max_digits=12, decimal_places=2,
@@ -132,10 +125,10 @@ class Poste(PosteWorkflow, models.Model):
     date_creation = models.DateTimeField(auto_now_add=True)
     date_modification = models.DateTimeField(auto_now=True)
     date_debut = models.DateField(verbose_name="Date de début",
-                                    help_text="format: aaaa-mm-jj")
+                                    help_text=HELP_TEXT_DATE)
     date_fin = models.DateField(null=True, blank=True,
                                     verbose_name="Date de fin",
-                                    help_text="format: aaaa-mm-jj")
+                                    help_text=HELP_TEXT_DATE)
     actif = models.BooleanField(default=True)
 
     # Managers
@@ -143,8 +136,10 @@ class Poste(PosteWorkflow, models.Model):
 
     def _get_key(self):
         """
-        Les vues sont montées selon une clef spéciale pour identifier la provenance du poste.
-        Cette méthode fournit un moyen de reconstruire cette clef afin de générer les URLs.
+        Les vues sont montées selon une clef spéciale 
+        pour identifier la provenance du poste.
+        Cette méthode fournit un moyen de reconstruire cette clef 
+        afin de générer les URLs.
         """
         return "dae-%s" % self.id
     key = property(_get_key)
@@ -152,10 +147,12 @@ class Poste(PosteWorkflow, models.Model):
     def get_dossiers(self):
         """
         Liste tous les anciens dossiers liés à ce poste.
-        (Le nom de la relation sur le rh.Poste est mal choisi poste1 au lieu de dossier1)
+        (Le nom de la relation sur le rh.Poste est mal choisi 
+        poste1 au lieu de dossier1)
         Note1 : seulement le dosssier principal fait l'objet de la recherche.
-        Note2 : les dossiers sont retournés du plus récent au plus vieux. (Ce test est fait
-        en fonction du id, car les dates de création sont absentes de rh v1).
+        Note2 : les dossiers sont retournés du plus récent au plus vieux. 
+        (Ce test est fait en fonction du id, 
+        car les dates de création sont absentes de rh v1).
         """
         if self.id_rh is None:
             return []
@@ -164,7 +161,8 @@ class Poste(PosteWorkflow, models.Model):
             
     def get_complement_nom(self):
         """
-        Inspecte les modèles rh v1 pour trouver dans le dernier  dossier un complément de titre de poste.
+        Inspecte les modèles rh v1 pour trouver dans le dernier dossier 
+        un complément de titre de poste.
         """
         dossiers = self.get_dossiers()
         if len(dossiers) > 0:
@@ -184,9 +182,12 @@ class Poste(PosteWorkflow, models.Model):
             return None
 
     def get_default_devise(self):
-        """Récupère la devise par défaut en fonction de l'implantation (EUR autrement)"""
+        """Récupère la devise par défaut en fonction de l'implantation 
+        (EUR autrement)
+        """
         try:
-            implantation_devise = rh.TauxChange.objects.filter(implantation=self.implantation)[0].devise
+            implantation_devise = rh.TauxChange.objects \
+                            .filter(implantation=self.implantation)[0].devise
         except:
             implantation_devise = 5 # EUR
         return implantation_devise
@@ -282,7 +283,8 @@ class Poste(PosteWorkflow, models.Model):
 
     def __unicode__(self):
         """
-        Cette fonction est consommatrice SQL car elle cherche les dossiers qui ont été liés à celui-ci.
+        Cette fonction est consommatrice SQL car elle cherche les dossiers 
+        qui ont été liés à celui-ci.
         """
         complement_nom_poste = self.get_complement_nom()
         if complement_nom_poste is None:
@@ -312,7 +314,6 @@ POSTE_FINANCEMENT_CHOICES = (
     ('C', 'C - Autre')
 )
 
-
 class PosteFinancement(models.Model):
     poste = models.ForeignKey('Poste', related_name='financements')
     type = models.CharField(max_length=1, choices=POSTE_FINANCEMENT_CHOICES)
@@ -327,12 +328,26 @@ class PosteFinancement(models.Model):
     def __unicode__(self):
         return u"%s %s %s" % (self.get_type_display(), self.pourcentage, self.commentaire)
 
+
+class PostePiece(models.Model):
+    """Documents relatifs au Poste
+    Ex.: Description de poste
+    """
+    poste = models.ForeignKey("Poste")
+    nom = models.CharField(verbose_name="Nom", max_length=255)
+    fichier = models.FileField(verbose_name="Fichier", 
+                            upload_to=poste_piece_dispatch, 
+                            storage=storage_prive)
+
+### EMPLOYÉ/PERSONNE
+
+# TODO : migration pour m -> M, f -> F
+
 GENRE_CHOICES = (
     ('m', 'Homme'),
     ('f', 'Femme'),
 )
 
-
 class Employe(models.Model):
 
     # Modèle existant
@@ -340,12 +355,18 @@ class Employe(models.Model):
                             verbose_name='Employé')
     nom = models.CharField(max_length=255)
     prenom = models.CharField(max_length=255, verbose_name='Prénom')
-    genre = models.CharField(max_length=1, choices=GENRE_CHOICES,
-                             null=True, blank=True)
+    genre = models.CharField(max_length=1, choices=GENRE_CHOICES)
 
     def __unicode__(self):
-        return u'%s %s' % (self.prenom, self.nom)
+        return u'%s %s' % (self.prenom, self.nom.upper())
+
 
+### DOSSIER
+
+STATUT_RESIDENCE_CHOICES = (
+    ('local', 'Local'),
+    ('expat', 'Expatrié'),
+)
 
 COMPTE_COMPTA_CHOICES = (
     ('coda', 'CODA'),
@@ -353,12 +374,6 @@ COMPTE_COMPTA_CHOICES = (
     ('aucun', 'Aucun'),
 )
 
-class DossierPiece(models.Model):
-    dossier = models.ForeignKey("Dossier")
-    nom = models.CharField(verbose_name="Nom", max_length=255)
-    fichier = models.FileField(verbose_name="Fichier", upload_to=dossier_piece_dispatch, storage=storage_prive)
-
-
 class Dossier(DossierWorkflow, models.Model):
 
     # Modèle existant
@@ -405,21 +420,26 @@ class Dossier(DossierWorkflow, models.Model):
     # Recrutement
     remplacement = models.BooleanField()
     statut_residence = models.CharField(max_length=10, default='local', 
-                                        verbose_name="Statut",
-                                        choices=STATUT_RESIDENCE_CHOICES)
+                            verbose_name="Statut",
+                            choices=STATUT_RESIDENCE_CHOICES)
 
     # Rémunération
     classement = models.ForeignKey(rh.Classement, related_name='+',
-                                   verbose_name='Classement proposé')
+                            null=True, blank=True,
+                            verbose_name='Classement proposé')
     salaire = models.DecimalField(max_digits=12, decimal_places=2,
-                                  verbose_name='Salaire de base',
-                                  null=True, default=None)
+                            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, decimal_places=2,
-                                         verbose_name="Régime de travail",
-                                         help_text="% du temps complet")
+    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, verbose_name="Nb. heures par semaine")
+                            decimal_places=2, 
+                            default=REGIME_TRAVAIL_NB_HEURE_SEMAINE_DEFAULT,
+                            verbose_name="Nb. heures par semaine")
 
     # Contrat
     type_contrat = models.ForeignKey(rh.TypeContrat, related_name='+')
@@ -480,6 +500,17 @@ class Dossier(DossierWorkflow, models.Model):
 if not reversion.is_registered(Dossier):
     reversion.register(Dossier)
 
+class DossierPiece(models.Model):
+    """Documents relatifs au Dossier (à l'occupation de ce poste par employé).
+    Ex.: Lettre de motivation.
+    """
+    dossier = models.ForeignKey("Dossier")
+    nom = models.CharField(verbose_name="Nom", max_length=255)
+    fichier = models.FileField(verbose_name="Fichier", 
+                            upload_to=dossier_piece_dispatch, 
+                            storage=storage_prive)
+
+
 class DossierComparaison(models.Model):
     """
     Photo d'une comparaison salariale au moment de l'embauche.
@@ -492,31 +523,23 @@ class DossierComparaison(models.Model):
     devise = models.ForeignKey(rh.Devise, default=5, related_name='+', null=True, blank=True)
     montant_euros = models.IntegerField(null=True)
 
+
+### RÉMUNÉRATION
+
 class Remuneration(models.Model):
     # Identification
     dossier = models.ForeignKey('Dossier', db_column='dossier')
     type = models.ForeignKey(rh.TypeRemuneration, db_column='type',
                              related_name='+')
-    # TODO: what's that?
-    # type_revalorisation = models.ForeignKey('TypeRevalorisation',
-                                            # db_column='type_revalorisation')
     montant = models.DecimalField(max_digits=12, decimal_places=2,
                                   null=True)  # Annuel
     devise = models.ForeignKey(rh.Devise, to_field='code',
                                db_column='devise', related_name='+')
     precision = models.CharField(max_length=255, null=True, blank=True)
-    # date_effective = models.DateField(null=True, blank=True)
-    # pourcentage = models.IntegerField(null=True, blank=True)
 
     # Méta
     date_creation = models.DateField(auto_now_add=True)
-    user_creation = models.IntegerField(null=True, blank=True)
-    # desactivation = models.BooleanField(default=False, blank=True)
-    # date_desactivation = models.DateField(null=True, blank=True)
-    # user_desactivation = models.IntegerField(null=True, blank=True)
-    # annulation = models.BooleanField(default=False, blank=True)
-    # date_annulation = models.DateField(null=True, blank=True)
-    # user_annulation = models.IntegerField(null=True, blank=True)
+    user_creation = models.IntegerField(null=True, blank=True)  # TODO : user
 
     def montant_mois(self):
         return round(self.montant / 12, 2)
@@ -531,6 +554,8 @@ class Remuneration(models.Model):
         return round(self.montant_euro() / 12, 2)
 
 
+### JUSTIFICATIONS
+
 TYPE_JUSTIFICATIONS = (
     ('N', 'Nouvel employé'),
     ('R', 'Renouvellement employé'),
diff --git a/project/rh/admin.py b/project/rh/admin.py
new file mode 100644 (file)
index 0000000..405b00b
--- /dev/null
@@ -0,0 +1,122 @@
+# -*- encoding: utf-8 -*-
+
+from models import *
+from django.contrib import admin
+
+class CommentaireAdmin(admin.ModelAdmin):
+    pass
+
+class PosteAdmin(admin.ModelAdmin):
+    pass
+
+class PosteFinancementAdmin(admin.ModelAdmin):
+    pass
+
+class PostePieceAdmin(admin.ModelAdmin):
+    pass
+
+class PosteCommentaireAdmin(admin.ModelAdmin):
+    pass
+
+class EmployeAdmin(admin.ModelAdmin):
+    pass
+
+class EmployePieceAdmin(admin.ModelAdmin):
+    pass
+
+class EmployeCommentaireAdmin(admin.ModelAdmin):
+    pass
+
+class AyantDroitAdmin(admin.ModelAdmin):
+    pass
+
+class AyantDroitCommentaireAdmin(admin.ModelAdmin):
+    pass
+
+class DossierAdmin(admin.ModelAdmin):
+    pass
+
+class DossierPieceAdmin(admin.ModelAdmin):
+    pass
+
+class DossierCommentaireAdmin(admin.ModelAdmin):
+    pass
+
+class RemunerationAdmin(admin.ModelAdmin):
+    pass
+
+class ContratAdmin(admin.ModelAdmin):
+    pass
+
+class EvenementAdmin(admin.ModelAdmin):
+    pass
+
+class EvenementRemunerationAdmin(admin.ModelAdmin):
+    pass
+
+class FamilleEmploiAdmin(admin.ModelAdmin):
+    pass
+
+class TypePosteAdmin(admin.ModelAdmin):
+    pass
+
+class TypeRemunerationAdmin(admin.ModelAdmin):
+    pass
+
+class TypeRevalorisationAdmin(admin.ModelAdmin):
+    pass
+
+class ServiceAdmin(admin.ModelAdmin):
+    pass
+
+class OrganismeBstgAdmin(admin.ModelAdmin):
+    pass
+
+class StatutAdmin(admin.ModelAdmin):
+    pass
+
+class ClassementAdmin(admin.ModelAdmin):
+    pass
+
+class TauxChangeAdmin(admin.ModelAdmin):
+    pass
+
+class ValeurPointAdmin(admin.ModelAdmin):
+    pass
+
+class DeviseAdmin(admin.ModelAdmin):
+    pass
+
+class TypeContratAdmin(admin.ModelAdmin):
+    pass
+
+
+admin.site.register(Commentaire, CommentaireAdmin)
+admin.site.register(Poste, PosteAdmin)
+admin.site.register(PosteFinancement, PosteFinancementAdmin)
+admin.site.register(PostePiece, PostePieceAdmin)
+admin.site.register(PosteCommentaire, PosteCommentaireAdmin)
+admin.site.register(Employe, EmployeAdmin)
+admin.site.register(EmployePiece, EmployePieceAdmin)
+admin.site.register(EmployeCommentaire, EmployeCommentaireAdmin)
+admin.site.register(AyantDroit, AyantDroitAdmin)
+admin.site.register(AyantDroitCommentaire, AyantDroitCommentaireAdmin)
+admin.site.register(Dossier, DossierAdmin)
+admin.site.register(DossierPiece, DossierPieceAdmin)
+admin.site.register(DossierCommentaire, DossierCommentaireAdmin)
+admin.site.register(Remuneration, RemunerationAdmin)
+admin.site.register(Contrat, ContratAdmin)
+admin.site.register(Evenement, EvenementAdmin)
+admin.site.register(EvenementRemuneration, EvenementRemunerationAdmin)
+admin.site.register(FamilleEmploi, FamilleEmploiAdmin)
+admin.site.register(TypePoste, TypePosteAdmin)
+admin.site.register(TypeRemuneration, TypeRemunerationAdmin)
+admin.site.register(TypeRevalorisation, TypeRevalorisationAdmin)
+admin.site.register(Service, ServiceAdmin)
+admin.site.register(OrganismeBstg, OrganismeBstgAdmin)
+admin.site.register(Statut, StatutAdmin)
+admin.site.register(Classement, ClassementAdmin)
+admin.site.register(TauxChange, TauxChangeAdmin)
+admin.site.register(ValeurPoint, ValeurPointAdmin)
+admin.site.register(Devise, DeviseAdmin)
+admin.site.register(TypeContrat, TypeContratAdmin)
index 4e2b51e..e6240e1 100644 (file)
@@ -1,7 +1,244 @@
 # -=- encoding: utf-8 -=-
 
+import datetime
+
+from django.core.files.storage import FileSystemStorage
 from django.db import models
-from datamaster_modeles.models import Pays, Implantation
+import settings
+
+import datamaster_modeles.models as ref
+
+
+# Constantes
+HELP_TEXT_DATE = u"format: aaaa-mm-jj"
+REGIME_TRAVAIL_DEFAULT = 100.00
+REGIME_TRAVAIL_NB_HEURE_SEMAINE_DEFAULT = 35.00
+
+
+# Upload de fichiers
+storage_prive = FileSystemStorage(settings.PRIVE_MEDIA_ROOT, 
+                            base_url=settings.PRIVE_MEDIA_URL)
+
+def poste_piece_dispatch(instance, filename):
+    path = "poste/%s/%s" % (instance.poste_id, filename)
+    return path
+
+def dossier_piece_dispatch(instance, filename):
+    path = "dossier/%s/%s" % (instance.dossier_id, filename)
+    return path
+
+# Abstracts
+class Metadata(models.Model):
+    """Méta-données AUF.
+    Metadata.actif = flag remplaçant la suppression.
+    actif == False : objet réputé supprimé.
+    """
+    actif = models.BooleanField(default=True)
+    date_creation = models.DateField(auto_now_add=True)
+    user_creation = models.ForeignKey('auth.User', 
+                            db_column='user_creation', related_name='+',
+                            null=True, blank=True)
+    date_modification = models.DateField(auto_now=True)
+    user_modification = models.ForeignKey('auth.User', 
+                            db_column='user_modification', related_name='+',
+                            null=True, blank=True)
+    date_desactivation = models.DateField(null=True, blank=True)
+    user_desactivation = models.ForeignKey('auth.User', 
+                            db_column='user_desactivation', related_name='+',
+                            null=True, blank=True)
+    
+    class Meta:
+        abstract = True
+
+class Commentaire(Metadata):
+    texte = models.TextField()
+    owner = models.ForeignKey('auth.User', db_column='owner', related_name='+')
+    
+    class Meta:
+        abstract = True
+        ordering = ['-date_creation']
+        
+    def __unicode__(self):
+        return u'%s' % (self.texte)
+
+
+### POSTE
+
+POSTE_APPEL_CHOICES = (
+    ('interne', 'Interne'),
+    ('externe', 'Externe'),
+)
+
+class Poste(Metadata):
+    """Un Poste est un emploi (job) à combler dans une implantation. 
+    Un Poste peut être comblé par un Employe, auquel cas un Dossier est créé.
+    Si on veut recruter 2 jardiniers, 2 Postes distincts existent.
+    """
+    # Identification
+    nom = models.CharField(max_length=255, 
+                            verbose_name=u"Titre du poste", )
+    nom_feminin = models.CharField(max_length=255,
+                            verbose_name=u"Titre du poste (au féminin)",
+                            null=True)
+    implantation = models.ForeignKey(ref.Implantation, 
+                            db_column='implantation', related_name='+')
+    type_poste = models.ForeignKey('TypePoste', db_column='type_poste',
+                            related_name='+',
+                            null=True)
+    service = models.ForeignKey('Service', db_column='service', 
+                            related_name='+',
+                            verbose_name=u"Direction/Service/Pôle support",
+                            default=1)  # default = Rectorat
+    responsable = models.ForeignKey('Poste', db_column='responsable', 
+                            related_name='+',
+                            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, 
+                            verbose_name=u"Temps de travail", 
+                            help_text=u"% 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=u"Nb. heures par semaine")
+
+    # Recrutement
+    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=u"Mise à disposition",
+                            default=False)
+    appel = models.CharField(max_length=10, 
+                            verbose_name=u"Appel à candidature",
+                            choices=POSTE_APPEL_CHOICES,
+                            default='interne')
+
+    # Rémunération
+    classement_min = models.ForeignKey('Classement', 
+                            db_column='classement_min', related_name='+',
+                            null=True, blank=True)
+    classement_max = models.ForeignKey('Classement', 
+                            db_column='classement_max', related_name='+',
+                            null=True, blank=True)
+    valeur_point_min = models.ForeignKey('ValeurPoint', 
+                            db_column='valeur_point_min', related_name='+', 
+                            null=True, blank=True)
+    valeur_point_max = models.ForeignKey('ValeurPoint', 
+                            db_column='valeur_point_max', related_name='+', 
+                            null=True, blank=True)
+    devise_min = models.ForeignKey('Devise', db_column='devise_min', 
+                            related_name='+', default=5)
+    devise_max = models.ForeignKey('Devise', db_column='devise_max', 
+                            related_name='+', default=5)
+    salaire_min = models.DecimalField(max_digits=12, decimal_places=2,
+                            default=0)
+    salaire_max = models.DecimalField(max_digits=12, decimal_places=2,
+                            default=0)
+    indemn_min = models.DecimalField(max_digits=12, decimal_places=2,
+                            default=0)
+    indemn_max = models.DecimalField(max_digits=12, decimal_places=2,
+                            default=0)
+    autre_min = models.DecimalField(max_digits=12, decimal_places=2,
+                            default=0)
+    autre_max = models.DecimalField(max_digits=12, decimal_places=2,
+                            default=0)
+
+    # Comparatifs de rémunération
+    devise_comparaison = models.ForeignKey('Devise', 
+                            db_column='devise_comparaison', 
+                            related_name='+',
+                            default=5)
+    comp_locale_min = models.DecimalField(max_digits=12, decimal_places=2,
+                            null=True, blank=True)
+    comp_locale_max = models.DecimalField(max_digits=12, decimal_places=2,
+                            null=True, blank=True)
+    comp_universite_min = models.DecimalField(max_digits=12, decimal_places=2,
+                            null=True, blank=True)
+    comp_universite_max = models.DecimalField(max_digits=12, decimal_places=2,
+                            null=True, blank=True)
+    comp_fonctionpub_min = models.DecimalField(max_digits=12, decimal_places=2,
+                            null=True, blank=True)
+    comp_fonctionpub_max = models.DecimalField(max_digits=12, decimal_places=2,
+                            null=True, blank=True)
+    comp_ong_min = models.DecimalField(max_digits=12, decimal_places=2,
+                            null=True, blank=True)
+    comp_ong_max = models.DecimalField(max_digits=12, decimal_places=2,
+                            null=True, blank=True)
+    comp_autre_min = models.DecimalField(max_digits=12, decimal_places=2,
+                            null=True, blank=True)
+    comp_autre_max = models.DecimalField(max_digits=12, decimal_places=2,
+                            null=True, blank=True)
+
+    # Justification
+    justification = models.TextField(null=True, blank=True)
+
+    # Autres Metadata
+    date_validation = models.DateTimeField(null=True, blank=True)   # de dae
+    date_debut = models.DateField(verbose_name=u"Date de début",
+                            help_text=HELP_TEXT_DATE)
+    date_fin = models.DateField(verbose_name=u"Date de fin",
+                            help_text=HELP_TEXT_DATE,
+                            null=True, blank=True)
+
+    class Meta:
+        ordering = ['implantation__nom', 'nom']
+
+    def __unicode__(self):
+        # TODO : gérer si poste est vacant ou non dans affichage
+        # TODO : gérer le nom_feminin (autre méthode appelée par __unicode__ ?)
+        return u'%s - %s [%s]' % (self.implantation, self.nom, self.id)
+
+
+POSTE_FINANCEMENT_CHOICES = (
+    ('A', 'A - Frais de personnel'),
+    ('B', 'B - Projet(s)-Titre(s)'),
+    ('C', 'C - Autre')
+)
+
+class PosteFinancement(models.Model):
+    """Pour un Poste, structure d'informations décrivant comment on prévoit
+    financer ce Poste.
+    """
+    poste = models.ForeignKey('Poste', db_column='poste', 
+                            related_name='financements')
+    type = models.CharField(max_length=1, choices=POSTE_FINANCEMENT_CHOICES)
+    pourcentage = models.DecimalField(max_digits=12, decimal_places=2,
+            help_text=u"ex.: 33.33 % (décimale avec point)")
+    commentaire = models.TextField(
+            help_text=u"Spécifiez la source de financement.")
+
+    class Meta:
+        ordering = ['type']
+        
+    def __unicode__(self):
+        return u'%s : %s %' % (self.type, self.pourcentage)
+
+class PostePiece(models.Model):
+    """Documents relatifs au Poste.
+    Ex.: Description de poste
+    """
+    poste = models.ForeignKey("Poste", db_column='poste', 
+                            related_name='pieces')
+    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 Meta:
+        ordering = ['nom']
+        
+    def __unicode__(self):
+        return u'%s' % (self.nom)
+
+class PosteCommentaire(Commentaire):
+    poste = models.ForeignKey("Poste", db_column='poste', related_name='+')
+
+
+### EMPLOYÉ/PERSONNE
 
 GENRE_CHOICES = (
     ('M', 'Homme'),
@@ -13,71 +250,74 @@ SITUATION_CHOICES = (
     ('M', 'Marié'),
 )
 
-class Employe(models.Model):   
-    #Identification
-    id = models.IntegerField(primary_key=True)
+class Employe(Metadata):
+    """Personne occupant ou ayant occupé un Poste. Un Employe aura autant de 
+    Dossiers qu'il occupe ou a occupé de Postes.
+    
+    Cette classe aurait pu avantageusement s'appeler Personne car la notion 
+    d'employé n'a pas de sens si aucun Dossier n'existe pour une personne.
+    """
+    # Identification
     nom = models.CharField(max_length=255)
-    prenom = models.CharField(max_length=255)
-    nationalite = models.ForeignKey('datamaster_modeles.Pays', to_field='code', related_name='employes_nationalite', db_column='nationalite')
-    date_naissance = models.DateField(null=True, blank=True)
-    #Infos personnelles
-    genre = models.CharField(max_length=1, choices=GENRE_CHOICES, null=True, blank=True)
-    situation_famille = models.CharField(max_length=1, choices=SITUATION_CHOICES, null=True, blank=True)
-    date_entree = models.DateField(null=True, blank=True) #devrait pas être là
-    #Coordonnées
+    prenom = models.CharField(max_length=255, verbose_name=u"Prénom")
+    # TODO : nom_affichage doit être obligatoire, pas nom et prenom
+    nom_affichage = models.CharField(max_length=255, 
+                            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')
+    date_naissance = models.DateField(help_text=HELP_TEXT_DATE,
+                            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,
+                            null=True, blank=True)
+    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, null=True, blank=True)
     tel_cellulaire = models.CharField(max_length=255, null=True, blank=True)
     adresse = models.CharField(max_length=255, null=True, blank=True)
-    no_rue = models.CharField(max_length=255, null=True, blank=True)
     ville = models.CharField(max_length=255, null=True, blank=True)
     province = models.CharField(max_length=255, null=True, blank=True)
     code_postal = models.CharField(max_length=255, null=True, blank=True)
-    pays = models.ForeignKey('datamaster_modeles.Pays', to_field='code', null=True, blank=True, related_name='employes', db_column='pays')
-    #Métas
-    date_creation = models.DateField(auto_now_add=True)
-    date_maj = models.DateField(auto_now=True)
-    commentaire = models.TextField(null=True, blank=True)
-    
-TYPE_DOSSIER_CHOICES = (
-    ('2', 'Local'),
-    ('1', 'Expatrié'),
-)
+    pays = models.ForeignKey(ref.Pays, to_field='code', db_column='pays',
+                            related_name='employes', 
+                            null=True, blank=True)
+
+    class Meta:
+        ordering = ['nom_affichage']
+        
+    def __unicode__(self):
+        # TODO : gérer nom d'affichage
+        return u'%s' % (self.nom_affichage)
+
+class EmployePiece(models.Model):
+    """Documents relatifs à un employé.
+    Ex.: CV...
+    """
+    employe = models.ForeignKey("Employe", db_column='employe', 
+                            related_name='+')
+    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)
+
+    class Meta:
+        ordering = ['nom']
+        
+    def __unicode__(self):
+        return u'%s' % (self.nom)
+
+class EmployeCommentaire(Commentaire):
+    employe = models.ForeignKey("Employe", db_column='employe',
+                            related_name='+')
 
-class Dossier(models.Model):
-    #Identification
-    id = models.IntegerField(primary_key=True)
-    code = models.CharField(max_length=10, unique=True)
-    employe = models.ForeignKey('Employe', db_column='employe')
-    #Postes
-    poste1 = models.ForeignKey('Poste', db_column='poste1', related_name='dossiers_poste1')
-    implantation1 = models.ForeignKey('datamaster_modeles.Implantation', db_column='implantation1', related_name='dossiers_implantation1')
-    complement1 = models.TextField(null=True, blank=True)
-    responsable_implantation1 = models.IntegerField()
-    poste2 = models.ForeignKey('Poste', db_column='poste2', related_name='dossiers_poste2', blank=True, null=True)
-    implantation2 = models.ForeignKey('datamaster_modeles.Implantation', db_column='implantation2', related_name='dossiers_implantation2')
-    complement2 = models.TextField(null=True, blank=True)
-    responsable_implantation2 = models.IntegerField() 
-    #Relations
-    service = models.ForeignKey('Service', db_column='service')
-    responsable = models.ForeignKey('Employe', db_column='responsable', related_name='responsable_de')
-    remplacement_de = models.ForeignKey('Employe', db_column='remplacement_de', related_name='replaced_by')
-    type = models.CharField(max_length=1, choices=TYPE_DOSSIER_CHOICES)
-    statut = models.ForeignKey('Statut', db_column='statut')
-    organisme_bstg = models.ForeignKey('OrganismeBstg', db_column='organisme_bstg')
-    #Rémunération
-    classement = models.ForeignKey('Classement', db_column='classement')
-    regime_travail = models.IntegerField()
-    #Mandat
-    mandat_date_debut = models.DateField()
-    mandat_date_fin = models.DateField()
-    #Contrat
-    contrat_date_debut = models.DateField()
-    contrat_date_fin = models.DateField()
-    type_contrat = models.ForeignKey('TypeContrat', db_column='type_contrat')
-    #Meta
-    date_creation = models.DateField(auto_now_add=True)
-    date_maj = models.DateField(auto_now=True)
-    commentaire = models.TextField(null=True, blank=True) 
 
 LIEN_PARENTE_CHOICES = (
     ('Conjoint', 'Conjoint'),
@@ -86,60 +326,283 @@ LIEN_PARENTE_CHOICES = (
     ('Fils', 'Fils'),
 )
 
-class AyantDroit(models.Model):
-    #Identification
-    id = models.IntegerField(primary_key=True)
+class AyantDroit(Metadata):
+    """Personne en relation avec un Employe.
+    """
+    # Identification
     nom = models.CharField(max_length=255)
     prenom = models.CharField(max_length=255)
-    #Relation
-    employe = models.ForeignKey('Employe', db_column='employe', related_name='ayants_droit')
-    lien_parente = models.CharField(max_length=10, choices=LIEN_PARENTE_CHOICES, null=True, blank=True)
-    #Méta
-    commentaire = models.TextField(null=True, blank=True) 
-    actif = models.BooleanField()
+    # TODO : nom_affichage doit être obligatoire, pas nom et prenom
+    nom_affichage = models.CharField(max_length=255, 
+                            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')
+    date_naissance = models.DateField(help_text=HELP_TEXT_DATE,
+                            null=True, blank=True)
+    genre = models.CharField(max_length=1, choices=GENRE_CHOICES)
+    
+    # Relation
+    employe = models.ForeignKey('Employe', db_column='employe', 
+                            related_name='ayantdroits')
+    lien_parente = models.CharField(max_length=10, 
+                            choices=LIEN_PARENTE_CHOICES,
+                            null=True, blank=True)
+
+    class Meta:
+        ordering = ['nom_affichage']
+    def __unicode__(self):
+        # TODO : gérer nom d'affichage
+        return u'%s %s' % (self.prenom, self.nom.upper())
+
+class AyantDroitCommentaire(Commentaire):
+    ayant_droit = models.ForeignKey("AyantDroit", db_column='ayant_droit',
+                            related_name='+')
+
+
+### DOSSIER
+
+STATUT_RESIDENCE_CHOICES = (
+    ('local', 'Local'),
+    ('expat', 'Expatrié'),
+)
+
+COMPTE_COMPTA_CHOICES = (
+    ('coda', 'CODA'),
+    ('scs', 'SCS'),
+    ('aucun', 'Aucun'),
+)
+
+class Dossier(Metadata):
+    """Le Dossier regroupe les informations relatives à l'occupation
+    d'un Poste par un Employe. Un seul Dossier existe par Poste occupé
+    par un Employe.
+    
+    Plusieurs Contrats peuvent être associés au Dossier.
+    Une structure de Remuneration est rattachée au Dossier. Un Poste pour
+    lequel aucun Dossier n'existe est un poste vacant.
+    """
+    # Identification
+    employe = models.ForeignKey('Employe', db_column='employe', 
+                            related_name='+')
+    poste = models.ForeignKey('Poste', db_column='poste', 
+                            related_name='+', editable=False)
+    statut = models.ForeignKey('Statut', related_name='+', default=3)
+    organisme_bstg = models.ForeignKey('OrganismeBstg', 
+                            db_column='organisme_bstg',
+                            related_name='+',
+                            verbose_name=u"Organisme", 
+                            help_text=u"Si détaché (DET) ou \
+                                    mis à disposition (MAD), \
+                                    préciser l'organisme.",
+                            null=True, blank=True)
+                          
+    # Recrutement
+    remplacement = models.BooleanField(default=False)
+    statut_residence = models.CharField(max_length=10, default='local', 
+                            verbose_name=u"Statut",
+                            choices=STATUT_RESIDENCE_CHOICES)
+   
+    # Rémunération
+    classement = models.ForeignKey('Classement', db_column='classement', 
+                            related_name='+',
+                            null=True, blank=True)
+    regime_travail = models.DecimalField(max_digits=12, 
+                            decimal_places=2,
+                            default=REGIME_TRAVAIL_DEFAULT,
+                            verbose_name=u"Régime de travail",
+                            help_text=u"% 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=u"Nb. heures par semaine")
+
+    # Occupation du Poste par cet Employe (anciennement "mandat")
+    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=u"Date de fin d'occupation \
+                            de poste",
+                            help_text=HELP_TEXT_DATE,
+                            null=True, blank=True)
     
+    # Comptes
+    # TODO?
+    
+    class Meta:
+        ordering = ['poste__nom', 'employe__nom_affichage']
+        
+    def __unicode__(self):
+        return u'%s - %s' % (self.poste.nom, self.employe)
+
+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=u"Nom", max_length=255)
+    fichier = models.FileField(verbose_name=u"Fichier", 
+                            upload_to=dossier_piece_dispatch, 
+                            storage=storage_prive)
+
+    class Meta:
+        ordering = ['nom']
+        
+    def __unicode__(self):
+        return u'%s' % (self.nom)
+
+class DossierCommentaire(Commentaire):
+    dossier = models.ForeignKey("Dossier", db_column='dossier', 
+                            related_name='+')
+
+
+### RÉMUNÉRATION
     
-class Remuneration(models.Model):
-    #Identification
-    id = models.IntegerField(primary_key=True)
+class RemunerationMixin(Metadata):
+    # Identification
     dossier = models.ForeignKey('Dossier', db_column='dossier')
-    type = models.ForeignKey('TypeRemuneration', db_column='type')
-    type_revalorisation = models.ForeignKey('TypeRevalorisation', db_column='type_revalorisation')
-    montant = models.FloatField()
-    devise = models.ForeignKey('Devise', to_field='code', db_column='devise')
-    date_effective = models.DateField()
-    pourcentage = models.IntegerField()
-    #Méta
-    date_creation = models.DateField(auto_now_add=True)
-    user_creation = models.IntegerField() #User ou employé
-    desactivation = models.BooleanField() #
-    date_desactivation = models.DateField()
-    user_desactivation = models.IntegerField() #User ou employé
-    annule = models.BooleanField()
-    date_annule = models.DateField()
-    user_annule = models.IntegerField() #User ou employé
+    type = models.ForeignKey('TypeRemuneration', db_column='type', 
+                            related_name='+')
+    type_revalorisation = models.ForeignKey('TypeRevalorisation', 
+                            db_column='type_revalorisation', 
+                            related_name='+',
+                            null=True, blank=True)
+    montant = models.FloatField(null=True, blank=True,
+                            default=0)
+                            # Annuel (12 mois, 52 semaines, 364 jours?)
+    devise = models.ForeignKey('Devise', to_field='id',
+                            db_column='devise', related_name='+',
+                            default=5)
+    # commentaire = precision
+    commentaire = models.CharField(max_length=255, null=True, blank=True)
+    # date_debut = anciennement date_effectif
+    date_debut = models.DateField(help_text=HELP_TEXT_DATE, 
+                            null=True, blank=True)
+    date_fin = models.DateField(help_text=HELP_TEXT_DATE,
+                            null=True, blank=True)
     
-class FamilleEmploi(models.Model):
-    #Identification
-    id = models.IntegerField(primary_key=True)
+    class Meta: 
+        abstract = True
+        ordering = ['type__nom', '-date_fin']
+        
+    def __unicode__(self):
+        return u'%s %s (%s)' % (self.montant, self.devise.code, self.type.nom)
+    
+class Remuneration(RemunerationMixin):
+    """Structure de rémunération (données budgétaires) en situation normale
+    pour un Dossier. Si un Evenement existe, utiliser la structure de 
+    rémunération EvenementRemuneration de cet événement.    
+    """
+
+    def montant_mois(self):
+        return round(self.montant / 12, 2)
+
+    def taux_devise(self):
+        return self.devise.tauxchange_set.order_by('-annee').all()[0].taux
+
+    def montant_euro(self):
+        return round(float(self.montant) / float(self.taux_devise()), 2)
+
+    def montant_euro_mois(self):
+        return round(self.montant_euro() / 12, 2)
+    
+    def __unicode__(self):
+        try:
+            devise = self.devise.code
+        except:
+            devise = "???"
+        return "%s %s" % (self.montant, devise)
+
+
+### CONTRATS
+        
+class Contrat(Metadata):
+    """Document juridique qui encadre la relation de travail d'un Employe
+    pour un Poste particulier. Pour un Dossier (qui documente cette 
+    relation de travail) plusieurs contrats peuvent être associés.
+    """
+    dossier = models.ForeignKey('Dossier', db_column='dossier', 
+                            related_name='+')
+    type_contrat = models.ForeignKey('TypeContrat', db_column='type_contrat', 
+                            related_name='+')
+    date_debut = models.DateField(help_text=HELP_TEXT_DATE)
+    date_fin = models.DateField(help_text=HELP_TEXT_DATE,
+                            null=True, blank=True)
+
+    class Meta:
+        ordering = ['dossier__employe__nom_affichage']
+        
+    def __unicode__(self):
+        return u'%s - %s' % (self.dossier.employe.nom_affichage, self.id)
+        
+# TODO? class ContratPiece(models.Model):
+    
+
+### ÉVÉNEMENTS
+
+class Evenement(Metadata):
+    """Un Evenement sert à déclarer une situation temporaire (exceptionnelle) 
+    d'un Dossier qui vient altérer des informations normales liées à un Dossier 
+    (ex.: la Remuneration).
+    
+    Ex.: congé de maternité, maladie...
+    
+    Lors de ces situations exceptionnelles, l'Employe a un régime de travail
+    différent et une rémunération en conséquence. On souhaite toutefois
+    conserver le Dossier intact afin d'éviter une re-saisie des données lors
+    du retour à la normale.
+    """
+    dossier = models.ForeignKey("Dossier", db_column='dossier', 
+                            related_name='+')
+    nom = models.CharField(max_length=255)
+    date_debut = models.DateField(help_text=HELP_TEXT_DATE)
+    date_fin = models.DateField(help_text=HELP_TEXT_DATE, 
+                            null=True, blank=True)
+    class Meta:
+        ordering = ['nom']
+                            
+    def __unicode__(self):
+        return u'%s' % (self.nom)
+    
+class EvenementRemuneration(RemunerationMixin):
+    """Structure de rémunération liée à un Evenement qui remplace 
+    temporairement la Remuneration normale d'un Dossier, pour toute la durée
+    de l'Evenement.
+    """
+    evenement = models.ForeignKey("Evenement", db_column='evenement',
+                            related_name='+')
+
+
+### RÉFÉRENCES RH 
+
+class FamilleEmploi(Metadata):
+    """Catégorie utilisée dans la gestion des Postes.
+    Catégorie supérieure à TypePoste.
+    """
     nom = models.CharField(max_length=255)
-    #Méta
-    actif = models.BooleanField()
+    
+    def __unicode__(self):
+        return u'%s' % (self.nom)
 
-class TypePoste(models.Model):
-    #Identification
-    id = models.IntegerField(primary_key=True)
+class TypePoste(Metadata):
+    """Catégorie de Poste.
+    """
     nom = models.CharField(max_length=255)
     nom_feminin = models.CharField(max_length=255)
-    description = models.CharField(max_length=255)
-    is_responsable = models.BooleanField()
-    famille_emploi = models.ForeignKey('FamilleEmploi', db_column='famille_emploi')
-    #Méta
-    date_modification = models.DateField(auto_now=True)
-    actif = models.BooleanField()
+    
+    is_responsable = models.BooleanField(default=False)
+    famille_emploi = models.ForeignKey('FamilleEmploi', 
+                            db_column='famille_emploi',
+                            related_name='+')
 
+    class Meta:
+        ordering = ['nom']
+        
     def __unicode__(self):
-        return u'%s' % self.nom
+        # TODO : gérer nom féminin
+        return u'%s' % (self.nom)
 
 
 TYPE_PAIEMENT_CHOICES = (
@@ -151,56 +614,41 @@ NATURE_REMUNERATION_CHOICES = (
     ('Accessoire', 'Accessoire'),
     ('Charges', 'Charges'),
     ('Indemnité', 'Indemnité'),
-    ('RAS', 'RAS'),
+    ('RAS', 'Rémunération autre source'),
     ('Traitement', 'Traitement'),
 )
 
-class TypeRemuneration(models.Model):
-    #Identification
-    id = models.IntegerField(primary_key=True)
+class TypeRemuneration(Metadata):
+    """Catégorie de Remuneration.
+    """
     nom = models.CharField(max_length=255)
-    type_paiement = models.CharField(max_length=30, choices=TYPE_PAIEMENT_CHOICES)
-    nature_remuneration = models.CharField(max_length=30, choices=NATURE_REMUNERATION_CHOICES)
-    #Méta
-    actif = models.BooleanField()
+    type_paiement = models.CharField(max_length=30, 
+                            choices=TYPE_PAIEMENT_CHOICES)
+    nature_remuneration = models.CharField(max_length=30, 
+                            choices=NATURE_REMUNERATION_CHOICES)
+
+    def __unicode__(self):
+        return u'%s' % (self.nom)
         
-class TypeRevalorisation(models.Model):
-    #Identification
-    id = models.IntegerField(primary_key=True)
+class TypeRevalorisation(Metadata):
+    """Justification du changement de la Remuneration.
+    (Actuellement utilisé dans aucun traitement informatique.)
+    """
     nom = models.CharField(max_length=255)
-    #Méta
-    actif = models.BooleanField()
-    
-PROPORTION_CHOICES = (
-    ('0.5', '0.5'),
-    ('1', '1'),
-)
-
-class Poste(models.Model):
-    #Identification
-    id = models.IntegerField(primary_key=True)
-    implantation = models.ForeignKey('datamaster_modeles.Implantation',
-            db_column='implantation', related_name='postes')
-    type_poste = models.ForeignKey('TypePoste', db_column='type_poste')
-    proportion = models.CharField(max_length=10, choices=PROPORTION_CHOICES)
-    #(sert à quoi?) renommer "regime_travail" ou autre?    convertir data en % (data * 100; ex: 1 = 100%)
-    #Méta
-    date_modification = models.DateField(auto_now=True)
-    actif = models.BooleanField()
 
     def __unicode__(self):
-        return u'%s - %s' % (self.implantation, self.type_poste.nom)
-
-
-class Service(models.Model):
-    #Identification
-    id = models.IntegerField(primary_key=True)
+        return u'%s' % (self.nom)
+    
+class Service(Metadata):
+    """Unité administrative où les Postes sont rattachés.
+    """
     nom = models.CharField(max_length=255)
-    #Méta
-    actif = models.BooleanField()
+        
+    class Meta:
+        ordering = ['nom']
 
     def __unicode__(self):
-        return u'%s' % self.nom
+        return u'%s' % (self.nom)
 
 
 TYPE_ORGANISME_CHOICES = (
@@ -208,86 +656,164 @@ TYPE_ORGANISME_CHOICES = (
     ('DET', 'Détachement'),
 )
 
-class OrganismeBstg(models.Model):
-    #Identification
-    id = models.IntegerField(primary_key=True)
+class OrganismeBstg(Metadata):
+    """Organisation d'où provient un Employe mis à disposition (MAD) de 
+    ou détaché (DET) à l'AUF à titre gratuit.
+    
+    (BSTG = bien et service à titre gratuit.)
+    """
     nom = models.CharField(max_length=255)
     type = models.CharField(max_length=10, choices=TYPE_ORGANISME_CHOICES)
-    #Méta
-    actif = models.BooleanField()
+    pays = models.ForeignKey(ref.Pays, to_field='code', 
+                            db_column='pays',
+                            related_name='organismes_bstg',
+                            null=True, blank=True)
 
-CONTRAT_CATEGORIE_CHOICES= (
-    ('A', 'A'),
-    ('C', 'C'),
-)
-class Statut(models.Model):
-    #Identification
-    id = models.IntegerField(primary_key=True)
+    class Meta:
+        ordering = ['type', 'nom']
+
+    def __unicode__(self):
+        return u'%s (%s)' % (self.nom, self.type)
+
+class Statut(Metadata):
+    """Statut de l'Employe dans le cadre d'un Dossier particulier.
+    """
+    # Identification
     code = models.CharField(max_length=25, unique=True)
     nom = models.CharField(max_length=255)
-    type_contrat_categorie = models.CharField(max_length=10, choices=CONTRAT_CATEGORIE_CHOICES)
-    #CHOICES A, C (veut dire quoi?) voir TypeContrat.categorie
-    #Méta
-    actif = models.BooleanField()
+
+    class Meta:
+        ordering = ['code']
+        
+    def __unicode__(self):
+        return u'%s : %s' % (self.code, self.nom)
+
 
 TYPE_CLASSEMENT_CHOICES = (
-    ('S', 'S'),
-    ('T', 'T'),
+    ('S', 'S -Soutien'),
+    ('T', 'T - Technicien'),
+    ('P', 'P - Professionel'),
+    ('C', 'C - Cadre'),
+    ('D', 'D - Direction'),
+    ('SO', 'SO - Sans objet [expatriés]'),
+    ('HG', 'HG - Hors grille [direction]'),
 )
-class Classement(models.Model):
-    #Identification
-    id = models.IntegerField(primary_key=True)
+
+class Classement(Metadata):
+    """Éléments de classement de la 
+    "Grille générique de classement hiérarchique".
+    
+    Utile pour connaître, pour un Dossier, le salaire de base théorique lié au 
+    classement dans la grille. Le classement donne le coefficient utilisé dans:
+
+    salaire de base = coefficient * valeur du point de l'Implantation du Poste
+    """
+    # Identification
     type = models.CharField(max_length=10, choices=TYPE_CLASSEMENT_CHOICES)
     echelon = models.IntegerField()
     degre = models.IntegerField()
-    coefficient = models.FloatField()
-    #Méta
-    commentaire = models.TextField(null=True, blank=True) 
-    date_modification = models.DateField(auto_now=True)
-    actif = models.BooleanField()
+    coefficient = models.FloatField(default=0)
+    # Méta
+    # annee # au lieu de date_debut et date_fin
+    commentaire = models.TextField(null=True, blank=True)
+    
+    class Meta:
+        ordering = ['type','echelon','degre','coefficient']
 
     def __unicode__(self):
         return u'%s.%s.%s (%s)' % (self.type, self.echelon, self.degre,
                                    self.coefficient)
 
-
-class ValeurPoint(models.Model):
-    #Identification
-    id = models.IntegerField(primary_key=True)
-    valeur = models.FloatField()
-    implantation = models.ForeignKey('datamaster_modeles.Implantation', db_column='implantation', related_name='valeurs_point')
-    #Méta
+class TauxChange(Metadata):
+    """Taux de change de la devise vers l'euro (EUR) 
+    pour chaque année budgétaire.
+    """
+    # Identification
+    devise = models.ForeignKey('Devise', to_field='code', db_column='devise',
+                            related_name='+')
     annee = models.IntegerField()
-
+    taux = models.FloatField()
+    
+    class Meta:
+        ordering = ['annee', 'devise__code']
+    
     def __unicode__(self):
-        return u'%s (%s-%s)' % (self.valeur, self.implantation_id, self.annee)
+        return u'%s : %s €' % (self.devise.code, self.taux)
 
+class ValeurPoint(Metadata):
+    """Utile pour connaître, pour un Dossier, le salaire de base théorique lié 
+    au classement dans la grille. La ValeurPoint s'obtient par l'implantation 
+    du POste de ce Dossier : dossier.poste.implantation (pseudo code).
 
-class TauxChange(models.Model):
-    #Identification
-    id = models.IntegerField(primary_key=True)
-    devise = models.ForeignKey('Devise', to_field='code', db_column='devise')
+    salaire de base = coefficient * valeur du point de l'Implantation du Poste
+    """
+    valeur = models.FloatField()
+    devise = models.ForeignKey('Devise', db_column='devise', 
+                            related_name='+', default=5)
+    implantation = models.ForeignKey(ref.Implantation, 
+                            db_column='implantation', 
+                            related_name='valeur_point')
+    # Méta
     annee = models.IntegerField()
-    taux = models.FloatField()
-    #Relations
-    implantation = models.ForeignKey('datamaster_modeles.Implantation', db_column='implantation', related_name='taux_change')
 
+    # Stockage de tous les taux de change 
+    # pour optimiser la recherche de la devise associée
+    annee_courante = datetime.datetime.now().year
+    tauxchange = TauxChange.objects.select_related('devise')    \
+                            .filter(annee=annee_courante)
+
+    class Meta:
+        ordering = ['annee', 'implantation__nom']
+        
+    def __unicode__(self):
+        tx = self.get_tauxchange_courant()
+        if tx:
+            devise_code = tx.devise.code
+        else:
+            devise_code = "??"
+        return u'%s %s (%s-%s)' % (self.valeur, devise_code, 
+                            self.implantation_id, self.annee)
+        
+    class Meta:
+        ordering = ['valeur']
 
-class Devise(models.Model):
-    id = models.IntegerField(primary_key=True)
+class Devise(Metadata):
+    """Devise monétaire.
+    """
     code =  models.CharField(max_length=10, unique=True)
     nom = models.CharField(max_length=255)
 
+    class Meta:
+        ordering = ['code']
+        
     def __unicode__(self):
         return u'%s - %s' % (self.code, self.nom)
 
-
-class TypeContrat(models.Model):
-    #Identification
-    id = models.IntegerField(primary_key=True)
+class TypeContrat(Metadata):
+    """Type de contrat.
+    """
     nom = models.CharField(max_length=255)
-    nom_long = models.CharField(max_length=255) #description
-    categorie = models.CharField(max_length=10, choices=CONTRAT_CATEGORIE_CHOICES)
-    #Méta
-    actif = models.BooleanField()
+    nom_long = models.CharField(max_length=255)
 
+    def __unicode__(self):
+        return u'%s' % (self.nom)
+        
+        
+### AUTRES
+
+class ResponsableImplantation(Metadata):
+    """Le responsable d'une implantation. 
+    Anciennement géré sur le Dossier du responsable.
+    """
+    employe = models.ForeignKey('Employe', db_column='employe', 
+                            related_name='+',
+                            null=True, blank=True)
+    implantation = models.ForeignKey(ref.Implantation, 
+                            db_column='implantation', related_name='+', 
+                            unique=True)
+
+    def __unicode__(self):
+        return u'%s : %s' % (self.implantation, self.employe)
+        
+    class Meta:
+        ordering = ['implantation__nom']
index 8b56524..43d4228 100644 (file)
@@ -16,17 +16,21 @@ SITUATION_CHOICES = (
 )
 
 class Employe(models.Model):   
-    #Identification
+    # Identification
     id = models.IntegerField(primary_key=True)
     nom = models.CharField(max_length=255)
     prenom = models.CharField(max_length=255)
-    nationalite = models.ForeignKey('datamaster_modeles.Pays', to_field='code', related_name='nationalite', db_column='nationalite')
+    nationalite = models.ForeignKey('datamaster_modeles.Pays', to_field='code', 
+                            related_name='nationalite', 
+                            db_column='nationalite')
     date_naissance = models.DateField(null=True, blank=True)
-    #Infos personnelles
-    genre = models.CharField(max_length=1, choices=GENRE_CHOICES, null=True, blank=True)
-    situation_famille = models.CharField(max_length=1, choices=SITUATION_CHOICES, null=True, blank=True)
+    # Infos personnelles
+    genre = models.CharField(max_length=1, null=True, blank=True,
+                            choices=GENRE_CHOICES)
+    situation_famille = models.CharField(max_length=1, null=True, blank=True,
+                            choices=SITUATION_CHOICES)
     date_entree = models.DateField(null=True, blank=True) #devrait pas être là
-    #Coordonnées
+    # Coordonnées
     tel_domicile = models.CharField(max_length=255, null=True, blank=True)
     tel_cellulaire = models.CharField(max_length=255, null=True, blank=True)
     adresse = models.CharField(max_length=255, null=True, blank=True)
@@ -34,8 +38,10 @@ class Employe(models.Model):
     ville = models.CharField(max_length=255, null=True, blank=True)
     province = models.CharField(max_length=255, null=True, blank=True)
     code_postal = models.CharField(max_length=255, null=True, blank=True)
-    pays = models.ForeignKey('datamaster_modeles.Pays', to_field='code', null=True, blank=True, related_name='pays', db_column='pays')
-    #Métas
+    pays = models.ForeignKey('datamaster_modeles.Pays', to_field='code', 
+                            null=True, blank=True, 
+                            related_name='pays', db_column='pays')
+    # Métas
     date_creation = models.DateField(auto_now_add=True)
     date_maj = models.DateField(auto_now=True)
     commentaire = models.TextField(null=True, blank=True)
@@ -71,37 +77,56 @@ class DossierManager(models.Manager):
         return super(DossierManager, self).get_query_set().select_related(*fkeys).all()
 
 class Dossier(models.Model):
-    #Identification
+    # Identification
     id = models.IntegerField(primary_key=True)
     code = models.CharField(max_length=10, unique=True)
     employe = models.ForeignKey('Employe', db_column='employe')
-    #Postes
-    poste1 = models.ForeignKey('Poste', db_column='poste1', related_name='poste1')
-    implantation1 = models.ForeignKey('datamaster_modeles.Implantation', db_column='implantation1', related_name='implantation1', blank=True, null=True)
+    # Postes
+    poste1 = models.ForeignKey('Poste', db_column='poste1', 
+                            related_name='poste1')
+    implantation1 = models.ForeignKey('datamaster_modeles.Implantation', 
+                            db_column='implantation1', 
+                            related_name='implantation1', 
+                            blank=True, null=True)
     complement1 = models.TextField(null=True, blank=True)
     responsable_implantation1 = models.IntegerField()
-    poste2 = models.ForeignKey('Poste', db_column='poste2', related_name='poste2', blank=True, null=True)
-    implantation2 = models.ForeignKey('datamaster_modeles.Implantation', db_column='implantation2', related_name='implantation2', null=True, blank=True)
+    poste2 = models.ForeignKey('Poste', db_column='poste2', 
+                            related_name='poste2', 
+                            blank=True, null=True)
+    implantation2 = models.ForeignKey('datamaster_modeles.Implantation', 
+                            db_column='implantation2', 
+                            related_name='implantation2', 
+                            null=True, blank=True)
     complement2 = models.TextField(null=True, blank=True)
     responsable_implantation2 = models.IntegerField() 
-    #Relations
-    service = models.ForeignKey('Service', db_column='service', blank=True, null=True)
-    responsable = models.ForeignKey('Employe', db_column='responsable', related_name='responsable', blank=True, null=True)
-    remplacement_de = models.ForeignKey('Employe', db_column='remplacement_de', related_name='remplacement_de', blank=True, null=True)
+    # Relations
+    service = models.ForeignKey('Service', db_column='service', 
+                            blank=True, null=True)
+    responsable = models.ForeignKey('Employe', db_column='responsable', 
+                            related_name='responsable', 
+                            blank=True, null=True)
+    remplacement_de = models.ForeignKey('Employe', db_column='remplacement_de', 
+                            related_name='remplacement_de', 
+                            blank=True, null=True)
     type = models.CharField(max_length=1, choices=TYPE_DOSSIER_CHOICES)
-    statut = models.ForeignKey('Statut', db_column='statut', blank=True, null=True)
-    organisme_bstg = models.ForeignKey('OrganismeBstg', db_column='organisme_bstg', blank=True, null=True)
-    #Rémunération
-    classement = models.ForeignKey('Classement', db_column='classement', blank=True, null=True)
+    statut = models.ForeignKey('Statut', db_column='statut', 
+                            blank=True, null=True)
+    organisme_bstg = models.ForeignKey('OrganismeBstg', 
+                            db_column='organisme_bstg', 
+                            blank=True, null=True)
+    # Rémunération
+    classement = models.ForeignKey('Classement', db_column='classement', 
+                            blank=True, null=True)
     regime_travail = models.IntegerField()
-    #Mandat
+    # Mandat
     mandat_date_debut = models.DateField()
     mandat_date_fin = models.DateField(null=True, blank=True)
-    #Contrat
+    # Contrat
     contrat_date_debut = models.DateField()
     contrat_date_fin = models.DateField()
-    type_contrat = models.ForeignKey('TypeContrat', db_column='type_contrat', blank=True, null=True)
-    #Meta
+    type_contrat = models.ForeignKey('TypeContrat', db_column='type_contrat', 
+                            blank=True, null=True)
+    # Meta
     date_creation = models.DateField(auto_now_add=True)
     date_maj = models.DateField(auto_now=True)
     commentaire = models.TextField(null=True, blank=True) 
@@ -151,29 +176,33 @@ LIEN_PARENTE_CHOICES = (
 )
 
 class AyantDroit(models.Model):
-    #Identification
+    # Identification
     id = models.IntegerField(primary_key=True)
     nom = models.CharField(max_length=255)
     prenom = models.CharField(max_length=255)
-    #Relation
-    employe = models.ForeignKey('Employe', db_column='employe', related_name='employe')
-    lien_parente = models.CharField(max_length=10, choices=LIEN_PARENTE_CHOICES, null=True, blank=True)
-    #Méta
+    # Relation
+    employe = models.ForeignKey('Employe', db_column='employe', 
+                            related_name='employe')
+    lien_parente = models.CharField(max_length=10, null=True, blank=True, 
+                            choices=LIEN_PARENTE_CHOICES)
+    # Méta
     commentaire = models.TextField(null=True, blank=True) 
     actif = models.BooleanField()
     
     
 class Remuneration(models.Model):
-    #Identification
+    # Identification
     id = models.IntegerField(primary_key=True)
     dossier = models.ForeignKey('Dossier', db_column='dossier')
     type = models.ForeignKey('TypeRemuneration', db_column='type')
-    type_revalorisation = models.ForeignKey('TypeRevalorisation', db_column='type_revalorisation', null=True, blank=True)
+    type_revalorisation = models.ForeignKey('TypeRevalorisation', 
+                            db_column='type_revalorisation', 
+                            null=True, blank=True)
     montant = models.FloatField(null=True, blank=True)
     devise = models.ForeignKey('Devise', to_field='id', db_column='devise', null=True, blank=True)
     date_effective = models.DateField(null=True, blank=True)
     pourcentage = models.IntegerField(null=True, blank=True)
-    #Méta
+    # Méta
     date_creation = models.DateField(auto_now_add=True)
     user_creation = models.IntegerField(null=True, blank=True) #User ou employé
     desactivation = models.NullBooleanField(null=True, blank=True) #
@@ -198,21 +227,22 @@ class Remuneration(models.Model):
         return int(self.montant * self.get_taux_historique().taux)
 
 class FamilleEmploi(models.Model):
-    #Identification
+    # Identification
     id = models.IntegerField(primary_key=True)
     nom = models.CharField(max_length=255)
-    #Méta
+    # Méta
     actif = models.BooleanField()
 
 class TypePoste(models.Model):
-    #Identification
+    # Identification
     id = models.IntegerField(primary_key=True)
     nom = models.CharField(max_length=255)
     nom_feminin = models.CharField(max_length=255)
     description = models.CharField(max_length=255)
     is_responsable = models.BooleanField()
-    famille_emploi = models.ForeignKey('FamilleEmploi', db_column='famille_emploi')
-    #Méta
+    famille_emploi = models.ForeignKey('FamilleEmploi', 
+                            db_column='famille_emploi')
+    # Méta
     date_modification = models.DateField(auto_now=True)
     actif = models.BooleanField()
 
@@ -237,12 +267,14 @@ NATURE_REMUNERATION_CHOICES = (
 )
 
 class TypeRemuneration(models.Model):
-    #Identification
+    # Identification
     id = models.IntegerField(primary_key=True)
     nom = models.CharField(max_length=255)
-    type_paiement = models.CharField(max_length=30, choices=TYPE_PAIEMENT_CHOICES)
-    nature_remuneration = models.CharField(max_length=30, choices=NATURE_REMUNERATION_CHOICES)
-    #Méta
+    type_paiement = models.CharField(max_length=30, 
+                            choices=TYPE_PAIEMENT_CHOICES)
+    nature_remuneration = models.CharField(max_length=30, 
+                            choices=NATURE_REMUNERATION_CHOICES)
+    # Méta
     actif = models.BooleanField()
 
     def __unicode__(self):
@@ -250,10 +282,10 @@ class TypeRemuneration(models.Model):
 
 
 class TypeRevalorisation(models.Model):
-    #Identification
+    # Identification
     id = models.IntegerField(primary_key=True)
     nom = models.CharField(max_length=255)
-    #Méta
+    # Méta
     actif = models.BooleanField()
     
 PROPORTION_CHOICES = (
@@ -275,14 +307,14 @@ class PosteManager(SecurityManager):
         return super(PosteManager, self).get_query_set().select_related(*fkeys).all()
 
 class Poste(models.Model):
-    #Identification
+    # Identification
     id = models.IntegerField(primary_key=True)
     implantation = models.ForeignKey('datamaster_modeles.Implantation',
-            db_column='implantation', related_name='+')
+                            db_column='implantation', related_name='+')
     type_poste = models.ForeignKey('TypePoste', db_column='type_poste')
     proportion = models.CharField(max_length=10, choices=PROPORTION_CHOICES)
     #(sert à quoi?) renommer "regime_travail" ou autre?    convertir data en % (data * 100; ex: 1 = 100%)
-    #Méta
+    # Méta
     date_modification = models.DateField(auto_now=True)
     actif = models.BooleanField()
 
@@ -290,14 +322,15 @@ class Poste(models.Model):
     objects = PosteManager()
 
     def __unicode__(self):
-        return u'%s - %s [%s]' % (self.implantation, self.type_poste.nom, self.id)
+        return u'%s - %s [%s]' % (self.implantation, self.type_poste.nom, 
+                            self.id)
 
 
 class Service(models.Model):
-    #Identification
+    # Identification
     id = models.IntegerField(primary_key=True)
     nom = models.CharField(max_length=255)
-    #Méta
+    # Méta
     actif = models.BooleanField()
 
     def __unicode__(self):
@@ -313,11 +346,11 @@ TYPE_ORGANISME_CHOICES = (
 )
 
 class OrganismeBstg(models.Model):
-    #Identification
+    # Identification
     id = models.IntegerField(primary_key=True)
     nom = models.CharField(max_length=255)
     type = models.CharField(max_length=10, choices=TYPE_ORGANISME_CHOICES)
-    #Méta
+    # Méta
     actif = models.BooleanField()
 
     def __unicode__(self):
@@ -332,13 +365,14 @@ CONTRAT_CATEGORIE_CHOICES= (
     ('C', 'C'),
 )
 class Statut(models.Model):
-    #Identification
+    # Identification
     id = models.IntegerField(primary_key=True)
     code = models.CharField(max_length=25, unique=True)
     nom = models.CharField(max_length=255)
-    type_contrat_categorie = models.CharField(max_length=10, choices=CONTRAT_CATEGORIE_CHOICES)
+    type_contrat_categorie = models.CharField(max_length=10, 
+                            choices=CONTRAT_CATEGORIE_CHOICES)
     #CHOICES A, C (veut dire quoi?) voir TypeContrat.categorie
-    #Méta
+    # Méta
     actif = models.BooleanField()
 
     def __unicode__(self):
@@ -349,13 +383,13 @@ TYPE_CLASSEMENT_CHOICES = (
     ('T', 'T'),
 )
 class Classement(models.Model):
-    #Identification
+    # Identification
     id = models.IntegerField(primary_key=True)
     type = models.CharField(max_length=10, choices=TYPE_CLASSEMENT_CHOICES)
     echelon = models.IntegerField()
     degre = models.IntegerField()
     coefficient = models.FloatField()
-    #Méta
+    # Méta
     commentaire = models.TextField(null=True, blank=True) 
     date_modification = models.DateField(auto_now=True)
     actif = models.BooleanField()
@@ -367,13 +401,15 @@ class Classement(models.Model):
         ordering = ['type','echelon','degre','coefficient']
 
 class TauxChange(models.Model):
-    #Identification
+    # Identification
     id = models.IntegerField(primary_key=True)
-    devise = models.ForeignKey('Devise', db_column='devise')
+    devise = models.ForeignKey('Devise', to_field='code', db_column='devise')
     annee = models.IntegerField()
     taux = models.FloatField()
-    #Relations
-    implantation = models.ForeignKey('datamaster_modeles.Implantation', db_column='implantation')
+    # Relations
+    implantation = models.ForeignKey('datamaster_modeles.Implantation', 
+                            db_column='implantation',
+                            related_name='taux_change')
 
     def __unicode__(self):
         return u"%s %s : %s" % (self.devise, self.annee, self.taux)
@@ -398,11 +434,13 @@ class ValeurPointManager(models.Manager):
 
 
 class ValeurPoint(models.Model):
-    #Identification
+    # Identification
     id = models.IntegerField(primary_key=True)
     valeur = models.FloatField()
-    implantation = models.ForeignKey('datamaster_modeles.Implantation', db_column='implantation')
-    #Méta
+    implantation = models.ForeignKey('datamaster_modeles.Implantation', 
+                            db_column='implantation', 
+                            related_name='valeurs_point')
+    # Méta
     annee = models.IntegerField()
 
     # Stockage de tous les taux de change pour optimiser la recherche de la devise associée
@@ -445,12 +483,13 @@ class Devise(models.Model):
 
 
 class TypeContrat(models.Model):
-    #Identification
+    # Identification
     id = models.IntegerField(primary_key=True)
     nom = models.CharField(max_length=255)
     nom_long = models.CharField(max_length=255) #description
-    categorie = models.CharField(max_length=10, choices=CONTRAT_CATEGORIE_CHOICES)
-    #Méta
+    categorie = models.CharField(max_length=10, 
+                            choices=CONTRAT_CATEGORIE_CHOICES)
+    # Méta
     actif = models.BooleanField()
 
     def __unicode__(self):
index ebcff36..c88acb6 100644 (file)
@@ -65,8 +65,8 @@ INSTALLED_APPS = (
     'ajax_select',
     'south',
     'reversion',
+    'project.rh', 
     'auf.django.workflow',
-    #'project.rh', 
     'project.rh_v1',
     'project.dae',
 )