list_display contrat #1542
[auf_rh_dae.git] / project / rh / models.py
index 1090f9c..e5bcfd4 100644 (file)
@@ -1,11 +1,10 @@
 # -=- encoding: utf-8 -=-
 
 # -=- encoding: utf-8 -=-
 
-import datetime
-
 from django.core.files.storage import FileSystemStorage
 from django.db import models
 from django.core.files.storage import FileSystemStorage
 from django.db import models
-import settings
-
+from django.conf import settings
+from auf.django.metadata.models import AUFMetadata
+from auf.django.metadata.managers import NoDeleteManager
 import datamaster_modeles.models as ref
 
 
 import datamaster_modeles.models as ref
 
 
@@ -27,30 +26,8 @@ def dossier_piece_dispatch(instance, filename):
     path = "dossier/%s/%s" % (instance.dossier_id, filename)
     return path
 
     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, null=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):
+class Commentaire(AUFMetadata):
     texte = models.TextField()
     owner = models.ForeignKey('auth.User', db_column='owner', related_name='+')
     
     texte = models.TextField()
     owner = models.ForeignKey('auth.User', db_column='owner', related_name='+')
     
@@ -69,11 +46,18 @@ POSTE_APPEL_CHOICES = (
     ('externe', 'Externe'),
 )
 
     ('externe', 'Externe'),
 )
 
-class Poste_(Metadata):
+class PosteManager(NoDeleteManager):
+    def get_query_set(self):
+        return super(PosteManager, self).get_query_set().select_related('implantation')
+
+class Poste_(AUFMetadata):
     """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.
     """
     """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.
     """
+
+    objects = PosteManager()
+
     # Identification
     nom = models.CharField(max_length=255, 
                             verbose_name="Titre du poste", )
     # Identification
     nom = models.CharField(max_length=255, 
                             verbose_name="Titre du poste", )
@@ -85,34 +69,34 @@ class Poste_(Metadata):
     type_poste = models.ForeignKey('TypePoste', db_column='type_poste',
                             related_name='+',
                             null=True)
     type_poste = models.ForeignKey('TypePoste', db_column='type_poste',
                             related_name='+',
                             null=True)
-    service = models.ForeignKey('Service', db_column='service', 
+    service = models.ForeignKey('Service', db_column='service', null=True,
                             related_name='+',
                             verbose_name="Direction/Service/Pôle support",
                             default=1)  # default = Rectorat
     responsable = models.ForeignKey('Poste', db_column='responsable', 
                             related_name='+',
                             verbose_name="Direction/Service/Pôle support",
                             default=1)  # default = Rectorat
     responsable = models.ForeignKey('Poste', db_column='responsable', 
-                            related_name='+',
+                            related_name='+', null=True,
                             verbose_name="Poste du responsable",
                             default=149)    # default = Recteur
                                 
     # Contrat
     regime_travail = models.DecimalField(max_digits=12, decimal_places=2,
                             verbose_name="Poste du responsable",
                             default=149)    # default = Recteur
                                 
     # Contrat
     regime_travail = models.DecimalField(max_digits=12, decimal_places=2,
-                            default=REGIME_TRAVAIL_DEFAULT, 
+                            default=REGIME_TRAVAIL_DEFAULT, null=True,
                             verbose_name="Temps de travail", 
                             help_text="% du temps complet")
     regime_travail_nb_heure_semaine = models.DecimalField(max_digits=12,
                             verbose_name="Temps de travail", 
                             help_text="% du temps complet")
     regime_travail_nb_heure_semaine = models.DecimalField(max_digits=12,
-                            decimal_places=2,
+                            decimal_places=2, null=True,
                             default=REGIME_TRAVAIL_NB_HEURE_SEMAINE_DEFAULT,
                             verbose_name="Nb. heures par semaine")
 
     # Recrutement
                             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)
