[#2658] Intégration de reversion à l'app rh
[auf_rh_dae.git] / project / rh / admin.py
index 8e10643..7fc424e 100644 (file)
@@ -4,12 +4,11 @@ import datetime
 
 import reversion
 from ajax_select import make_ajax_form
-from auf.django.metadata.admin import \
-        AUFMetadataAdminMixin, AUFMetadataInlineAdminMixin, \
-        AUF_METADATA_READONLY_FIELDS
 from auf.django.references import models as ref
+from django import forms
 from django.core.urlresolvers import reverse
 from django.contrib import admin
+from django.contrib.contenttypes.models import ContentType
 from django.conf import settings
 from django.db.models import Q, Count
 from django.template.defaultfilters import date
@@ -36,6 +35,8 @@ class BaseAdmin(admin.ModelAdmin):
         )
 
 
+# Admin pour reversion
+
 class ArchiveMixin(object):
     """
     Archive Mixin pour gérer le queryset et le display
@@ -155,16 +156,68 @@ class ProtectRegionMixin(object):
         return obj.id in ids
 
 
+class DerniereModificationAdmin(admin.ModelAdmin):
+
+    def queryset(self, request):
+        qs = super(DerniereModificationAdmin, self).queryset(request)
+        ct = ContentType.objects.get_for_model(self.model)
+        db_table = self.model._meta.db_table
+        pk = self.model._meta.pk.column
+        return qs.extra(select={
+            'date_modification':
+            "SELECT action_time FROM django_admin_log "
+            "WHERE content_type_id = %d AND object_id = %s.%s "
+            "ORDER BY action_time DESC "
+            "LIMIT 1" % (ct.id, db_table, pk),
+            'user_modification':
+            "SELECT u.username "
+            "FROM auth_user u "
+            "INNER JOIN django_admin_log l ON l.user_id = u.id "
+            "WHERE l.content_type_id = %d AND object_id = %s.%s "
+            "ORDER BY action_time DESC "
+            "LIMIT 1" % (ct.id, db_table, pk),
+        })
+
+    def derniere_modification(self, obj):
+        text = ''
+        if obj.date_modification:
+            text += obj.date_modification.strftime('%d-%m-%Y %H:%M')
+        if obj.user_modification:
+            text += ' par ' + obj.user_modification
+        return text
+    derniere_modification.short_description = u'dernière modification'
+    derniere_modification.admin_order_field = 'date_modification'
+
+
 # Inlines
 
+class CommentaireInlineForm(forms.ModelForm):
+
+    def save(self, commit=True):
+
+        # Hack: reversion.VersionAdmin ne sauvegarde pas les champs qui ne
+        # sont pas explicitement dans le formulaire. Il plante cependant
+        # leur valeur dans `self.initial`. Ceci est un peu fragile. Si
+        # c'est possible, il serait plus approprié que Reversion se rende
+        # compte qu'il manque des champs.
+        instance = super(CommentaireInlineForm, self).save(commit=False)
+        if instance.owner_id is None and 'owner' in self.initial:
+            instance.owner_id = self.initial['owner']
+        if instance.date_creation is None and 'date_creation' in self.initial:
+            instance.date_creation = self.initial['date_creation']
+        if commit:
+            instance.save()
+            self.save_m2m()
+        return instance
+
+
 class ReadOnlyInlineMixin(object):
 
     def get_readonly_fields(self, request, obj=None):
-        return [f.name for f in self.model._meta.fields \
-                if f.name not in AUF_METADATA_READONLY_FIELDS]
+        return [f.name for f in self.model._meta.fields]
 
 
-class AyantDroitInline(AUFMetadataInlineAdminMixin, admin.StackedInline):
+class AyantDroitInline(admin.StackedInline):
     model = rh.AyantDroit
     form = AyantDroitForm
     extra = 0
@@ -181,14 +234,14 @@ class AyantDroitInline(AUFMetadataInlineAdminMixin, admin.StackedInline):
     )
 
 
-class AyantDroitCommentaireInline(AUFMetadataInlineAdminMixin, \
-        admin.TabularInline):
-    readonly_fields = ('owner', )
+class AyantDroitCommentaireInline(admin.TabularInline):
+    readonly_fields = ('owner',)
     model = rh.AyantDroitCommentaire
     extra = 1
+    form = CommentaireInlineForm
 
 
-class ContratInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
+class ContratInline(admin.TabularInline):
     form = ContratForm
     model = rh.Contrat
     extra = 1
@@ -196,7 +249,6 @@ class ContratInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
 
 class DossierROInline(ReadOnlyInlineMixin, LinkedInline):
     template = "admin/rh/dossier/linked.html"
-    exclude = AUF_METADATA_READONLY_FIELDS
     model = rh.Dossier
     extra = 0
     can_delete = False
@@ -211,11 +263,11 @@ class DossierROInline(ReadOnlyInlineMixin, LinkedInline):
         return False
 
 
-class DossierCommentaireInline(AUFMetadataInlineAdminMixin, \
-        admin.TabularInline):
-    readonly_fields = ('owner', )
+class DossierCommentaireInline(admin.TabularInline):
+    readonly_fields = ('owner',)
     model = rh.DossierCommentaire
     extra = 1
+    form = CommentaireInlineForm
 
 
 class DossierPieceInline(admin.TabularInline):
@@ -227,11 +279,11 @@ class EmployeInline(admin.TabularInline):
     model = rh.Employe
 
 
-class EmployeCommentaireInline(AUFMetadataInlineAdminMixin, \
-        admin.TabularInline):
-    readonly_fields = ('owner', )
+class EmployeCommentaireInline(admin.TabularInline):
+    readonly_fields = ('owner',)
     model = rh.EmployeCommentaire
     extra = 1
+    form = CommentaireInlineForm
 
 
 class EmployePieceInline(admin.TabularInline):
@@ -239,10 +291,11 @@ class EmployePieceInline(admin.TabularInline):
     extra = 4
 
 
-class PosteCommentaireInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
-    readonly_fields = ('owner', )
+class PosteCommentaireInline(admin.TabularInline):
+    readonly_fields = ('owner',)
     model = rh.PosteCommentaire
     extra = 1
+    form = CommentaireInlineForm
 
 
 class PosteFinancementInline(admin.TabularInline):
@@ -253,7 +306,7 @@ class PostePieceInline(admin.TabularInline):
     model = rh.PostePiece
 
 
-class RemunerationInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
+class RemunerationInline(admin.TabularInline):
     model = rh.Remuneration
     extra = 1
 
@@ -262,63 +315,42 @@ class RemunerationROInline(ReadOnlyInlineMixin, RemunerationInline):
     pass
 
 
-class TypePosteInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
+class TypePosteInline(admin.TabularInline):
     model = rh.TypePoste
 
 
-class PosteComparaisonInline(AUFMetadataInlineAdminMixin, admin.TabularInline):
+class PosteComparaisonInline(admin.TabularInline):
     model = rh.PosteComparaison
 
 
-class ClassementAdmin(AUFMetadataAdminMixin, BaseAdmin,
-                      reversion.VersionAdmin):
-    list_display = ('_classement', '_date_modification', 'user_modification', )
-    fieldsets = AUFMetadataAdminMixin.fieldsets + (
-        (None, {
-            'fields': ('type', 'echelon', 'degre', 'coefficient',)}),
+class ClassementAdmin(reversion.VersionAdmin, DerniereModificationAdmin,
+                      BaseAdmin):
+    ignore_duplicate_revisions = True
+    list_display = ('_classement', 'derniere_modification')
+    fieldsets = (
+        (None, {'fields': ('type', 'echelon', 'degre', 'coefficient',)}),
     )
 
     def _classement(self, obj):
         return unicode(obj)
     _classement.short_description = u"Classement"
 
-    def _date_modification(self, obj):
-        return date(obj.date_modification) \
-                if obj.date_modification is not None else "(aucune)"
-    _date_modification.short_description = u'date modification'
-    _date_modification.admin_order_field = 'date_modification'
-
-
-class CommentaireAdmin(reversion.VersionAdmin, BaseAdmin):
-    pass
-
 
-class DeviseAdmin(AUFMetadataAdminMixin, reversion.VersionAdmin,
-                  ArchiveMixin, BaseAdmin):
+class DeviseAdmin(reversion.VersionAdmin, ArchiveMixin,
+                  DerniereModificationAdmin, BaseAdmin):
+    ignore_duplicate_revisions = True
     list_display = (
-            'code',
-            'nom',
-            '_archive',
-            '_date_modification',
-            'user_modification',
-            )
+        'code', 'nom', '_archive', 'derniere_modification',
+    )
     list_filter = ('archive', )
-    fieldsets = AUFMetadataAdminMixin.fieldsets + (
-        (None, {
-            'fields': ('code', 'nom', 'archive', ),
-        }),
+    fieldsets = (
+        (None, {'fields': ('code', 'nom', 'archive', )}),
     )
 
-    def _date_modification(self, obj):
-        return date(obj.date_modification) \
-                if obj.date_modification is not None else "(aucune)"
-    _date_modification.short_description = u'date modification'
-    _date_modification.admin_order_field = 'date_modification'
-
 
-class DossierAdmin(DateRangeMixin, AUFMetadataAdminMixin,
-                   ProtectRegionMixin, BaseAdmin, AjaxSelect,
-                   reversion.VersionAdmin):
+class DossierAdmin(DateRangeMixin, ProtectRegionMixin, reversion.VersionAdmin,
+                   AjaxSelect, DerniereModificationAdmin, BaseAdmin):
+    ignore_duplicate_revisions = True
     alphabet_filter = 'employe__nom'
     search_fields = (
         'id',
@@ -338,8 +370,7 @@ class DossierAdmin(DateRangeMixin, AUFMetadataAdminMixin,
         '_employe',
         '_date_debut',
         '_date_fin',
-        '_date_modification',
-        'user_modification',
+        'derniere_modification',
         '_dae',
     )
     list_display_links = ('_nom',)
@@ -355,7 +386,7 @@ class DossierAdmin(DateRangeMixin, AUFMetadataAdminMixin,
                RemunerationInline,
                DossierCommentaireInline,
               )
-    fieldsets = AUFMetadataAdminMixin.fieldsets + (
+    fieldsets = (
         (None, {
             'fields': (
                 'employe',
@@ -449,12 +480,6 @@ class DossierAdmin(DateRangeMixin, AUFMetadataAdminMixin,
     _date_fin.short_description = u'Occupation fin'
     _date_fin.admin_order_field = 'date_fin'
 
-    def _date_modification(self, obj):
-        return date(obj.date_modification) \
-                if obj.date_modification is not None else "(aucune)"
-    _date_modification.short_description = u'date modification'
-    _date_modification.admin_order_field = 'date_modification'
-
     def _poste(self, dossier):
         link = u"""<a title="Aperçu du poste"
                       onclick="return showAddAnotherPopup(this);"
