refact models (incomplet)
authordavin baragiotta <davin.baragiotta@u-db.(none)>
Tue, 3 May 2011 20:36:39 +0000 (16:36 -0400)
committerDavin BARAGIOTTA <davin.baragiotta@auf.org>
Tue, 3 May 2011 20:36:39 +0000 (16:36 -0400)
project/dae/models.py
project/rh/models.py

index 1e57a52..a392a55 100644 (file)
@@ -9,23 +9,16 @@ import datamaster_modeles.models as ref
 from rh_v1 import models as rh
 import settings
 
-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)
@@ -36,10 +29,12 @@ 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 PosteManager(models.Manager):
     """
@@ -64,46 +59,44 @@ class PosteManager(models.Manager):
 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,
@@ -147,12 +140,15 @@ class Poste(PosteWorkflow, models.Model):
     justification = models.TextField()
 
     # Validations
-    validation_bureau_regional = models.BooleanField(verbose_name="Validation bureau régional")
+    validation_bureau_regional = models.BooleanField(
+                            verbose_name="Validation bureau régional")
     validation_bureau_regional_date = models.DateField(blank=True, null=True)
     validation_drh = models.BooleanField(verbose_name="Validation DRH")
     validation_drh_date = models.DateField(blank=True, null=True)
-    validation_secretaire_general = models.BooleanField(verbose_name="Validation secrétaire général")
-    validation_secretaire_general_date = models.DateField(blank=True, null=True)
+    validation_secretaire_general = models.BooleanField(
+                            verbose_name="Validation secrétaire général")
+    validation_secretaire_general_date = models.DateField(blank=True, 
+                            null=True)
     validation_recteur = models.BooleanField(verbose_name="Validation recteur")
     validation_recteur_date = models.DateField(blank=True, null=True)
 
@@ -160,10 +156,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
@@ -171,8 +167,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)
@@ -180,10 +178,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 []
@@ -192,7 +192,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:
@@ -212,7 +213,9 @@ 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
         except:
@@ -221,7 +224,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:
@@ -251,7 +255,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)
@@ -263,12 +266,24 @@ class PosteFinancement(models.Model):
     class Meta:
         ordering = ['type']
 
+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
@@ -279,20 +294,22 @@ class Employe(models.Model):
     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'),
     ('scs', 'SCS'),
     ('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(models.Model):
 
     # Modèle existant
@@ -339,21 +356,26 @@ class Dossier(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='+')
@@ -377,31 +399,33 @@ class Dossier(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)
+
+
+### 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)
@@ -416,6 +440,8 @@ class Remuneration(models.Model):
         return round(self.montant_euro() / 12, 2)
 
 
+### JUSTIFICATIONS
+
 TYPE_JUSTIFICATIONS = (
     ('N', 'Nouvel employé'),
     ('R', 'Renouvellement employé'),
@@ -439,16 +465,16 @@ class JustificationAutreEmploye(models.Model):
     reponse = models.TextField()
 
 
+### VALIDATIONS
+
 class Validation(models.Model):
     # user
     date = models.DateField()
 
     # avis = ? (CHOICES?)
 
-
 class ValidationPoste(models.Model):
     poste = models.ForeignKey('Poste')
 
-
 class ValidationEmploye(models.Model):
     employe = models.ForeignKey('Employe')
index 1cc2d26..380e3df 100644 (file)
@@ -9,6 +9,12 @@ import settings
 import datamaster_modeles.models as ref
 
 
+# Constantes
+HELP_TEXT_DATE = "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)
@@ -21,20 +27,27 @@ def dossier_piece_dispatch(instance, filename):
     path = "dossier/%s/%s" % (instance.dossier_id, filename)
     return path
 
-# Commentaires
-class Commentaire(models.Model):
-    texte = models.TextField()
-    # Méta
-    date_creation = models.DateTimeField(auto_now_add=True)
+# Abstracts
+class Metadata(models.Model):
+    """Méta-données AUF.
+    """
+    actif = models.BooleanField(default=True)
+    date_creation = models.DateField(auto_now_add=True)
+    user_creation = models.ForeignKey("auth.User")
     date_modification = models.DateField(auto_now=True)
-    owner = models.ForeignKey("auth.User")
-    actif = models.BooleanField()
+    user_modification = models.ForeignKey("auth.User")
+    date_desactivation = models.DateField()
+    user_desactivation = models.ForeignKey("auth.User")
     
     class Meta:
         abstract = True
 
-# Constantes
-HELP_TEXT_DATE = "format: aaaa-mm-jj"
+class Commentaire(Metadata):
+    texte = models.TextField()
+    owner = models.ForeignKey("auth.User")
+    
+    class Meta:
+        abstract = True
 
 
 ### POSTE
@@ -44,50 +57,50 @@ POSTE_APPEL_CHOICES = (
     ('externe', 'Externe'),
 )
 
-class Poste(models.Model):
+class Poste(Metadata):
     # Identification
     id = models.IntegerField(primary_key=True)
-    nom = models.CharField(verbose_name="Titre du poste", max_length=255)
-    nom_feminin = models.CharField(verbose_name="Titre du poste", max_length=255)
+    nom = models.CharField(max_length=255, 
+                            verbose_name="Titre du poste", )
+    nom_feminin = models.CharField(max_length=255,
+                            verbose_name="Titre du poste (au féminin)")
     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")
+    type_poste = models.ForeignKey('TypePoste', null=True, related_name='+')
+    service = models.ForeignKey('Service', related_name='+',
+                            verbose_name=u"Direction/Service/Pôle support")
+    responsable = models.ForeignKey('Poste', related_name='+',
+                            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?
     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_min = models.ForeignKey('Classement', related_name='+',
                             blank=True, null=True)
-    classement_max = models.ForeignKey(rh.Classement, related_name='+',
+    classement_max = models.ForeignKey('Classement', related_name='+',
                             blank=True, null=True)
-    valeur_point_min = models.ForeignKey(rh.ValeurPoint, related_name='+', 
+    valeur_point_min = models.ForeignKey('ValeurPoint', related_name='+', 
                             blank=True, null=True)
-    valeur_point_max = models.ForeignKey(rh.ValeurPoint, related_name='+', 
+    valeur_point_max = models.ForeignKey('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='+')
+    devise_min = models.ForeignKey('Devise', default=5, related_name='+')
+    devise_max = models.ForeignKey('Devise', default=5, related_name='+')
     salaire_min = models.DecimalField(max_digits=12, decimal_places=2,
                                       default=0)
     salaire_max = models.DecimalField(max_digits=12, decimal_places=2,
@@ -102,7 +115,7 @@ class Poste(models.Model):
                                       default=0)
 
     # Comparatifs de rémunération
-    devise_comparaison = models.ForeignKey(rh.Devise, related_name='+',
+    devise_comparaison = models.ForeignKey('Devise', related_name='+',
                                            default=5)
     comp_locale_min = models.DecimalField(max_digits=12, decimal_places=2,
                                           null=True, blank=True)
@@ -128,19 +141,16 @@ class Poste(models.Model):
     # Justification
     justification = models.TextField()
 
-    # Méta
+    # Autres Metadata
     date_validation = models.DateTimeField(null=True, blank=True)   # de dae
-    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=HELP_TEXT_DATE)
     date_fin = models.DateField(null=True, blank=True,
                                     verbose_name="Date de fin",
-                                    help_text=)
-    actif = models.BooleanField(default=True)
+                                    help_text=HELP_TEXT_DATE)
             
     def __unicode__(self):
-        # gérer si poste est vacant ou non dans affichage
+        # TODO : gérer si poste est vacant ou non dans affichage
         return u'%s - %s [%s]' % (self.implantation, self.nom, self.id)
 
 
@@ -174,6 +184,7 @@ class PostePiece(models.Model):
 class PosteCommentaire(Commentaire):
     poste = models.ForeignKey("Poste")
 
+
 ### EMPLOYÉ/PERSONNE
 
 GENRE_CHOICES = (
@@ -186,18 +197,18 @@ SITUATION_CHOICES = (
     ('M', 'Marié'),
 )
 
-class Employe(models.Model):
+class Employe(Metadata):
     # Identification
     id = models.IntegerField(primary_key=True)
     nom = models.CharField(max_length=255)
-    prenom = models.CharField(max_length=255)
+    prenom = models.CharField(max_length=255, verbose_name='Prénom')
     nationalite = models.ForeignKey(ref.Pays, to_field='code', 
                             related_name='employes_nationalite', 
                             db_column='nationalite')
     date_naissance = models.DateField(null=True, blank=True)
+    genre = models.CharField(max_length=1, choices=GENRE_CHOICES)
     
     # Infos personnelles
-    genre = models.CharField(max_length=1, choices=GENRE_CHOICES)
     situation_famille = models.CharField(max_length=1, null=True, blank=True,
                             choices=SITUATION_CHOICES)
     date_entree = models.DateField(verbose_name="Date d'entrée à l'AUF", 
@@ -214,13 +225,9 @@ class Employe(models.Model):
     pays = models.ForeignKey(ref.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)  # date_modification
 
     def __unicode__(self):
-        return u'%s %s' % (self.prenom, self.nom)
+        return u'%s %s' % (self.prenom, self.nom.upper())
 
 class EmployePiece(models.Model):
     """Documents relatifs à l'employé
