fix form poste
[auf_rh_dae.git] / project / dae / forms.py
index 05a3340..7618371 100644 (file)
 # -*- encoding: utf-8 -*-
 
 # -*- encoding: utf-8 -*-
 
+from django.db.models import Q
 from django import forms
 from django import forms
-
+from django.forms.models import inlineformset_factory
+from django.contrib.admin import widgets as admin_widgets 
+from ajax_select.fields import AutoCompleteSelectField
+from auf.django.workflow.forms import WorkflowFormMixin
 from datamaster_modeles import models as ref
 from datamaster_modeles import models as ref
-
 from dae import models as dae
 from dae import models as dae
+from utils import get_employe_from_user, is_user_dans_service
 from rh_v1 import models as rh
 from rh_v1 import models as rh
-
+from workflow import grp_drh
+
+def _implantation_choices(obj, request):
+    # TRAITEMENT NORMAL
+    employe = get_employe_from_user(request.user)
+    # SERVICE
+    if is_user_dans_service(request.user):
+        q = Q(**{ 'id' : employe.implantation_id })
+    # REGION
+    else:
+        q = Q(**{ 'region' : employe.implantation.region })
+
+    # TRAITEMENT DRH
+    if grp_drh in request.user.groups.all():
+        q = Q()
+    return [('', '----------')] + [(i.id, unicode(i), )for i in ref.Implantation.objects.filter(q)]
+
+def _employe_choices(obj, request):
+    q = Q(id_rh__isnull=True) & Q(id_rh__isnull=True)
+
+    # TRAITEMENT NORMAL
+    employe = get_employe_from_user(request.user)
+    # SERVICE
+    if is_user_dans_service(request.user):
+        q_region_service = Q(implantation1=employe.implantation) | Q(implantation2=employe.implantation)
+    # REGION
+    else:
+        q_region_service = Q(implantation1__region=employe.implantation.region) | Q(implantation2__region=employe.implantation.region) 
+    # TRAITEMENT DRH
+    if grp_drh in request.user.groups.all():
+        q_region_service = Q()
+
+    # Construction de la liste des employés en puisant dans DAE (pas d'info) et dans rh_v1
+    # Pour le filtrage par région/service, on est obligé d'aller regarder le dossier rh_v1
+    # car l'information dans le modèle rh_v1.Employe n'existe pas.
+    dae_ = dae.Employe.objects.filter(id_rh__isnull=True)
+    copies = dae.Employe.objects.filter(Q(id_rh__isnull=False))
+    id_copies = [p.id_rh_id for p in copies.all()]
+    employes_ids = list(set([d.employe_id for d in rh.Dossier.objects.filter(q_region_service)]))
+    rhv1 = rh.Employe.objects.filter(id__in=employes_ids).exclude(id__in=id_copies)
+
+    def option_label(employe):
+        return "%s %s" % (employe.nom.upper(), employe.prenom.title())
+
+    return [('', 'Nouvel employé')] + \
+           sorted([('dae-%s' % p.id, option_label(p)) for p in dae_ | copies] +
+                  [('rh-%s' % p.id, option_label(p)) for p in rhv1],
+                  key=lambda t: t[1])
+
+
+def label_poste_display(poste):
+    """Formate un visuel pour un poste dans une liste déroulante"""
+    label = u"%s - %s [%s]" %(poste.type_poste, poste.type_poste.famille_emploi.nom, poste.id)
+    return label
+
+class PostePieceForm(inlineformset_factory(dae.Poste, dae.PostePiece)):
+    pass
+
+class DossierPieceForm(inlineformset_factory(dae.Dossier, dae.DossierPiece)):
+    pass
+
+class FinancementForm(inlineformset_factory(dae.Poste, dae.PosteFinancement, extra=1)):
+    pass
+
+class JustificationNouvelEmployeForm(inlineformset_factory(dae.Dossier,
+                                                           dae.JustificationNouvelEmploye,
+                                                           extra=0,
+                                                           can_delete=False,
+                                                           exclude=('question',))):
+    """
+    Formulaire de justification d'un nouvel employé.
+    Le dossier a besoin d'être enregistré une première fois afin de prépopuler les questions.
+    """
+    def __init__(self, *args, **kwargs):
+        instance = kwargs['instance']
+        if instance.id:
+            q_ids = [j.question.id for j in instance.justificationnouvelemploye_set.filter(dossier=instance)]
+            for q in dae.JustificationQuestion.objects.filter(type="N"):
+                if q.id in q_ids:
+                    continue
+                j = dae.JustificationNouvelEmploye()
+                j.dossier = instance
+                j.question = q
+                j.save()
+        super(self.__class__, self).__init__(*args, **kwargs)
+
+class JustificationAutreEmployeForm(inlineformset_factory(dae.Dossier,
+                                                           dae.JustificationAutreEmploye,
+                                                           extra=0,
+                                                           can_delete=False,
+                                                           exclude=('question',))):
+    """
+    Formulaire de justification d'un nouvel employé.
+    Le dossier a besoin d'être enregistré une première fois afin de prépopuler les questions.
+    """
+    def __init__(self, *args, **kwargs):
+        instance = kwargs['instance']
+        if instance.id:
+            q_ids = [j.question.id for j in instance.justificationautreemploye_set.filter(dossier=instance)]
+            for q in dae.JustificationQuestion.objects.filter(type="R"):
+                if q.id in q_ids:
+                    continue
+                j = dae.JustificationAutreEmploye()
+                j.dossier = instance
+                j.question = q
+                j.save()
+        super(self.__class__, self).__init__(*args, **kwargs)
 
 class PosteForm(forms.ModelForm):
     """ Formulaire des postes. """
 
 class PosteForm(forms.ModelForm):
     """ Formulaire des postes. """