@@ -497,8 +522,8 @@ class DossierAdmin(DateRangeMixin, AUFMetadataAdminMixin,
             instance.save()
 
 
-class EmployeAdminMixin(DateRangeMixin, AUFMetadataAdminMixin,
-                        ProtectRegionMixin, BaseAdmin):
+class EmployeAdminBase(DateRangeMixin, ProtectRegionMixin,
+                       DerniereModificationAdmin, BaseAdmin):
     prefixe_recherche_temporelle = "rh_dossiers__"
     alphabet_filter = 'nom'
     DEFAULT_ALPHABET = u'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
@@ -510,36 +535,30 @@ class EmployeAdminMixin(DateRangeMixin, AUFMetadataAdminMixin,
     ordering = ('nom', )
     form = EmployeAdminForm
     list_display = (
-            '_id',
-            '_apercu',
-            '_nom',
-            '_dossiers_postes',
-            'date_entree',
-            '_date_modification',
-            'user_modification',
-            )
+        '_id', '_apercu', '_nom', '_dossiers_postes', 'date_entree',
+        'derniere_modification'
+    )
     list_display_links = ('_nom',)
     list_filter = (
-            'rh_dossiers__poste__implantation__region',
-            'rh_dossiers__poste__implantation',
-            'nb_postes',
-            )
-    inlines = (AyantDroitInline,
-               DossierROInline,
-               EmployePieceInline,
-               EmployeCommentaireInline)
-    fieldsets = AUFMetadataAdminMixin.fieldsets + (
+        'rh_dossiers__poste__implantation__region',
+        'rh_dossiers__poste__implantation', 'nb_postes'
+    )
+    inlines = (
+        AyantDroitInline, DossierROInline, EmployePieceInline,
+        EmployeCommentaireInline
+    )
+    fieldsets = (
         ('Identification', {
             'fields': (
                 ('nom', 'prenom'),
                 ('nom_affichage', 'genre'),
                 'nationalite',
                 'date_naissance',
-                )}
-            ),
+            )
+        }),
         ('Informations personnelles', {
-            'fields': ('situation_famille', 'date_entree', )}
-            ),
+            'fields': ('situation_famille', 'date_entree', )
+        }),
         ('Coordonnées personnelles', {
             'fields': (
                 ('tel_domicile', 'tel_cellulaire'),
@@ -547,9 +566,9 @@ class EmployeAdminMixin(DateRangeMixin, AUFMetadataAdminMixin,
                 ('code_postal', 'province'),
                 'pays',
                 'courriel_perso'
-                )}
-            ),
-        )
+            )
+        }),
+    )
 
     def _apercu(self, obj):
         return u"""<a title="Aperçu de l'employé"
@@ -627,7 +646,7 @@ class EmployeAdminMixin(DateRangeMixin, AUFMetadataAdminMixin,
     _dossiers_postes.short_description = u"Dossiers et postes"
 
     def queryset(self, request):
-        qs = super(EmployeAdmin, self).queryset(request)
+        qs = super(EmployeAdminBase, self).queryset(request)
         return qs.select_related(depth=1).order_by('nom')
 
     def save_formset(self, request, form, formset, change):
@@ -639,11 +658,11 @@ class EmployeAdminMixin(DateRangeMixin, AUFMetadataAdminMixin,
             instance.save()
 
 
-class EmployeAdmin(reversion.VersionAdmin, EmployeAdminMixin):
-    pass
+class EmployeAdmin(reversion.VersionAdmin, EmployeAdminBase):
+    ignore_duplicate_revisions = True
 
 
-class EmployeProxyAdmin(admin.ModelAdmin, EmployeAdminMixin):
+class EmployeProxyAdmin(EmployeAdminBase):
     list_display = ('_id', '_apercu', '_nom', '_organigramme')
     actions = None
 
@@ -685,45 +704,31 @@ class EmployeProxyAdmin(admin.ModelAdmin, EmployeAdminMixin):
     _organigramme.short_description = "Organigramme"
 
 
-class CategorieEmploiAdmin(AUFMetadataAdminMixin, reversion.VersionAdmin,
-                           BaseAdmin):
-    list_display = ('nom', '_date_modification', 'user_modification', )
+class CategorieEmploiAdmin(reversion.VersionAdmin,
+                           DerniereModificationAdmin, BaseAdmin):
+    ignore_duplicate_revisions = True
+    list_display = ('nom', 'derniere_modification')
     inlines = (TypePosteInline,)
-    fieldsets = AUFMetadataAdminMixin.fieldsets + (
-        (None, {'fields': ('nom', )}),)
-
-    def _date_modification(self, obj):
-        return date(obj.date_modification) \
-                if obj.date_modification is not None else "(aucune)"
-    _date_modification.short_description = u'date modification'
-    _date_modification.admin_order_field = 'date_modification'
+    fieldsets = (
+        (None, {'fields': ('nom', )}),
+    )
 
 
-class OrganismeBstgAdmin(AUFMetadataAdminMixin, reversion.VersionAdmin,
+class OrganismeBstgAdmin(reversion.VersionAdmin, DerniereModificationAdmin,
                          BaseAdmin):
+    ignore_duplicate_revisions = True
     search_fields = ('nom',)
-    list_display = (
-            'nom',
-            'type',
-            'pays',
-            '_date_modification',
-            'user_modification',
-            )
+    list_display = ('nom', 'type', 'pays', 'derniere_modification')
     list_filter = ('type', )
     inlines = (DossierROInline,)
-    fieldsets = AUFMetadataAdminMixin.fieldsets + (
+    fieldsets = (
         (None, {'fields': ('nom', 'type', 'pays',)}),
-        )
-
-    def _date_modification(self, obj):
-        return date(obj.date_modification) \
-                if obj.date_modification is not None else "(aucune)"
-    _date_modification.short_description = u'date modification'
-    _date_modification.admin_order_field = 'date_modification'
+    )
 
 
-class PosteAdmin(DateRangeMixin, AUFMetadataAdminMixin, ProtectRegionMixin,
-                 reversion.VersionAdmin, AjaxSelect, BaseAdmin):
+class PosteAdmin(DateRangeMixin, ProtectRegionMixin, reversion.VersionAdmin,
+                 AjaxSelect, DerniereModificationAdmin, BaseAdmin):
+    ignore_duplicate_revisions = True
     form = make_ajax_form(rh.Poste, {
         'implantation': 'implantations',
         'type_poste': 'typepostes',
@@ -733,29 +738,20 @@ class PosteAdmin(DateRangeMixin, AUFMetadataAdminMixin, ProtectRegionMixin,
     })
     alphabet_filter = 'nom'
     search_fields = (
-            'id',
-            'nom',
-            'implantation__nom',
-            'implantation__region__code',
-            'implantation__region__nom',
-            'rh_dossiers__employe__id',
-            'rh_dossiers__employe__nom',
-            'rh_dossiers__employe__prenom',
-            )
+        'id',
+        'nom',
+        'implantation__nom',
+        'implantation__region__code',
+        'implantation__region__nom',
+        'rh_dossiers__employe__id',
+        'rh_dossiers__employe__nom',
+        'rh_dossiers__employe__prenom',
+    )
     list_display = (
-        '_id',
-        '_apercu',
-        '_nom',
-        '_occupe_par',
-        '_implantation',
-        '_service',
-        '_responsable',
-        'date_debut',
-        'date_fin',
-        '_date_modification',
-        'user_modification',
-        '_dae',
-        )
+        '_id', '_apercu', '_nom', '_occupe_par', 'implantation', '_service',
+        '_responsable', 'date_debut', 'date_fin', 'derniere_modification',
+        '_dae'
+    )
     list_filter = (
         'implantation__region',
         'implantation',
@@ -764,9 +760,9 @@ class PosteAdmin(DateRangeMixin, AUFMetadataAdminMixin, ProtectRegionMixin,
         'type_poste__categorie_emploi',
         'type_poste__famille_professionnelle',
         'vacant',
-        )
+    )
     list_display_links = ('_nom',)
-    fieldsets = AUFMetadataAdminMixin.fieldsets + (
+    fieldsets = (
         (None, {'fields': (
                 ('nom', 'nom_feminin'),
                 'implantation',
@@ -862,10 +858,7 @@ class PosteAdmin(DateRangeMixin, AUFMetadataAdminMixin, ProtectRegionMixin,
     _id.admin_order_field = 'id'
 
     def _service(self, obj):
-        if obj.service.supprime:
-            return """<span style="color:red">%s</span>""" % obj.service
-        else:
-            return obj.service
+        return obj.service
     _service.short_description = 'Service'
     _service.allow_tags = True
 
@@ -920,11 +913,6 @@ class PosteAdmin(DateRangeMixin, AUFMetadataAdminMixin, ProtectRegionMixin,
     _nom.short_description = u'Poste'
     _nom.admin_order_field = 'nom'
 
-    def _date_modification(self, obj):
-        return date(obj.date_modification)
-    _date_modification.short_description = u'date modification'
-    _date_modification.admin_order_field = 'date_modification'
-
     def _occupe_par(self, obj):
         """Formatte la méthode Poste.occupe_par() pour l'admin"""
         output = u"Vacant"
