from django.db import models
import reversion
from workflow import PosteWorkflow, DossierWorkflow
-from workflow import DOSSIER_ETAT_DRH_FINALISATION
-from managers import DossierManager, PosteManager
+from workflow import DOSSIER_ETAT_DRH_FINALISATION, DOSSIER_ETAT_REGION_FINALISATION, \
+ DOSSIER_ETAT_FINALISE
+from managers import DossierManager, PosteManager, PosteComparaisonManager, \
+ DossierComparaisonManager
import datamaster_modeles.models as ref
from rh_v1 import models as rh
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)
-
-def poste_piece_dispatch(instance, filename):
- path = "poste/%s/%s" % (instance.poste_id, filename)
- return path
-
-def dossier_piece_dispatch(instance, filename):
- path = "dossier/%s/%s" % (instance.dossier_id, filename)
- return path
+UPLOAD_STORAGE = FileSystemStorage(settings.PRIVE_MEDIA_ROOT)
### POSTE
)
+class DeviseException(Exception):
+ silent_variable_failure = True
+
class Poste(PosteWorkflow, models.Model):
# Contrat
regime_travail = models.DecimalField(max_digits=12, decimal_places=2,
- default=REGIME_TRAVAIL_DEFAULT,
- verbose_name=u"Temps de travail",
+ default=REGIME_TRAVAIL_DEFAULT,
+ verbose_name=u"Temps de travail",
help_text="% du temps complet")
regime_travail_nb_heure_semaine = models.DecimalField(max_digits=12,
decimal_places=2,
# Recrutement
local = models.BooleanField(verbose_name=u"Local", default=True, blank=True)
- expatrie = models.BooleanField(verbose_name=u"Expatrié", default=False,
+ expatrie = models.BooleanField(verbose_name=u"Expatrié", default=False,
blank=True)
mise_a_disposition = models.BooleanField(verbose_name=u"Mise à disposition")
appel = models.CharField(max_length=10, default='interne',
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='+',
+ valeur_point_min = models.ForeignKey(rh.ValeurPoint, related_name='+',
blank=True, null=True)
- valeur_point_max = models.ForeignKey(rh.ValeurPoint, related_name='+',
+ 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='+')
def _get_key(self):
"""
- Les vues sont montées selon une clef spéciale
+ 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
+ Cette méthode fournit un moyen de reconstruire cette clef
afin de générer les URLs.
"""
return "dae-%s" % self.id
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
+ (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,
+ 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 []
postes = [p for p in self.id_rh.poste1.all()]
return sorted(postes, key=lambda poste: poste.id, reverse=True)
-
+
def get_complement_nom(self):
"""
- Inspecte les modèles rh v1 pour trouver dans le dernier dossier
+ Inspecte les modèles rh v1 pour trouver dans le dernier dossier
un complément de titre de poste.
"""
dossiers = self.get_dossiers()
return None
def get_default_devise(self):
- """Récupère la devise par défaut en fonction de l'implantation
+ """Récupère la devise par défaut en fonction de l'implantation
(EUR autrement)
"""
try:
#####################
def get_couts_minimum(self):
- return (float)(self.salaire_min + self.indemn_expat_min + + self.indemn_fct_min + self.charges_patronales_min + self.autre_min)
+ return self.salaire_min + self.indemn_expat_min + self.indemn_fct_min + self.charges_patronales_min + self.autre_min
+
+ def get_salaire_minimum(self):
+ return self.get_couts_minimum() - self.charges_patronales_min
def get_taux_minimum(self):
- taux_changes = rh.TauxChange.objects.filter(devise=self.devise_min).order_by('annee')
- for t in taux_changes:
- if t.implantation == self.implantation:
- return t.taux
- if len(taux_changes) > 0:
- return taux_changes[0].taux
+ if self.devise_min.code == 'EUR':
+ return 1
+ liste_taux = self.devise_min.tauxchange_set.order_by('-annee').filter(implantation=self.implantation)
+ if len(liste_taux) == 0:
+ raise DeviseException(u"La devise %s n'a pas de taux pour l'implantation %s" % (self.devise_min, self.implantation))
else:
- raise Exception('Taux indisponible pour la devise %s (%s)' % (self.devise_min, self.implantation))
+ return liste_taux[0].taux
def get_couts_minimum_euros(self):
- return self.get_couts_minimum() * self.get_taux_minimum()
+ return float(self.get_couts_minimum()) * self.get_taux_minimum()
+
+ def get_salaire_minimum_euros(self):
+ return float(self.get_salaire_minimum()) * self.get_taux_minimum()
def get_couts_maximum(self):
- return (float)(self.salaire_max + self.indemn_expat_max + + self.indemn_fct_max + self.charges_patronales_max + self.autre_max)
+ return self.salaire_max + self.indemn_expat_max + self.indemn_fct_max + self.charges_patronales_max + self.autre_max
+
+ def get_salaire_maximum(self):
+ return self.get_couts_maximum() - self.charges_patronales_max
def get_taux_maximum(self):
- taux_changes = rh.TauxChange.objects.filter(devise=self.devise_max).order_by('annee')
- for t in taux_changes:
- if t.implantation == self.implantation:
- return t.taux
- if len(taux_changes) > 0:
- return taux_changes[0].taux
+ if self.devise_max.code == 'EUR':
+ return 1
+ liste_taux = self.devise_max.tauxchange_set.order_by('-annee').filter(implantation=self.implantation)
+ if len(liste_taux) == 0:
+ raise DeviseException(u"La devise %s n'a pas de taux pour l'implantation %s" % (self.devise_max, self.implantation))
else:
- raise Exception('Taux indisponible pour la devise %s (%s)' % (self.devise_max, self.implantation))
+ return liste_taux[0].taux
def get_couts_maximum_euros(self):
- return self.get_couts_maximum() * self.get_taux_maximum()
+ return float(self.get_couts_maximum()) * self.get_taux_maximum()
+ def get_salaire_maximum_euros(self):
+ return float(self.get_salaire_maximum()) * self.get_taux_maximum()
def show_taux_minimum(self):
try:
return self.get_taux_minimum()
- except Exception, e:
+ except DeviseException, e:
return e
def show_couts_minimum_euros(self):
try:
return self.get_couts_minimum_euros()
- except Exception, e:
+ except DeviseException, e:
+ return e
+
+ def show_salaire_minimum_euros(self):
+ try:
+ return self.get_salaire_minimum_euros()
+ except DeviseException, e:
return e
def show_taux_maximum(self):
try:
return self.get_taux_maximum()
- except Exception, e:
+ except DeviseException, e:
return e
def show_couts_maximum_euros(self):
try:
return self.get_couts_maximum_euros()
- except Exception, e:
+ except DeviseException, e:
+ return e
+
+ def show_salaire_maximum_euros(self):
+ try:
+ return self.get_salaire_maximum_euros()
+ except DeviseException, e:
return e
return False
else:
return True
-
+
def get_taux_comparaison(self):
try:
def __unicode__(self):
"""
- Cette fonction est consommatrice SQL car elle cherche les dossiers
+ Cette fonction est consommatrice SQL car elle cherche les dossiers
qui ont été liés à celui-ci.
"""
complement_nom_poste = self.get_complement_nom()
ordering = ['type']
def __unicode__(self):
- return u"%s %s %s" % (self.get_type_display(), self.pourcentage, self.commentaire)
+ return u"%s %.0f%% %s" % (self.get_type_display(), self.pourcentage, self.commentaire)
class PostePiece(models.Model):
poste = models.ForeignKey("Poste")
nom = models.CharField(verbose_name=u"Nom", max_length=255)
fichier = models.FileField(verbose_name=u"Fichier",
- upload_to=poste_piece_dispatch,
- storage=storage_prive)
+ upload_to='dae/poste',
+ storage=UPLOAD_STORAGE)
class PosteComparaison(models.Model):
poste = models.ForeignKey('Poste', related_name='comparaisons_internes')
montant = models.IntegerField(null=True)
devise = models.ForeignKey(rh.Devise, default=5, related_name='+', null=True, blank=True)
+ objects = PosteComparaisonManager()
+
def taux_devise(self):
+ if self.devise.code == 'EUR':
+ return 1
liste_taux = self.devise.tauxchange_set.order_by('-annee').filter(implantation=self.implantation)
if len(liste_taux) == 0:
- raise Exception(u"La devise %s n'a pas de taux pour l'implantation %s" % (self.devise, self.implantation))
+ raise DeviseException(u"La devise %s n'a pas de taux pour l'implantation %s" % (self.devise, self.implantation))
else:
return liste_taux[0].taux
class Employe(models.Model):
# Modèle existant
- id_rh = models.ForeignKey(rh.Employe, null=True, related_name='+',
+ id_rh = models.ForeignKey(rh.Employe, null=True, related_name='+',
verbose_name=u'Employé')
nom = models.CharField(max_length=255)
prenom = models.CharField(max_length=255, verbose_name=u'Prénom')
employe = models.ForeignKey('Employe', related_name='+', editable=False)
poste = models.ForeignKey('Poste', related_name='dossiers', editable=False)
statut = models.ForeignKey(rh.Statut, related_name='+')
- organisme_bstg = models.ForeignKey(rh.OrganismeBstg,
+ organisme_bstg = models.ForeignKey(rh.OrganismeBstg,
null=True, blank=True,
- verbose_name=u"Organisme",
+ verbose_name=u"Organisme",
help_text="Si détaché (DET) ou mis à disposition (MAD), \
préciser l'organisme.",
related_name='+')
blank=True,)
# Données antérieures de l'employé
- # la devise??
statut_anterieur = models.ForeignKey(
rh.Statut, related_name='+', null=True, blank=True,
verbose_name=u'Statut antérieur')
verbose_name=u'Classement précédent')
salaire_anterieur = models.DecimalField(
max_digits=12, decimal_places=2, null=True, default=None,
- blank=True, verbose_name=u'Salaire précédent')
+ blank=True, verbose_name='Salaire précédent')
+ devise_anterieur = models.ForeignKey(rh.Devise, related_name='+',
+ null=True, blank=True)
+ type_contrat_anterieur = models.ForeignKey(rh.TypeContrat,
+ related_name='+', null=True, blank=True,
+ verbose_name=u'Type contrat antérieur', )
# Données du titulaire précédent
employe_anterieur = models.ForeignKey(
verbose_name=u'Classement titulaire précédent')
salaire_titulaire_anterieur = models.DecimalField(
max_digits=12, decimal_places=2, default=None, null=True,
- blank=True, verbose_name=u'Salaire titulaire précédent')
+ blank=True, verbose_name='Salaire titulaire précédent')
+ devise_titulaire_anterieur = models.ForeignKey(rh.Devise, related_name='+', null=True, blank=True)
# Recrutement
remplacement = models.BooleanField()
- statut_residence = models.CharField(max_length=10, default='local',
- verbose_name=u"Statut",
+ statut_residence = models.CharField(max_length=10, default='local',
+ verbose_name="Statut",
choices=STATUT_RESIDENCE_CHOICES)
# Rémunération
verbose_name=u'Salaire de base',
null=True, default=None)
devise = models.ForeignKey(rh.Devise, default=5, related_name='+')
- regime_travail = models.DecimalField(max_digits=12,
+ regime_travail = models.DecimalField(max_digits=12,
decimal_places=2,
default=REGIME_TRAVAIL_DEFAULT,
verbose_name=u"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,
default=REGIME_TRAVAIL_NB_HEURE_SEMAINE_DEFAULT,
verbose_name=u"Nb. heures par semaine")
verbose_name=u'Compte comptabilité',
choices=COMPTE_COMPTA_CHOICES)
compte_courriel = models.BooleanField()
-
+
# Méta
date_creation = models.DateTimeField(auto_now_add=True)
-
+
# Managers
objects = DossierManager()
-
+
def __unicode__(self):
return u'[%s] %s - %s' % (self.poste.implantation, self.poste.nom, self.employe)
+ def taux_devise(self):
+ if self.devise.code == 'EUR':
+ return 1
+ liste_taux = self.devise.tauxchange_set.order_by('-annee').filter(implantation=self.poste.implantation)
+ if len(liste_taux) == 0:
+ raise DeviseException(u"La devise %s n'a pas de taux pour l'implantation %s" % (self.devise, self.poste.implantation))
+ else:
+ return liste_taux[0].taux
+
+ def get_salaire_anterieur_euros(self):
+ if self.devise_anterieur.code == 'EUR':
+ tx = 1
+ else:
+ liste_taux = self.devise_anterieur.tauxchange_set.order_by('-annee').filter(implantation=self.poste.implantation)
+ if len(liste_taux) == 0:
+ raise DeviseException(u"La devise %s n'a pas de taux pour l'implantation %s" % (self.devise_anterieur, self.poste.implantation))
+ tx = liste_taux[0].taux
+ return (float)(tx) * (float)(self.salaire_anterieur)
+
+ def get_salaire_titulaire_anterieur_euros(self):
+ if self.devise_titulaire_anterieur.code == 'EUR':
+ tx = 1
+ else:
+ liste_taux = self.devise_titulaire_anterieur.tauxchange_set.order_by('-annee').filter(implantation=self.poste.implantation)
+ if len(liste_taux) == 0:
+ raise DeviseException(u"La devise %s n'a pas de taux pour l'implantation %s" % (self.devise_titulaire_anterieur, self.poste.implantation))
+ tx = liste_taux[0].taux
+ return (float)(tx) * (float)(self.salaire_titulaire_anterieur)
+
def get_salaire_euros(self):
- try:
- tx = self.devise.tauxchange_set.order_by('-annee').filter(implantation=self.poste.implantation)[0].taux
- except:
- tx = 0
+ tx = self.taux_devise()
return (float)(tx) * (float)(self.salaire)
def get_remunerations_brutes(self):
def get_total_remunerations_tierces(self):
total = 0.0
- for r in self.get_remunerations_tierces():
+ for r in self.get_remunerations_tierces():
total += r.montant_euro()
return total
+ def valide(self):
+ return self.etat in (DOSSIER_ETAT_REGION_FINALISATION,
+ DOSSIER_ETAT_DRH_FINALISATION,
+ DOSSIER_ETAT_FINALISE)
+
# Tester l'enregistrement car les models.py sont importés au complet
if not reversion.is_registered(Dossier):
Ex.: Lettre de motivation.
"""
dossier = models.ForeignKey("Dossier")
- nom = models.CharField(verbose_name=u"Nom", max_length=255)
- fichier = models.FileField(verbose_name=u"Fichier",
- upload_to=dossier_piece_dispatch,
- storage=storage_prive)
+ nom = models.CharField(verbose_name="Nom", max_length=255)
+ fichier = models.FileField(verbose_name="Fichier",
+ upload_to='dae/dossier',
+ storage=UPLOAD_STORAGE)
class DossierComparaison(models.Model):
Photo d'une comparaison salariale au moment de l'embauche.
"""
dossier = models.ForeignKey('Dossier', related_name='comparaisons')
- statut = models.ForeignKey(rh.Statut, related_name='+', verbose_name=u'Statut', null=True, blank=True, )
- classement = models.ForeignKey(rh.Classement, related_name='+', verbose_name=u'Classement', null=True, blank=True, )
- implantation = models.ForeignKey(ref.Implantation, null=True, blank=True)
+ statut = models.ForeignKey(rh.Statut, related_name='+',
+ verbose_name='Statut', null=True, blank=True, )
+ classement = models.ForeignKey(rh.Classement, related_name='+',
+ verbose_name='Classement', null=True, blank=True, )
+ implantation = models.ForeignKey(ref.Implantation, related_name='+',
+ null=True, blank=True)
poste = models.CharField(max_length=255, null=True, blank=True)
personne = models.CharField(max_length=255, null=True, blank=True)
montant = models.IntegerField(null=True)
devise = models.ForeignKey(rh.Devise, default=5, related_name='+', null=True, blank=True)
+ objects = DossierComparaisonManager()
+
def taux_devise(self):
- liste_taux = self.devise.tauxchange_set.order_by('-annee').filter(implantation=self.dossier.poste.implantation)
+ if self.devise.code == 'EUR':
+ return 1
+ liste_taux = self.devise.tauxchange_set.order_by('-annee').filter(implantation=self.implantation)
if len(liste_taux) == 0:
- raise Exception(u"La devise %s n'a pas de taux pour l'implantation %s" % (self.devise, self.dossier.poste.implantation))
+ raise DeviseException(u"La devise %s n'a pas de taux pour l'implantation %s" % (self.devise, self.implantation))
else:
return liste_taux[0].taux
return round(self.montant / 12, 2)
def taux_devise(self):
+ if self.devise.code == 'EUR':
+ return 1
liste_taux = self.devise.tauxchange_set.order_by('-annee').filter(implantation=self.dossier.poste.implantation)
if len(liste_taux) == 0:
- raise Exception(u"La devise %s n'a pas de taux pour l'implantation %s" % (self.devise, self.dossier.poste.implantation))
+ raise DeviseException(u"La devise %s n'a pas de taux pour l'implantation %s" % (self.devise, self.dossier.poste.implantation))
else:
return liste_taux[0].taux
def montant_euro_mois(self):
return round(self.montant_euro() / 12, 2)
+
+
+### CONTRATS
+
+class Contrat(models.Model):
+ dossier = models.ForeignKey(Dossier, related_name='contrats')
+ type = models.ForeignKey(rh.TypeContrat, related_name='+')
+ fichier = models.FileField(upload_to='dae/contrats', storage=UPLOAD_STORAGE)
+