+    
+    
     class Meta:
         model = dae.Poste
 
         fields = ('poste', 'implantation', 'type_poste', 'service', 'nom',
     class Meta:
         model = dae.Poste
 
         fields = ('poste', 'implantation', 'type_poste', 'service', 'nom',
-                  'responsable', 'statut_residence', 'mise_a_disposition',
+                  'responsable', 'local', 'expatrie', 'mise_a_disposition',
                   'appel', 'date_debut', 'date_fin', 'actif',
                   'regime_travail', 'regime_travail_nb_heure_semaine',
                   'classement_min', 'classement_max',
                   'appel', 'date_debut', 'date_fin', 'actif',
                   'regime_travail', 'regime_travail_nb_heure_semaine',
                   'classement_min', 'classement_max',
-                  'coefficient_min', 'coefficient_max',
                   'valeur_point_min', 'valeur_point_max',
                   'valeur_point_min', 'valeur_point_max',
+                  'devise_min', 'devise_max',
                   'salaire_min', 'salaire_max', 'indemn_min', 'indemn_max',
                   'autre_min', 'autre_max', 'devise_comparaison',
                   'comp_locale_min', 'comp_locale_max',
                   'comp_universite_min', 'comp_universite_max',
                   'comp_fonctionpub_min', 'comp_fonctionpub_max',
                   'comp_ong_min', 'comp_ong_max',
                   'salaire_min', 'salaire_max', 'indemn_min', 'indemn_max',
                   'autre_min', 'autre_max', 'devise_comparaison',
                   'comp_locale_min', 'comp_locale_max',
                   'comp_universite_min', 'comp_universite_max',
                   'comp_fonctionpub_min', 'comp_fonctionpub_max',
                   'comp_ong_min', 'comp_ong_max',
-                  'comp_autre_min', 'comp_autre_max',)
-        widgets = dict(statut_residence=forms.RadioSelect(),
-                       appel=forms.RadioSelect(),
-                       nom=forms.TextInput(attrs={'size': 60}),
-)
-
-    responsable = forms.ModelChoiceField(
-            queryset=rh.Poste.objects.select_related(depth=1))
+                  'comp_autre_min', 'comp_autre_max',
+                  'justification',
+                  )
+        widgets = dict(appel=forms.RadioSelect(),
+                       nom=forms.TextInput(attrs={'size': 60},),
+                       date_debut=admin_widgets.AdminDateWidget(),
+                       date_fin=admin_widgets.AdminDateWidget(),
+                       justification=forms.Textarea(attrs={'cols': 80},),
+                       #devise_min=forms.Select(attrs={'disabled':'disabled'}),
+                       #devise_max=forms.Select(attrs={'disabled':'disabled'}),
+                    )
+
+    responsable=AutoCompleteSelectField('responsables', required=True)
+    #responsable = forms.ModelChoiceField(
+    #        queryset=rh.Poste.objects.select_related(depth=1))
 
     # La liste des choix est laissée vide. Voir __init__ pour la raison.
     poste = forms.ChoiceField(label="Nouveau poste ou évolution du poste",
                               choices=(), required=False)
 
 
     # La liste des choix est laissée vide. Voir __init__ pour la raison.
     poste = forms.ChoiceField(label="Nouveau poste ou évolution du poste",
                               choices=(), required=False)
 