@@ -1022,32 +1010,19 @@ class ResponsableImplantationAdmin(BaseAdmin):
         return False
 
 
-class ServiceAdminMixin(AUFMetadataAdminMixin, ArchiveMixin, BaseAdmin):
-    list_display = (
-            'nom',
-            '_archive',
-            '_date_modification',
-            'user_modification',
-            )
+class ServiceAdminBase(ArchiveMixin, DerniereModificationAdmin, BaseAdmin):
+    list_display = ('nom', '_archive', 'derniere_modification')
     list_filter = ('archive', )
-    fieldsets = AUFMetadataAdminMixin.fieldsets + (
-        (None, {
-            'fields': ('nom', 'archive', ),
-        }),
-        )
-
-    def _date_modification(self, obj):
-        return date(obj.date_modification) \
-                if obj.date_modification is not None else "(aucune)"
-    _date_modification.short_description = u'date modification'
-    _date_modification.admin_order_field = 'date_modification'
+    fieldsets = (
+        (None, {'fields': ('nom', 'archive')}),
+    )
 
 
-class ServiceAdmin(reversion.VersionAdmin, ServiceAdminMixin):
-    pass
+class ServiceAdmin(reversion.VersionAdmin, ServiceAdminBase):
+    ignore_duplicate_revisions = True
 
 
-class ServiceProxyAdmin(admin.ModelAdmin, ServiceAdminMixin):
+class ServiceProxyAdmin(ServiceAdminBase):
     list_display = ('nom', '_organigramme', '_archive', )
     actions = None
 