-    mise_a_disposition = models.BooleanField(
+    local = models.NullBooleanField(verbose_name="Local", default=True, 
+                            null=True, blank=True)
+    expatrie = models.NullBooleanField(verbose_name="Expatrié", default=False, 
+                            null=True, blank=True)
+    mise_a_disposition = models.NullBooleanField(
                             verbose_name="Mise à disposition",
                             verbose_name="Mise à disposition",
-                            default=False)
-    appel = models.CharField(max_length=10, 
+                            null=True, default=False)
+    appel = models.CharField(max_length=10, null=True,
                             verbose_name="Appel à candidature",
                             choices=POSTE_APPEL_CHOICES,
                             default='interne')
                             verbose_name="Appel à candidature",
                             choices=POSTE_APPEL_CHOICES,
                             default='interne')
@@ -130,25 +114,25 @@ class Poste_(Metadata):
     valeur_point_max = models.ForeignKey('ValeurPoint', 
                             db_column='valeur_point_max', 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', 
+    devise_min = models.ForeignKey('Devise', db_column='devise_min', null=True,
                             related_name='+', default=5)
                             related_name='+', default=5)
-    devise_max = models.ForeignKey('Devise', db_column='devise_max', 
+    devise_max = models.ForeignKey('Devise', db_column='devise_max', null=True,
                             related_name='+', default=5)
     salaire_min = models.DecimalField(max_digits=12, decimal_places=2,
                             related_name='+', default=5)
     salaire_min = models.DecimalField(max_digits=12, decimal_places=2,
-                            default=0)
+                            null=True, default=0)
     salaire_max = models.DecimalField(max_digits=12, decimal_places=2,
     salaire_max = models.DecimalField(max_digits=12, decimal_places=2,
-                            default=0)
+                            null=True, default=0)
     indemn_min = models.DecimalField(max_digits=12, decimal_places=2,
     indemn_min = models.DecimalField(max_digits=12, decimal_places=2,
-                            default=0)
+                            null=True, default=0)
     indemn_max = models.DecimalField(max_digits=12, decimal_places=2,
     indemn_max = models.DecimalField(max_digits=12, decimal_places=2,
-                            default=0)
+                            null=True, default=0)
     autre_min = models.DecimalField(max_digits=12, decimal_places=2,
     autre_min = models.DecimalField(max_digits=12, decimal_places=2,
-                            default=0)
+                            null=True, default=0)
     autre_max = models.DecimalField(max_digits=12, decimal_places=2,
     autre_max = models.DecimalField(max_digits=12, decimal_places=2,
-                            default=0)
+                            null=True, default=0)
 
     # Comparatifs de rémunération
 
     # Comparatifs de rémunération
-    devise_comparaison = models.ForeignKey('Devise', 
+    devise_comparaison = models.ForeignKey('Devise', null=True,
                             db_column='devise_comparaison', 
                             related_name='+',
                             default=5)
                             db_column='devise_comparaison', 
                             related_name='+',
                             default=5)
@@ -178,7 +162,7 @@ class Poste_(Metadata):
 
     # Autres Metadata
     date_validation = models.DateTimeField(null=True, blank=True)   # de dae
 
     # Autres Metadata
     date_validation = models.DateTimeField(null=True, blank=True)   # de dae