+    valeur_point_min  = forms.ModelChoiceField(queryset=rh.ValeurPoint.actuelles.all(), required=False)
+    valeur_point_max = forms.ModelChoiceField(queryset=rh.ValeurPoint.actuelles.all(), required=False)
+
     def __init__(self, *args, **kwargs):
         """ Mise à jour dynamique du contenu du menu des postes.
 
     def __init__(self, *args, **kwargs):
         """ Mise à jour dynamique du contenu du menu des postes.
 
@@ -51,28 +173,58 @@ class PosteForm(forms.ModelForm):
         car le "id" de chaque choix est spécial (voir _poste_choices).
 
         """
         car le "id" de chaque choix est spécial (voir _poste_choices).
 
         """
+        request = kwargs.pop('request')
         super(PosteForm, self).__init__(*args, **kwargs)
         super(PosteForm, self).__init__(*args, **kwargs)
-        self.fields['poste'].choices = self._poste_choices()
+        self.fields['poste'].choices = self._poste_choices(request)
+        self.fields['implantation'].choices = _implantation_choices(self, request)
 
 
-    def _poste_choices(self):
+        # Quand le dae.Poste n'existe pas, on recherche dans les dossiers rhv1
+        if self.instance and self.instance.id is None:
+            dossiers = self.instance.get_dossiers()
+            if len(dossiers) > 0:
+                self.initial['service'] = dossiers[0].service_id
+                self.initial['nom'] = "%s %s" % (self.initial['nom'], self.instance.get_complement_nom())
+
+
+    def _poste_choices(self, request):
         """ Menu déroulant pour les postes.
 
         Constitué des postes de dae et des postes de rh_v1 qui n'ont pas
         d'équivalent dans dae.
 
         """
         """ Menu déroulant pour les postes.
 
         Constitué des postes de dae et des postes de rh_v1 qui n'ont pas
         d'équivalent dans dae.
 
         """
-        dae_ = dae.Poste.objects.filter(actif=True, id_rh__isnull=True)
-        copies = dae.Poste.objects.exclude(id_rh__isnull=True)
+        dae_ = dae.Poste.objects.ma_region_ou_service(request.user).filter(actif=True, id_rh__isnull=True)
+        copies = dae.Poste.objects.ma_region_ou_service(request.user).exclude(id_rh__isnull=True)
         id_copies = [p.id_rh_id for p in copies.all()]
         id_copies = [p.id_rh_id for p in copies.all()]
-        rhv1 = rh.Poste.objects.filter(actif=True).exclude(id__in=id_copies)
+        rhv1 = rh.Poste.objects.ma_region_ou_service(request.user).filter(actif=True).exclude(id__in=id_copies)
         # Optimisation de la requête
         rhv1 = rhv1.select_related(depth=1)
 
         return [('', 'Nouveau poste')] + \
         # Optimisation de la requête
         rhv1 = rhv1.select_related(depth=1)
 
         return [('', 'Nouveau poste')] + \
-               sorted([('dae-%s' % p.id, unicode(p)) for p in dae_ | copies] +
-                      [('rh-%s' % p.id, unicode(p)) for p in rhv1],
+               sorted([('dae-%s' % p.id, label_poste_display(p)) for p in dae_ | copies] +
+                      [('rh-%s' % p.id, label_poste_display(p)) for p in rhv1],
                       key=lambda t: t[1])
 
                       key=lambda t: t[1])
 
+    def clean(self):
+        """
+        Validation conditionnelles de certains champs.
+        """
+        cleaned_data  = self.cleaned_data
+
+        # Gestion de la mise à disposition
+        mise_a_disposition = cleaned_data.get("mise_a_disposition")
+        valeur_point_min = cleaned_data.get("valeur_point_min")
+        valeur_point_max = cleaned_data.get("valeur_point_max")
+        if mise_a_disposition is False and (valeur_point_min is None or valeur_point_max is None):
+            msg = u"Ce champ est obligatoire."
+            self._errors["valeur_point_min"] = self.error_class([msg])
+            self._errors["valeur_point_max"] = self.error_class([msg])
+            raise forms.ValidationError("Les valeurs de point sont vides")
+        
+        return cleaned_data
+
+
+
     def save(self, *args, **kwargs):
         kwargs2 = kwargs.copy()
         kwargs2['commit'] = False
     def save(self, *args, **kwargs):
         kwargs2 = kwargs.copy()
         kwargs2['commit'] = False
