From d6985a3a5bc08e8c0e8e74127125446967cf6a3a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Olivier=20Larchev=C3=AAque?= Date: Fri, 8 Jul 2011 11:12:44 -0400 Subject: [PATCH] plug metadata module #1544 --- buildout.cfg | 3 ++ project/rh/lib.py | 114 ++++++++++++++------------------------------------ project/rh/models.py | 92 +++++++++++----------------------------- 3 files changed, 59 insertions(+), 150 deletions(-) diff --git a/buildout.cfg b/buildout.cfg index 888d3e7..55d7aaa 100644 --- a/buildout.cfg +++ b/buildout.cfg @@ -9,6 +9,7 @@ find-links = http://pypi.auf.org/simple/auf.recipe.django/ http://pypi.auf.org/simple/auf.django.auth/ http://pypi.auf.org/simple/auf.django.workflow/ http://pypi.auf.org/simple/auf.django.admingroup/ + http://pypi.auf.org/simple/auf.django.metadata/ eggs = django @@ -22,6 +23,8 @@ eggs = django-reversion simplejson django-ajax-selects + auf.django.metadata + # LA PROD ne dispose que de reportlab 2.1, incompatible avec # les versions de pisa assez évoluées pour un bon rendu. # reportlab diff --git a/project/rh/lib.py b/project/rh/lib.py index 61c32e6..fc351c8 100644 --- a/project/rh/lib.py +++ b/project/rh/lib.py @@ -1,80 +1,44 @@ # -*- encoding: utf-8 -*- -import datetime from django.db import models from django.contrib import admin - +from auf.django.metadata.admin import AUFMetadataAdminMixin, AUFMetadataInlineAdminMixin, AUF_METADATA_READONLY_FIELDS from project.rh import models as rh -# MetaData -METADATA_READONLY_FIELDS = ('supprime', - 'date_creation', - 'user_creation', - 'date_modification', - 'user_modification', - 'date_activation', - 'user_activation', - 'date_desactivation', - 'user_desactivation', ) - -METADATA_FIELDSET_FIELDS = ('actif', 'date_creation', 'user_creation', - 'date_modification', 'user_modification', - 'date_activation', 'user_activation', - 'date_desactivation', 'user_desactivation',) - -class MetadataAdminMixin(object): - """ - Surcharge l'admin de base, pour setter automatiquement les metadata - """ - def save_model(self, request, obj, form, change): - if change is False: - obj.user_creation = request.user - obj.date_creation = datetime.datetime.now() - obj.user_modification = request.user - obj.date_modification = datetime.datetime.now() - if form.initial['actif'] is True and obj.actif is False: - obj.user_desactivation = request.user - obj.date_desactivation = datetime.datetime.now() - if form.initial['actif'] is False and obj.actif is True: - obj.user_activation = request.user - obj.date_activation = datetime.datetime.now() - obj.save() - -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 METADATA_READONLY_FIELDS] +# Inlines +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] -# Inlines -class AyantDroitInline(admin.TabularInline): - exclude = METADATA_READONLY_FIELDS + ('actif', ) +class AyantDroitInline(AUFMetadataInlineAdminMixin, admin.TabularInline): model = models.Model # à remplacer dans admin.py extra = 1 -class AyantDroitCommentaireInline(admin.TabularInline): - exclude = METADATA_READONLY_FIELDS + ('actif', ) + +class AyantDroitCommentaireInline(AUFMetadataInlineAdminMixin, admin.TabularInline): readonly_fields = ('owner', ) model = models.Model # à remplacer dans admin.py extra = 1 -class ContratInline(admin.TabularInline): +class ContratInline(AUFMetadataInlineAdminMixin, admin.TabularInline): model = models.Model # à remplacer dans admin.py - exclude = METADATA_READONLY_FIELDS + ('actif', ) extra = 1 -class DossierROInline(ReadonlyInlineMixin, admin.TabularInline): +class DossierROInline(ReadOnlyInlineMixin, admin.TabularInline): + exclude = AUF_METADATA_READONLY_FIELDS model = models.Model # à remplacer dans admin.py - exclude = METADATA_READONLY_FIELDS -class DossierCommentaireInline(admin.TabularInline, MetadataAdminMixin): - exclude = METADATA_READONLY_FIELDS + ('actif', ) + +class DossierCommentaireInline(AUFMetadataInlineAdminMixin, admin.TabularInline): readonly_fields = ('owner', ) model = models.Model # à remplacer dans admin.py extra = 1 + class DossierPieceInline(admin.TabularInline): model = models.Model # à remplacer dans admin.py @@ -82,9 +46,7 @@ class DossierPieceInline(admin.TabularInline): class EmployeInline(admin.TabularInline): model = models.Model # à remplacer dans admin.py - -class EmployeCommentaireInline(admin.TabularInline): - exclude = METADATA_READONLY_FIELDS + ('actif', ) +class EmployeCommentaireInline(AUFMetadataInlineAdminMixin, admin.TabularInline): readonly_fields = ('owner', ) model = models.Model # à remplacer dans admin.py extra = 1 @@ -94,15 +56,13 @@ class EmployePieceInline(admin.TabularInline): model = models.Model # à remplacer dans admin.py -class EvenementInline(admin.TabularInline, MetadataAdminMixin): +class EvenementInline(AUFMetadataInlineAdminMixin, admin.TabularInline): model = models.Model # à remplacer dans admin.py - exclude = METADATA_READONLY_FIELDS + ('actif', ) extra = 1 -class EvenementRemunerationInline(admin.TabularInline, MetadataAdminMixin): +class EvenementRemunerationInline(AUFMetadataInlineAdminMixin, admin.TabularInline): model = models.Model # à remplacer dans admin.py - exclude = METADATA_READONLY_FIELDS + ('actif', ) extra = 1 @@ -110,8 +70,7 @@ class PosteInline(admin.TabularInline): model = models.Model # à remplacer dans admin.py -class PosteCommentaireInline(admin.TabularInline): - exclude = METADATA_READONLY_FIELDS + ('actif', ) +class PosteCommentaireInline(AUFMetadataInlineAdminMixin, admin.TabularInline): readonly_fields = ('owner', ) model = models.Model # à remplacer dans admin.py extra = 1 @@ -125,13 +84,12 @@ class PostePieceInline(admin.TabularInline): model = models.Model # à remplacer dans admin.py -class RemunerationInline(admin.TabularInline): +class RemunerationInline(AUFMetadataInlineAdminMixin, admin.TabularInline): model = models.Model # à remplacer dans admin.py - exclude = METADATA_READONLY_FIELDS + ('actif', ) extra = 1 -class RemunerationROInline(ReadonlyInlineMixin, RemunerationInline): +class RemunerationROInline(ReadOnlyInlineMixin, RemunerationInline): pass @@ -141,19 +99,15 @@ class TypePosteInline(admin.TabularInline): # Admins -class AyantDroitAdmin(admin.ModelAdmin): +class AyantDroitAdmin(AUFMetadataAdminMixin, admin.ModelAdmin): """ L'ajout d'un nouvel ayantdroit se fait dans l'admin de l'employé. """ search_fields = ('nom', 'prenom', 'employe__nom', 'employe__prenom', ) list_display = ('_ayantdroit', '_employe', ) inlines = (AyantDroitCommentaireInline,) - readonly_fields = METADATA_READONLY_FIELDS + ('employe',) - fieldsets = ( - ('Metadata', { - 'classes': ('collapse',), - 'fields': METADATA_FIELDSET_FIELDS, - }), + readonly_fields = AUFMetadataAdminMixin.readonly_fields + ('employe',) + fieldsets = AUFMetadataAdminMixin.fieldsets + ( ("Lien avec l'employé", { 'fields': ('employe', 'lien_parente', ) }), @@ -164,6 +118,7 @@ class AyantDroitAdmin(admin.ModelAdmin): ) def save_formset(self, request, form, formset, change): + super(AyantDroitAdmin, self).save_formset(request, form, formset, change) instances = formset.save(commit=False) for instance in instances: if instance.__class__ == rh.AyantDroitCommentaire: @@ -202,7 +157,7 @@ class DeviseAdmin(admin.ModelAdmin): pass -class DossierAdmin(MetadataAdminMixin, admin.ModelAdmin,): +class DossierAdmin(AUFMetadataAdminMixin, admin.ModelAdmin,): search_fields = ('employe__nom', 'employe__prenom', ) list_display = ('_employe', '_poste', 'date_debut', 'date_fin', ) inlines = (DossierPieceInline, ContratInline, @@ -210,12 +165,7 @@ class DossierAdmin(MetadataAdminMixin, admin.ModelAdmin,): #EvenementInline, DossierCommentaireInline, ) - readonly_fields = METADATA_READONLY_FIELDS - fieldsets = ( - ('Metadata', { - 'classes': ('collapse',), - 'fields': METADATA_FIELDSET_FIELDS, - }), + fieldsets = AUFMetadataAdminMixin.fieldsets + ( ('Identification', { 'fields': ('employe', 'poste', 'statut', 'organisme_bstg',) }), @@ -239,6 +189,7 @@ class DossierAdmin(MetadataAdminMixin, admin.ModelAdmin,): _employe.short_description = u'Employé' def save_formset(self, request, form, formset, change): + super(DossierAdmin, self).save_formset(request, form, formset, change) instances = formset.save(commit=False) for instance in instances: if instance.__class__ == rh.DossierCommentaire: @@ -254,17 +205,13 @@ class DossierCommentaireAdmin(admin.ModelAdmin): pass -class EmployeAdmin(MetadataAdminMixin, admin.ModelAdmin): +class EmployeAdmin(AUFMetadataAdminMixin, admin.ModelAdmin): + search_fields = ('id', 'nom', 'prenom', 'nom_affichage', ) inlines = (AyantDroitInline, DossierROInline, EmployePieceInline, EmployeCommentaireInline) - readonly_fields = METADATA_READONLY_FIELDS - fieldsets = ( - ('Metadata', { - 'classes': ('collapse',), - 'fields': METADATA_FIELDSET_FIELDS, - }), + fieldsets = AUFMetadataAdminMixin.fieldsets + ( ('Identification', { 'fields': ('nom', 'prenom', 'nom_affichage', 'nationalite', 'date_naissance', 'genre', ) }), @@ -277,6 +224,7 @@ class EmployeAdmin(MetadataAdminMixin, admin.ModelAdmin): ) def save_formset(self, request, form, formset, change): + super(EmployeAdmin, self).save_formset(request, form, formset, change) instances = formset.save(commit=False) for instance in instances: if instance.__class__ == rh.EmployeCommentaire: diff --git a/project/rh/models.py b/project/rh/models.py index 10a3470..a410f9b 100644 --- a/project/rh/models.py +++ b/project/rh/models.py @@ -1,11 +1,10 @@ # -=- encoding: utf-8 -=- -import datetime - 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 @@ -28,47 +27,7 @@ def dossier_piece_dispatch(instance, filename): return path -class RHManager(models.Manager): - def get_query_set(self): - return super(RHManager, self).get_query_set().filter(supprime=False) - - -# Abstracts -class Metadata(models.Model): - """Méta-données AUF. - Metadata.actif = flag remplaçant la suppression. - supprime == True : objet réputé supprimé. - """ - supprime = models.BooleanField(default=False) - date_creation = models.DateField(null=True, blank=True) - user_creation = models.ForeignKey('auth.User', - db_column='user_creation', related_name='+', - null=True, blank=True) - date_modification = models.DateField(null=True, blank=True) - user_modification = models.ForeignKey('auth.User', - db_column='user_modification', related_name='+', - null=True, blank=True) - actif = models.BooleanField(default=True) - date_activation = models.DateField(null=True, blank=True) - user_activation = models.ForeignKey('auth.User', - db_column='user_activation', 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) - - objects = RHManager() - - class Meta: - abstract = True - - def delete(self): - self.supprime = True - self.save() - - -class Commentaire(Metadata): +class Commentaire(AUFMetadata): texte = models.TextField() owner = models.ForeignKey('auth.User', db_column='owner', related_name='+') @@ -87,12 +46,11 @@ POSTE_APPEL_CHOICES = ( ('externe', 'Externe'), ) - -class PosteManager(models.Manager): +class PosteManager(NoDeleteManager): def get_query_set(self): return super(PosteManager, self).get_query_set().select_related('implantation') -class Poste_(Metadata): +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. @@ -313,7 +271,7 @@ SITUATION_CHOICES = ( ('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. @@ -402,7 +360,7 @@ LIEN_PARENTE_CHOICES = ( ('Fils', 'Fils'), ) -class AyantDroit(Metadata): +class AyantDroit(AUFMetadata): """Personne en relation avec un Employe. """ # Identification @@ -462,7 +420,7 @@ COMPTE_COMPTA_CHOICES = ( ('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. @@ -565,7 +523,7 @@ class DossierCommentaire(Commentaire): ### 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') @@ -637,7 +595,7 @@ class Remuneration(Remuneration_): ### CONTRATS -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. @@ -666,7 +624,7 @@ class Contrat(Metadata): ### É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). @@ -732,7 +690,7 @@ class EvenementRemuneration(EvenementRemuneration_): ### RÉFÉRENCES RH -class FamilleEmploi(Metadata): +class FamilleEmploi(AUFMetadata): """Catégorie utilisée dans la gestion des Postes. Catégorie supérieure à TypePoste. """ @@ -746,7 +704,7 @@ class FamilleEmploi(Metadata): def __unicode__(self): return u'%s' % (self.nom) -class TypePoste(Metadata): +class TypePoste(AUFMetadata): """Catégorie de Poste. """ nom = models.CharField(max_length=255) @@ -782,7 +740,7 @@ NATURE_REMUNERATION_CHOICES = ( ('Traitement', 'Traitement'), ) -class TypeRemuneration(Metadata): +class TypeRemuneration(AUFMetadata): """Catégorie de Remuneration. """ nom = models.CharField(max_length=255) @@ -801,7 +759,7 @@ class TypeRemuneration(Metadata): 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.) """ @@ -815,7 +773,7 @@ class TypeRevalorisation(Metadata): 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) @@ -834,7 +792,7 @@ TYPE_ORGANISME_CHOICES = ( ('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. @@ -855,7 +813,7 @@ class OrganismeBstg(Metadata): 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 @@ -882,7 +840,7 @@ TYPE_CLASSEMENT_CHOICES = ( ) -class Classement_(Metadata): +class Classement_(AUFMetadata): """Éléments de classement de la "Grille générique de classement hiérarchique". @@ -915,7 +873,7 @@ class Classement(Classement_): __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. """ @@ -939,7 +897,7 @@ class TauxChange(TauxChange_): __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). @@ -983,7 +941,7 @@ class ValeurPoint(ValeurPoint_): __doc__ = ValeurPoint_.__doc__ -class Devise(Metadata): +class Devise(AUFMetadata): """Devise monétaire. """ code = models.CharField(max_length=10, unique=True) @@ -997,7 +955,7 @@ class Devise(Metadata): 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) @@ -1014,7 +972,7 @@ class TypeContrat(Metadata): ### AUTRES -class ResponsableImplantation(Metadata): +class ResponsableImplantation(AUFMetadata): """Le responsable d'une implantation. Anciennement géré sur le Dossier du responsable. """ -- 1.7.10.4