@@ -235,6 +242,7 @@ class EmployePiece(models.Model):
 class EmployeCommentaire(Commentaire):
     employe = models.ForeignKey("Employe")
 
+
 LIEN_PARENTE_CHOICES = (
     ('Conjoint', 'Conjoint'),
     ('Conjointe', 'Conjointe'),
@@ -242,28 +250,27 @@ LIEN_PARENTE_CHOICES = (
     ('Fils', 'Fils'),
 )
 
-class AyantDroit(models.Model):
+class AyantDroit(Metadata):
     # Identification
     id = models.IntegerField(primary_key=True)
     nom = models.CharField(max_length=255)
     prenom = models.CharField(max_length=255)
-    # nationalite facult
-    # date_naissance facultatif
-    # genre facultafif
+    nationalite = models.ForeignKey(ref.Pays, to_field='code', 
+                            related_name='ayantdroits_nationalite', 
+                            db_column='nationalite')
+    date_naissance = models.DateField(null=True, blank=True)
+    genre = models.CharField(max_length=1, choices=GENRE_CHOICES)
     
     # Relation
     employe = models.ForeignKey('Employe', db_column='employe', 
                             related_name='ayants_droit')
     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 AyantDroitCommentaire(Commentaire):
     ayant_droit = models.ForeignKey("AyantDroit")
 
+
 ### DOSSIER
 
 STATUT_RESIDENCE_CHOICES = (
@@ -277,13 +284,12 @@ COMPTE_COMPTA_CHOICES = (
     ('aucun', 'Aucun'),
 )
 
-class Dossier(models.Model):
+class Dossier(Metadata):
     # Identification
     id = models.IntegerField(primary_key=True)
-    #code = models.CharField(max_length=10, unique=True)
     employe = models.ForeignKey('Employe', db_column='employe')
     poste = models.ForeignKey('Poste', related_name='+', editable=False)
-    statut = models.ForeignKey('Statut', related_name='+')  # blank=True, null=True ?
+    statut = models.ForeignKey('Statut', related_name='+')
     organisme_bstg = models.ForeignKey('OrganismeBstg', 
             null=True, blank=True,
             verbose_name="Organisme", 
@@ -292,38 +298,35 @@ class Dossier(models.Model):
             related_name='+')
         
     # Recrutement
-    remplacement = models.BooleanField()     # default False
+    remplacement = models.BooleanField(default=False)
     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='+',
-                            null=True, blank=True)
-    regime_travail = models.DecimalField(max_digits=12, decimal_places=2,
-                                         verbose_name="Régime de travail",
-                                         help_text="% du temps complet")     # default = 100
+    classement = models.ForeignKey('Classement', related_name='+',
+                          null=True, blank=True)
+    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")    # default = 35
+                            decimal_places=2, 
+                            default=REGIME_TRAVAIL_NB_HEURE_SEMAINE_DEFAULT,
+                            verbose_name="Nb. heures par semaine")
 
     # Occupation du Poste par cet Employe (anciennement "mandat")
     date_debut = models.DateField(help_text=HELP_TEXT_DATE,
                             verbose_name="Date de début d'occupation de poste")