@@ -1073,149 +1048,93 @@ class ServiceProxyAdmin(admin.ModelAdmin, ServiceAdminMixin):
     _organigramme.short_description = "Organigramme"
 
 
-class StatutAdmin(AUFMetadataAdminMixin, reversion.VersionAdmin, BaseAdmin):
-    list_display = ('code', 'nom', '_date_modification', 'user_modification', )
-    fieldsets = AUFMetadataAdminMixin.fieldsets + (
+class StatutAdmin(reversion.VersionAdmin, DerniereModificationAdmin,
+                  BaseAdmin):
+    ignore_duplicate_revisions = True
+    list_display = ('code', 'nom', 'derniere_modification')
+    fieldsets = (
         (None, {
             'fields': ('code', 'nom', ),
         }),
-        )
-
-    def _date_modification(self, obj):
-        return date(obj.date_modification) \
-                if obj.date_modification is not None else "(aucune)"
-    _date_modification.short_description = u'date modification'
-    _date_modification.admin_order_field = 'date_modification'
+    )
 
 
-class TauxChangeAdmin(reversion.VersionAdmin, BaseAdmin):
-    list_display = (
-            'taux',
-            'devise',
-            'annee',
-            '_date_modification',
-            'user_modification',
-            )
-    list_filter = ('devise', )
-    fieldsets = AUFMetadataAdminMixin.fieldsets + (
+class TauxChangeAdmin(reversion.VersionAdmin, DerniereModificationAdmin,
+                      BaseAdmin):
+    ignore_duplicate_revisions = True
+    list_display = ('taux', 'devise', 'annee', 'derniere_modification')
+    list_filter = ('devise',)
+    fieldsets = (
         (None, {
             'fields': ('taux', 'devise', 'annee', ),
         }),
-        )
-
-    def _date_modification(self, obj):
-        return date(obj.date_modification) \
-                if obj.date_modification is not None else "(aucune)"
-    _date_modification.short_description = u'date modification'
-    _date_modification.admin_order_field = 'date_modification'
+    )
 
 
-class TypeContratAdmin(reversion.VersionAdmin, BaseAdmin):
-    list_display = (
-            'nom',
-            'nom_long',
-            '_date_modification',
-            'user_modification',
-            )
-    fieldsets = AUFMetadataAdminMixin.fieldsets + (
+class TypeContratAdmin(reversion.VersionAdmin, DerniereModificationAdmin,
+                       BaseAdmin):
+    ignore_duplicate_revisions = True
+    list_display = ('nom', 'nom_long', 'derniere_modification')
+    fieldsets = (
         (None, {
             'fields': ('nom', 'nom_long', ),
         }),
-        )
-
-    def _date_modification(self, obj):
-        return date(obj.date_modification) \
-                if obj.date_modification is not None else "(aucune)"
-    _date_modification.short_description = u'date modification'
-    _date_modification.admin_order_field = 'date_modification'
+    )
 
 
-class TypePosteAdmin(AUFMetadataAdminMixin, reversion.VersionAdmin,
+class TypePosteAdmin(reversion.VersionAdmin, DerniereModificationAdmin,
                      BaseAdmin):
+    ignore_duplicate_revisions = True
     search_fields = ('nom', 'nom_feminin', )
-    list_display = (
-            'nom',
-            'categorie_emploi',
-            '_date_modification',
-            'user_modification',
-            )
+    list_display = ('nom', 'categorie_emploi', 'derniere_modification')
     list_filter = ('categorie_emploi', 'famille_professionnelle')
-    fieldsets = AUFMetadataAdminMixin.fieldsets + (
+    fieldsets = (
         (None, {
             'fields': (
-                'nom',
-                'nom_feminin',
-                'is_responsable',
-                'categorie_emploi',
+                'nom', 'nom_feminin', 'is_responsable', 'categorie_emploi',
                 'famille_professionnelle',
-                )}
-            ),
-        )
-
-    def _date_modification(self, obj):
-        return date(obj.date_modification) \
-                if obj.date_modification is not None else "(aucune)"
-    _date_modification.short_description = u'date modification'
-    _date_modification.admin_order_field = 'date_modification'
+            )
+        }),
+    )
 
 
-class TypeRemunerationAdmin(AUFMetadataAdminMixin, reversion.VersionAdmin,
-                            ArchiveMixin, BaseAdmin):
+class TypeRemunerationAdmin(reversion.VersionAdmin, ArchiveMixin,
+                            DerniereModificationAdmin, BaseAdmin):
+    ignore_duplicate_revisions = True
     list_display = (
-            'nom',
-            'type_paiement',
-            'nature_remuneration',
-            '_archive',
-            '_date_modification',
-            'user_modification',)
+        'nom', 'type_paiement', 'nature_remuneration', '_archive',
+        'derniere_modification'
+    )
     list_filter = ('archive', )
