X-Git-Url: http://git.auf.org/?p=auf_rh_dae.git;a=blobdiff_plain;f=project%2Frh%2Fmodels.py;h=e5bcfd450df3bac2bf851b82c8c01238c85282cd;hp=1cf38d0bd3cea382b39aa3df9f0299f2ff728fcb;hb=c41b7fcceb16fdd98d7f41f7ef88e3c714422988;hpb=15ea717e2cea0beec769050a05bacf6c13a4790e diff --git a/project/rh/models.py b/project/rh/models.py index 1cf38d0..e5bcfd4 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 @@ -27,31 +26,8 @@ def dossier_piece_dispatch(instance, filename): path = "dossier/%s/%s" % (instance.dossier_id, filename) return path -# Abstracts -class Metadata(models.Model): - """Méta-données AUF. - Metadata.actif = flag remplaçant la suppression. - supprime == True : objet réputé supprimé. - """ - actif = models.BooleanField(default=True) - supprime = models.BooleanField(default=False) - date_creation = models.DateField(auto_now_add=True) - user_creation = models.ForeignKey('auth.User', - db_column='user_creation', related_name='+', - null=True, blank=True) - date_modification = models.DateField(auto_now=True) - user_modification = models.ForeignKey('auth.User', - db_column='user_modification', related_name='+', - null=True, blank=True) - date_desactivation = models.DateField(null=True, blank=True) - user_desactivation = models.ForeignKey('auth.User', - db_column='user_desactivation', related_name='+', - null=True, blank=True) - - class Meta: - abstract = True -class Commentaire(Metadata): +class Commentaire(AUFMetadata): texte = models.TextField() owner = models.ForeignKey('auth.User', db_column='owner', related_name='+') @@ -70,11 +46,18 @@ POSTE_APPEL_CHOICES = ( ('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. """ + + objects = PosteManager() + # Identification nom = models.CharField(max_length=255, verbose_name="Titre du poste", ) @@ -86,34 +69,34 @@ class Poste_(Metadata): 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='+', + related_name='+', null=True, 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, - decimal_places=2, + decimal_places=2, null=True, 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", - 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') @@ -131,25 +114,25 @@ class Poste_(Metadata): 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) - 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, - default=0) + null=True, default=0) 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, - default=0) + null=True, default=0) 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, - default=0) + null=True, default=0) autre_max = models.DecimalField(max_digits=12, decimal_places=2, - default=0) + null=True, default=0) # 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) @@ -179,7 +162,7 @@ class Poste_(Metadata): # 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, @@ -260,6 +243,18 @@ class PostePiece(models.Model): def __unicode__(self): return u'%s' % (self.nom) +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') + 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) + montant_euros = models.IntegerField(null=True) + + class PosteCommentaire(Commentaire): poste = models.ForeignKey('Poste', db_column='poste', related_name='+') @@ -276,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. @@ -365,7 +360,7 @@ LIEN_PARENTE_CHOICES = ( ('Fils', 'Fils'), ) -class AyantDroit(Metadata): +class AyantDroit(AUFMetadata): """Personne en relation avec un Employe. """ # Identification @@ -425,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. @@ -438,9 +433,9 @@ class Dossier_(Metadata): 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='+', @@ -453,20 +448,20 @@ class Dossier_(Metadata): # 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) - 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, + decimal_places=2, null=True, default=REGIME_TRAVAIL_NB_HEURE_SEMAINE_DEFAULT, verbose_name="Nb. heures par semaine") @@ -528,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') @@ -599,12 +594,20 @@ class Remuneration(Remuneration_): ### 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. """ + + objects = ContratManager() + dossier = models.ForeignKey('Dossier', db_column='dossier', related_name='+') type_contrat = models.ForeignKey('TypeContrat', db_column='type_contrat', @@ -629,7 +632,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). @@ -695,7 +698,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. """ @@ -709,7 +712,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) @@ -745,7 +748,7 @@ NATURE_REMUNERATION_CHOICES = ( ('Traitement', 'Traitement'), ) -class TypeRemuneration(Metadata): +class TypeRemuneration(AUFMetadata): """Catégorie de Remuneration. """ nom = models.CharField(max_length=255) @@ -764,7 +767,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.) """ @@ -778,7 +781,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) @@ -797,7 +800,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. @@ -818,7 +821,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 @@ -845,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". @@ -858,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é") - 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) @@ -877,7 +881,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. """ @@ -901,15 +905,15 @@ 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). 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', @@ -945,7 +949,7 @@ class ValeurPoint(ValeurPoint_): __doc__ = ValeurPoint_.__doc__ -class Devise(Metadata): +class Devise(AUFMetadata): """Devise monétaire. """ code = models.CharField(max_length=10, unique=True) @@ -959,7 +963,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) @@ -976,7 +980,7 @@ class TypeContrat(Metadata): ### AUTRES -class ResponsableImplantation(Metadata): +class ResponsableImplantation(AUFMetadata): """Le responsable d'une implantation. Anciennement géré sur le Dossier du responsable. """