-    date_fin = models.DateField(help_text=HELP_TEXT_DATE,
-                            null=True, blank=True,
-                            verbose_name="Date de fin d'occupation de poste")
-
-    date_debut = models.DateField(verbose_name="Date de début",
-                                    help_text=HELP_TEXT_DATE)
     date_fin = models.DateField(null=True, blank=True,
-                                    verbose_name="Date de fin",
-                                    help_text=HELP_TEXT_DATE)
+                            help_text=HELP_TEXT_DATE,
+                            verbose_name="Date de fin d'occupation de poste")
     # Contrat
-    # m2m Contrat
+    # TODO : m2m Contrat
     
-    # Méta
-    date_creation = models.DateTimeField(auto_now_add=True)
-    date_modification = models.DateField(auto_now=True)
+    # Comptes
+    # TODO?
     
     def __unicode__(self):
         return u'%s - %s' % (self.poste.nom, self.employe)
@@ -341,34 +344,37 @@ class DossierPiece(models.Model):
 class DossierCommentaire(Commentaire):
     dossier = models.ForeignKey("Dossier")
 
+
 ### RÉMUNÉRATION
     
-class Remuneration(models.Model):
+class RemunerationMixin(Metadata):
     # Identification
     id = models.IntegerField(primary_key=True)
     dossier = models.ForeignKey('Dossier', db_column='dossier')
     type = models.ForeignKey('TypeRemuneration', db_column='type', 
                             related_name='+')