-    fieldsets = AUFMetadataAdminMixin.fieldsets + (
-        (None, {'fields': ('nom', 'type_paiement', 'nature_remuneration',
-        'archive')}),
-        )
-
-    def _date_modification(self, obj):
-        return date(obj.date_modification) \
-                if obj.date_modification is not None else "(aucune)"
-    _date_modification.short_description = u'date modification'
-    _date_modification.admin_order_field = 'date_modification'
-
+    fieldsets = (
+        (None, {
+            'fields': (
+                'nom', 'type_paiement', 'nature_remuneration', 'archive'
+            )
+        }),
+    )
 
-class TypeRevalorisationAdmin(AUFMetadataAdminMixin, reversion.VersionAdmin,
-                              BaseAdmin):
-    list_display = ('nom', '_date_modification', 'user_modification', )
-    fieldsets = AUFMetadataAdminMixin.fieldsets + (
-        (None, {'fields': ('nom', )}),
-        )
 
-    def _date_modification(self, obj):
-        return date(obj.date_modification) \
-                if obj.date_modification is not None else "(aucune)"
-    _date_modification.short_description = u'date modification'
-    _date_modification.admin_order_field = 'date_modification'
+class TypeRevalorisationAdmin(reversion.VersionAdmin,
+                              DerniereModificationAdmin, BaseAdmin):
+    ignore_duplicate_revisions = True
+    list_display = ('nom', 'derniere_modification')
+    fieldsets = (
+        (None, {'fields': ('nom',)}),
+    )
 
 
-class ValeurPointAdmin(AUFMetadataAdminMixin, reversion.VersionAdmin,
+class ValeurPointAdmin(reversion.VersionAdmin, DerniereModificationAdmin,
                        BaseAdmin):
+    ignore_duplicate_revisions = True
     list_display = (
-            '_devise_code',
-            '_devise_nom',
-            'annee',
-            'implantation',
-            'valeur',
-            '_date_modification',
-            'user_modification',
-            )
+        '_devise_code', '_devise_nom', 'annee', 'implantation',
+        'valeur', 'derniere_modification'
+    )
     list_filter = ('annee', 'devise', 'implantation__region', )
-    fieldsets = AUFMetadataAdminMixin.fieldsets + (
-        (None, {'fields': ('valeur', 'devise', 'implantation', 'annee', )}),
-        )
-
-    def _date_modification(self, obj):
-        return date(obj.date_modification) \
-                if obj.date_modification is not None else "(aucune)"
-    _date_modification.short_description = u'date modification'
-    _date_modification.admin_order_field = 'date_modification'
+    fieldsets = (
+        (None, {'fields': ('valeur', 'devise', 'implantation', 'annee')}),
+    )
 
     def _devise_code(self, obj):
         return obj.devise.code