-    date_debut = models.DateField(verbose_name="Date de début",
+    date_debut = models.DateField(verbose_name="Date de début", null=True,
                             help_text=HELP_TEXT_DATE)
     date_fin = models.DateField(verbose_name="Date de fin",
                             help_text=HELP_TEXT_DATE,
                             help_text=HELP_TEXT_DATE)
     date_fin = models.DateField(verbose_name="Date de fin",
                             help_text=HELP_TEXT_DATE,
@@ -207,6 +191,10 @@ class Poste(Poste_):
     __doc__ = Poste_.__doc__
 
 
     __doc__ = Poste_.__doc__
 
 
+class Poste(Poste_):
+    __doc__ = Poste_.__doc__
+
+
 POSTE_FINANCEMENT_CHOICES = (
     ('A', 'A - Frais de personnel'),
     ('B', 'B - Projet(s)-Titre(s)'),
 POSTE_FINANCEMENT_CHOICES = (
     ('A', 'A - Frais de personnel'),
     ('B', 'B - Projet(s)-Titre(s)'),
@@ -260,7 +248,7 @@ class PosteComparaison(models.Model):
     De la même manière qu'un dossier, un poste peut-être comparé à un autre poste.
     """
     poste = models.ForeignKey('Poste', related_name='comparaisons_internes')
     De la même manière qu'un dossier, un poste peut-être comparé à un autre poste.
     """
     poste = models.ForeignKey('Poste', related_name='comparaisons_internes')
-    implantation = models.ForeignKey(ref.Implantation, null=True, blank=True, related_name='+')
+    implantation = models.ForeignKey(ref.Implantation, null=True, blank=True, related_name="+")
     nom = models.CharField(verbose_name="Poste", max_length=255, null=True, blank=True)
     montant = models.IntegerField(null=True)
     devise = models.ForeignKey("Devise", default=5, related_name='+', null=True, blank=True)
     nom = models.CharField(verbose_name="Poste", max_length=255, null=True, blank=True)
     montant = models.IntegerField(null=True)
     devise = models.ForeignKey("Devise", default=5, related_name='+', null=True, blank=True)
@@ -283,7 +271,7 @@ SITUATION_CHOICES = (
     ('M', 'Marié'),
 )
 
     ('M', 'Marié'),
 )
 
-class Employe(Metadata):
+class Employe(AUFMetadata):
     """Personne occupant ou ayant occupé un Poste. Un Employe aura autant de 
     Dossiers qu'il occupe ou a occupé de Postes.
     
     """Personne occupant ou ayant occupé un Poste. Un Employe aura autant de 
     Dossiers qu'il occupe ou a occupé de Postes.
     
@@ -372,7 +360,7 @@ LIEN_PARENTE_CHOICES = (
     ('Fils', 'Fils'),
 )
 
     ('Fils', 'Fils'),
 )
 
-class AyantDroit(Metadata):
+class AyantDroit(AUFMetadata):
     """Personne en relation avec un Employe.
     """
     # Identification
     """Personne en relation avec un Employe.
     """
     # Identification
@@ -432,8 +420,7 @@ COMPTE_COMPTA_CHOICES = (
     ('aucun', 'Aucun'),
 )
 
     ('aucun', 'Aucun'),
 )
 
-
-class Dossier_(Metadata):
+class Dossier_(AUFMetadata):
     """Le Dossier regroupe les informations relatives à l'occupation
     d'un Poste par un Employe. Un seul Dossier existe par Poste occupé
     par un Employe.
     """Le Dossier regroupe les informations relatives à l'occupation
     d'un Poste par un Employe. Un seul Dossier existe par Poste occupé
     par un Employe.
@@ -446,9 +433,9 @@ class Dossier_(Metadata):
     employe = models.ForeignKey('Employe', db_column='employe', 
                             related_name='+',
                             verbose_name="Employé")
     employe = models.ForeignKey('Employe', db_column='employe', 
                             related_name='+',
                             verbose_name="Employé")
-    poste = models.ForeignKey('Poste', db_column='poste', 
-                            related_name='+', editable=False)
-    statut = models.ForeignKey('Statut', related_name='+', default=3)
+    poste = models.ForeignKey('Poste', db_column='poste', related_name='+')
+    statut = models.ForeignKey('Statut', related_name='+', default=3,
+                            null=True)
     organisme_bstg = models.ForeignKey('OrganismeBstg', 
                             db_column='organisme_bstg',
                             related_name='+',
     organisme_bstg = models.ForeignKey('OrganismeBstg', 
                             db_column='organisme_bstg',
                             related_name='+',
@@ -461,20 +448,20 @@ class Dossier_(Metadata):
     # Recrutement
     remplacement = models.BooleanField(default=False)
     statut_residence = models.CharField(max_length=10, default='local', 
     # Recrutement
     remplacement = models.BooleanField(default=False)
     statut_residence = models.CharField(max_length=10, default='local', 
-                            verbose_name="Statut",
+                            verbose_name="Statut", null=True,
                             choices=STATUT_RESIDENCE_CHOICES)
    
     # Rémunération
     classement = models.ForeignKey('Classement', db_column='classement', 
                             related_name='+',
                             null=True, blank=True)
                             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, 
+    regime_travail = models.DecimalField(max_digits=12, null=True,
                             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,
                             default=REGIME_TRAVAIL_DEFAULT,
                             verbose_name="Régime de travail",
                             help_text="% du temps complet")
     regime_travail_nb_heure_semaine = models.DecimalField(max_digits=12,
-                            decimal_places=2, 
+                            decimal_places=2, null=True,
                             default=REGIME_TRAVAIL_NB_HEURE_SEMAINE_DEFAULT,
                             verbose_name="Nb. heures par semaine")
 
                             default=REGIME_TRAVAIL_NB_HEURE_SEMAINE_DEFAULT,
                             verbose_name="Nb. heures par semaine")
 
@@ -507,6 +494,11 @@ class Dossier(Dossier_):
     __doc__ = Dossier_.__doc__
 
 
     __doc__ = Dossier_.__doc__
 
 
+
+class Dossier(Dossier_):
+    __doc__ = Dossier_.__doc__
+
+
 class DossierPiece(models.Model):
     """Documents relatifs au Dossier (à l'occupation de ce poste par employé).
     Ex.: Lettre de motivation.
 class DossierPiece(models.Model):
     """Documents relatifs au Dossier (à l'occupation de ce poste par employé).
     Ex.: Lettre de motivation.
@@ -531,7 +523,7 @@ class DossierCommentaire(Commentaire):
 
 ### RÉMUNÉRATION
     
 
 ### RÉMUNÉRATION
     
-class RemunerationMixin(Metadata):
+class RemunerationMixin(AUFMetadata):
     # Identification
     dossier = models.ForeignKey('Dossier', db_column='dossier',
                         related_name='%(app_label)s_%(class)s_remunerations')
     # Identification
     dossier = models.ForeignKey('Dossier', db_column='dossier',
                         related_name='%(app_label)s_%(class)s_remunerations')
@@ -602,12 +594,20 @@ class Remuneration(Remuneration_):
 
 
 ### CONTRATS
 
 
 ### CONTRATS
+
+class ContratManager(NoDeleteManager):
+    def get_query_set(self):
+        return super(ContratManager, self).get_query_set().select_related('dossier', 'dossier__poste')
+
         
         
-class Contrat(Metadata):
+class Contrat(AUFMetadata):
     """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.
     """
     """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.
     """
+
+    objects = ContratManager()
+
     dossier = models.ForeignKey('Dossier', db_column='dossier', 
                             related_name='+')
     type_contrat = models.ForeignKey('TypeContrat', db_column='type_contrat', 
     dossier = models.ForeignKey('Dossier', db_column='dossier', 
                             related_name='+')
     type_contrat = models.ForeignKey('TypeContrat', db_column='type_contrat', 
@@ -632,7 +632,7 @@ class Contrat(Metadata):
 
 ### ÉVÉNEMENTS
 
 
 ### ÉVÉNEMENTS
 
-class Evenement_(Metadata):
+class Evenement_(AUFMetadata):
     """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).
     """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).
@@ -688,10 +688,17 @@ class EvenementRemuneration_(RemunerationMixin):
 class EvenementRemuneration(EvenementRemuneration_):
     __doc__ = EvenementRemuneration_.__doc__
 
 class EvenementRemuneration(EvenementRemuneration_):
     __doc__ = EvenementRemuneration_.__doc__
 
+    class Meta:
+        abstract = True
+
+
+class EvenementRemuneration(EvenementRemuneration_):
+    __doc__ = EvenementRemuneration_.__doc__
+
 
 ### RÉFÉRENCES RH 
 
 
 ### RÉFÉRENCES RH 
 
-class FamilleEmploi(Metadata):
+class FamilleEmploi(AUFMetadata):
     """Catégorie utilisée dans la gestion des Postes.
     Catégorie supérieure à TypePoste.
     """
     """Catégorie utilisée dans la gestion des Postes.
     Catégorie supérieure à TypePoste.
     """
@@ -705,7 +712,7 @@ class FamilleEmploi(Metadata):
     def __unicode__(self):
         return u'%s' % (self.nom)
 
     def __unicode__(self):
         return u'%s' % (self.nom)
 
-class TypePoste(Metadata):
+class TypePoste(AUFMetadata):
     """Catégorie de Poste.
     """
     nom = models.CharField(max_length=255)
     """Catégorie de Poste.
     """
     nom = models.CharField(max_length=255)
@@ -741,7 +748,7 @@ NATURE_REMUNERATION_CHOICES = (
     ('Traitement', 'Traitement'),
 )
 
     ('Traitement', 'Traitement'),
 )
 
-class TypeRemuneration(Metadata):
+class TypeRemuneration(AUFMetadata):
     """Catégorie de Remuneration.
     """
     nom = models.CharField(max_length=255)
     """Catégorie de Remuneration.
     """
     nom = models.CharField(max_length=255)
@@ -760,7 +767,7 @@ class TypeRemuneration(Metadata):
     def __unicode__(self):
         return u'%s' % (self.nom)
         
     def __unicode__(self):
         return u'%s' % (self.nom)
         
-class TypeRevalorisation(Metadata):
+class TypeRevalorisation(AUFMetadata):
     """Justification du changement de la Remuneration.
     (Actuellement utilisé dans aucun traitement informatique.)
     """
     """Justification du changement de la Remuneration.
     (Actuellement utilisé dans aucun traitement informatique.)
     """
@@ -774,7 +781,7 @@ class TypeRevalorisation(Metadata):
     def __unicode__(self):
         return u'%s' % (self.nom)
     
     def __unicode__(self):
         return u'%s' % (self.nom)
     
-class Service(Metadata):
+class Service(AUFMetadata):
     """Unité administrative où les Postes sont rattachés.
     """
     nom = models.CharField(max_length=255)
     """Unité administrative où les Postes sont rattachés.
     """
     nom = models.CharField(max_length=255)
@@ -793,7 +800,7 @@ TYPE_ORGANISME_CHOICES = (
     ('DET', 'Détachement'),
 )
 
     ('DET', 'Détachement'),
 )
 
-class OrganismeBstg(Metadata):
+class OrganismeBstg(AUFMetadata):
     """Organisation d'où provient un Employe mis à disposition (MAD) de 
     ou détaché (DET) à l'AUF à titre gratuit.
     
     """Organisation d'où provient un Employe mis à disposition (MAD) de 
     ou détaché (DET) à l'AUF à titre gratuit.
     
@@ -814,7 +821,7 @@ class OrganismeBstg(Metadata):
     def __unicode__(self):
         return u'%s (%s)' % (self.nom, self.get_type_display())
 
     def __unicode__(self):
         return u'%s (%s)' % (self.nom, self.get_type_display())
 
-class Statut(Metadata):
+class Statut(AUFMetadata):
     """Statut de l'Employe dans le cadre d'un Dossier particulier.
     """
     # Identification
     """Statut de l'Employe dans le cadre d'un Dossier particulier.
     """
     # Identification
@@ -841,7 +848,7 @@ TYPE_CLASSEMENT_CHOICES = (
 )
 
 
 )
 
 
-class Classement_(Metadata):
+class Classement_(AUFMetadata):
     """Éléments de classement de la 
     "Grille générique de classement hiérarchique".
     
     """Éléments de classement de la 
     "Grille générique de classement hiérarchique".
     
@@ -854,7 +861,8 @@ class Classement_(Metadata):
     type = models.CharField(max_length=10, choices=TYPE_CLASSEMENT_CHOICES)
     echelon = models.IntegerField(verbose_name="Échelon")
     degre = models.IntegerField(verbose_name="Degré")
     type = models.CharField(max_length=10, choices=TYPE_CLASSEMENT_CHOICES)
     echelon = models.IntegerField(verbose_name="Échelon")
     degre = models.IntegerField(verbose_name="Degré")
-    coefficient = models.FloatField(default=0, verbose_name="Coéfficient")
+    coefficient = models.FloatField(default=0, verbose_name="Coéfficient",
+                                    null=True)
     # Méta
     # annee # au lieu de date_debut et date_fin
     commentaire = models.TextField(null=True, blank=True)
     # Méta
     # annee # au lieu de date_debut et date_fin
     commentaire = models.TextField(null=True, blank=True)
@@ -873,7 +881,7 @@ class Classement(Classement_):
     __doc__ = Classement_.__doc__
 
 
     __doc__ = Classement_.__doc__
 
 
-class TauxChange_(Metadata):
+class TauxChange_(AUFMetadata):
     """Taux de change de la devise vers l'euro (EUR) 
     pour chaque année budgétaire.
     """
     """Taux de change de la devise vers l'euro (EUR) 
     pour chaque année budgétaire.
     """
@@ -897,15 +905,15 @@ class TauxChange(TauxChange_):
     __doc__ = TauxChange_.__doc__
 
 
     __doc__ = TauxChange_.__doc__
 
 
-class ValeurPoint_(Metadata):
+class ValeurPoint_(AUFMetadata):
     """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).
 
     salaire de base = coefficient * valeur du point de l'Implantation du Poste
     """
     """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).
 
     salaire de base = coefficient * valeur du point de l'Implantation du Poste
     """
-    valeur = models.FloatField()
-    devise = models.ForeignKey('Devise', db_column='devise', 
+    valeur = models.FloatField(null=True)
+    devise = models.ForeignKey('Devise', db_column='devise', null=True,
                             related_name='+', default=5)
     implantation = models.ForeignKey(ref.Implantation, 
                             db_column='implantation',
                             related_name='+', default=5)
     implantation = models.ForeignKey(ref.Implantation, 
                             db_column='implantation',
@@ -914,11 +922,25 @@ class ValeurPoint_(Metadata):
     annee = models.IntegerField()
 
     class Meta:
     annee = models.IntegerField()
 
     class Meta:
+        ordering = ['annee', 'implantation__nom']
         abstract = True
         ordering = ['annee']
         verbose_name = "Valeur du point"
         verbose_name_plural = "Valeurs du point"
 
         abstract = True
         ordering = ['annee']
         verbose_name = "Valeur du point"
         verbose_name_plural = "Valeurs du point"
 
+    # TODO : cette fonction n'était pas présente dans la branche dev, utilité?
+    def get_tauxchange_courant(self):
+        """
+        Recherche le taux courant associé à la valeur d'un point.
+        Tous les taux de l'année courante sont chargés, pour optimiser un
+        affichage en liste. (On pourrait probablement améliorer le manager pour
+        lui greffer le taux courant sous forme de JOIN)
+        """
+        for tauxchange in self.tauxchange:
+            if tauxchange.implantation_id == self.implantation_id:
+                return tauxchange
+        return None
+
     def __unicode__(self):
         return u'%s %s (%s)' % (self.valeur, self.devise, self.annee)
 
     def __unicode__(self):
         return u'%s %s (%s)' % (self.valeur, self.devise, self.annee)
 
@@ -927,7 +949,7 @@ class ValeurPoint(ValeurPoint_):
     __doc__ = ValeurPoint_.__doc__
 
 
     __doc__ = ValeurPoint_.__doc__
 
 
-class Devise(Metadata):
+class Devise(AUFMetadata):
     """Devise monétaire.
     """
     code =  models.CharField(max_length=10, unique=True)
     """Devise monétaire.
     """
     code =  models.CharField(max_length=10, unique=True)
@@ -941,7 +963,7 @@ class Devise(Metadata):
     def __unicode__(self):
         return u'%s - %s' % (self.code, self.nom)
 
     def __unicode__(self):
         return u'%s - %s' % (self.code, self.nom)
 
-class TypeContrat(Metadata):
+class TypeContrat(AUFMetadata):
     """Type de contrat.
     """
     nom = models.CharField(max_length=255)
     """Type de contrat.
     """
     nom = models.CharField(max_length=255)
@@ -958,7 +980,7 @@ class TypeContrat(Metadata):
         
 ### AUTRES
 
         
 ### AUTRES
 
-class ResponsableImplantation(Metadata):
+class ResponsableImplantation(AUFMetadata):
     """Le responsable d'une implantation. 
     Anciennement géré sur le Dossier du responsable.
     """
     """Le responsable d'une implantation. 
     Anciennement géré sur le Dossier du responsable.
     """