-    # TODO: what's that?
     type_revalorisation = models.ForeignKey('TypeRevalorisation', 
                             db_column='type_revalorisation', 
                             null=True, blank=True)
-    montant = models.FloatField(null=True, blank=True)  # Annuel (12 mois, 52 semaines, 364 jours)
-    devise = models.ForeignKey('Devise', to_field='code', db_column='devise')#, 
-                            #null=True, blank=True)
-    commentaire = models.CharField(max_length=255, null=True, blank=True) # commentaire = precision
-    date_debut = models.DateField(null=True, blank=True)    # anciennement date_effectif
-    #date_fin = null=True
+    montant = models.FloatField(max_digits=12, decimal_places=2, 
+                            null=True, blank=True)
+                            # Annuel (12 mois, 52 semaines, 364 jours?)
+    devise = models.ForeignKey('Devise', to_field='code',
+                               db_column='devise', related_name='+')
+    # commentaire = precision
+    commentaire = models.CharField(max_length=255, null=True, blank=True)
+    # date_debut = anciennement date_effectif
+    date_debut = models.DateField(null=True, blank=True)
+    date_fin = models.DateField(null=True, blank=True)
     
-    # Méta
-    date_creation = models.DateField(auto_now_add=True)
-    user_creation = models.IntegerField(null=True, blank=True) #User ou employé
-#    desactivation = models.BooleanField(null=True, blank=True) #
-#    date_desactivation = models.DateField(null=True, blank=True)
-#    user_desactivation = models.IntegerField(null=True, blank=True) #User ou employé
-#    annulation = models.BooleanField(null=True, blank=True)
-#    date_annulation = models.DateField(null=True, blank=True)
-#    user_annulation = models.IntegerField(null=True, blank=True) #User ou employé
+    class Meta: 
+        abstract = True
+    
+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)
@@ -389,9 +395,32 @@ class Remuneration(models.Model):
             devise = "???"
         return "%s %s" % (self.montant, devise)
 