@@ -91,14 +243,14 @@ class ChoosePosteForm(forms.ModelForm):
     # La liste des choix est laissée vide. Voir PosteForm.__init__.
     poste = forms.ChoiceField(choices=(), required=False)
 
     # La liste des choix est laissée vide. Voir PosteForm.__init__.
     poste = forms.ChoiceField(choices=(), required=False)
 
-    def __init__(self, *args, **kwargs):
+    def __init__(self, request=None, *args, **kwargs):
         super(ChoosePosteForm, self).__init__(*args, **kwargs)
         super(ChoosePosteForm, self).__init__(*args, **kwargs)
-        self.fields['poste'].choices = self._poste_choices()
+        self.fields['poste'].choices = self._poste_choices(request)
 
 
-    def _poste_choices(self):
+    def _poste_choices(self, request):
         """ Menu déroulant pour les postes. """
         """ Menu déroulant pour les postes. """
-        dae_ = dae.Poste.objects.filter(id_rh__isnull=True)
-        copies = dae.Poste.objects.exclude(id_rh__isnull=True)
+        dae_ = dae.Poste.objects.ma_region_ou_service(request.user).filter(id_rh__isnull=True)
+        copies = dae.Poste.objects.ma_region_ou_service(request.user).exclude(id_rh__isnull=True)
         id_copies = [p.id_rh_id for p in copies.all()]
 
         return [('', '----------')] + \
         id_copies = [p.id_rh_id for p in copies.all()]
 
         return [('', '----------')] + \
@@ -106,13 +258,6 @@ class ChoosePosteForm(forms.ModelForm):
                       key=lambda t: t[1])
 
 
                       key=lambda t: t[1])
 
 
-class PosteFinancementForm(forms.ModelForm):
-    """ Formulaire des sources de financement pour un poste. """
-    class Meta:
-        model = dae.PosteFinancement
-        fields = ('type', 'montant', 'pourcentage', 'commentaire')
-
-
 class EmployeForm(forms.ModelForm):
     """ Formulaire des employés. """
     class Meta:
 class EmployeForm(forms.ModelForm):
     """ Formulaire des employés. """
     class Meta:
@@ -122,25 +267,31 @@ class EmployeForm(forms.ModelForm):
     # La liste des choix est laissée vide. Voir Poste.__init__ pour la raison.
     employe = forms.ChoiceField(choices=(), required=False)
 
     # La liste des choix est laissée vide. Voir Poste.__init__ pour la raison.
     employe = forms.ChoiceField(choices=(), required=False)
 
-    def __init__(self, *args, **kwargs):
+    def __init__(self, request, *args, **kwargs):
         """ Mise à jour dynamique du contenu du menu des employés. """
         super(EmployeForm, self).__init__(*args, **kwargs)
         """ Mise à jour dynamique du contenu du menu des employés. """
         super(EmployeForm, self).__init__(*args, **kwargs)
-        self.fields['employe'].choices = self._employe_choices()
-
-    def _employe_choices(self):
-        """ Menu déroulant pour les employés. """
-        dae_ = dae.Employe.objects.filter(id_rh__isnull=True)
-        copies = dae.Employe.objects.exclude(id_rh__isnull=True)
-        id_copies = [p.id_rh_id for p in copies.all()]
-        rhv1 = rh.Employe.objects.exclude(id__in=id_copies)
+        self.fields['employe'].choices = _employe_choices(self, request)
 
 
-        return [('', 'Nouvel employé')] + \
-               sorted([('dae-%s' % p.id, unicode(p)) for p in dae_ | copies] +
-                      [('rh-%s' % p.id, unicode(p)) for p in rhv1],
-                      key=lambda t: t[1])
 
 
 class DossierForm(forms.ModelForm):
     """ Formulaire des dossiers. """
     class Meta:
 
 
 class DossierForm(forms.ModelForm):
     """ Formulaire des dossiers. """
     class Meta:
+        exclude= ('etat', )
+        model = dae.Dossier
+        widgets = dict(statut_residence=forms.RadioSelect(),
+                       contrat_date_debut=admin_widgets.AdminDateWidget(),
+                       contrat_date_fin=admin_widgets.AdminDateWidget(),
+                    )
+
+class PosteWorkflowForm(WorkflowFormMixin):
+    
+    class Meta:
+        fields = ('etat', )
+        model = dae.Poste
+
+class DossierWorkflowForm(WorkflowFormMixin):
+    
+    class Meta:
+        fields = ('etat', )
         model = dae.Dossier
         model = dae.Dossier