-class HistoriqueRemuneration(models.Model):
+
+### 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")
-    # toujours pertinent si pour chaque Remuneration j'ai dd et df?
+    type_contrat = models.ForeignKey('TypeContrat', related_name='+')
+    date_debut = models.DateField(help_text=HELP_TEXT_DATE)
+    date_fin = models.DateField(null=True, blank=True,
+                                        help_text=HELP_TEXT_DATE)
+    
+
+### ÉVÉNEMENTS
+
+class Evenement(models.Models):
+    pass
+    # nom
+    # date_debut
+    # date_fin
+    
+class EvenementRemuneration(RemunerationMixin):
+    pass
+    # evenement
 
 
 ### RÉFÉRENCES RH 
@@ -525,7 +554,7 @@ class Classement(models.Model):
     type = models.CharField(max_length=10, choices=TYPE_CLASSEMENT_CHOICES)
     echelon = models.IntegerField()
     degre = models.IntegerField()
-    coefficient = models.FloatField()
+    coefficient = models.FloatField(null=True)
     # annee # au lieu de date_debut et date_fin
     # Méta
     commentaire = models.TextField(null=True, blank=True) 
@@ -559,7 +588,8 @@ class ValeurPoint(models.Model):
     # Méta
     annee = models.IntegerField()
 
-    # Stockage de tous les taux de change pour optimiser la recherche de la devise associée
+    # 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)
 
@@ -569,7 +599,8 @@ class ValeurPoint(models.Model):
             devise_code = tx.devise.code
         else:
             devise_code = "??"
-        return u'%s %s (%s-%s)' % (self.valeur, devise_code, self.implantation_id, self.annee)
+        return u'%s %s (%s-%s)' % (self.valeur, devise_code, 
+                            self.implantation_id, self.annee)
         
     class Meta:
         ordering = ['valeur']
@@ -586,7 +617,7 @@ class TypeContrat(models.Model):
     # Identification
     id = models.IntegerField(primary_key=True)
     nom = models.CharField(max_length=255)
-    nom_long = models.CharField(max_length=255) #description
+    nom_long = models.CharField(max_length=255) # description
     categorie = models.CharField(max_length=10, 
                             choices=CONTRAT_CATEGORIE_CHOICES) # A, C?
     # Méta
@@ -595,6 +626,9 @@ class TypeContrat(models.Model):
     def __unicode__(self):
         return u'%s' % (self.nom)
         
+        
+### AUTRES
+
 class ResponsableImplantation(models.Model):
     """Le responsable d'une implantation. 
     Anciennement géré sur le Dossier du responsable.
@@ -607,21 +641,3 @@ class ResponsableImplantation(models.Model):
         
     class Meta:
         ordering = ['implantation__nom']
-        
-class Contrat(models.Model):
-    dossier = models.ForeignKey("Dossier") # 1 contrat peut être dans plusieurs dossier Dossier.contrat = m2m Contrat
-    type_contrat = models.ForeignKey('TypeContrat', related_name='+')
-    date_debut = models.DateField(help_text=HELP_TEXT_DATE)
-    date_fin = models.DateField(null=True, blank=True,
-                                        help_text=HELP_TEXT_DATE)
-    
-class Evenement(models.Models):
-    pass
-    # nom
-    # date_debut
-    # date_fin
-    
-class EvenementRemuneration(models.Model):
-    pass
-    # evenement
-    # structure de rémunération hérité de abstract ici