poste consulter view
[auf_rh_dae.git] / project / dae / forms.py
CommitLineData
5d680e84 1# -*- encoding: utf-8 -*-
ce110fb9 2
5d680e84 3from django import forms
36341125 4from django.forms.models import inlineformset_factory
e88caaf0 5from django.contrib.admin import widgets as admin_widgets
afc204bf 6from ajax_select.fields import AutoCompleteSelectField
8fa94e8b 7from auf.django.workflow.forms import WorkflowFormMixin
5d680e84
NC
8from datamaster_modeles import models as ref
9
10from dae import models as dae
11from rh_v1 import models as rh
12
4bce4d24
OL
13def label_poste_display(poste):
14 """Formate un visuel pour un poste dans une liste déroulante"""
15 label = u"%s - %s [%s]" %(poste.type_poste, poste.type_poste.famille_emploi.nom, poste.id)
16 return label
9cb4de55
OL
17
18class PostePieceForm(inlineformset_factory(dae.Poste, dae.PostePiece)):
19 pass
20
21class DossierPieceForm(inlineformset_factory(dae.Dossier, dae.DossierPiece)):
22 pass
23
151e7bd0
OL
24class FinancementForm(inlineformset_factory(dae.Poste, dae.PosteFinancement, extra=1)):
25 pass
26
72db8238
OL
27class JustificationNouvelEmployeForm(inlineformset_factory(dae.Dossier,
28 dae.JustificationNouvelEmploye,
29 extra=0,
30 can_delete=False,
31 exclude=('question',))):
32 """
33 Formulaire de justification d'un nouvel employé.
34 Le dossier a besoin d'être enregistré une première fois afin de prépopuler les questions.
35 """
36 def __init__(self, *args, **kwargs):
37 instance = kwargs['instance']
38 if instance.id:
1cc5e025 39 q_ids = [j.question.id for j in instance.justificationnouvelemploye_set.filter(dossier=instance)]
72db8238
OL
40 for q in dae.JustificationQuestion.objects.filter(type="N"):
41 if q.id in q_ids:
42 continue
43 j = dae.JustificationNouvelEmploye()
44 j.dossier = instance
45 j.question = q
46 j.save()
47 super(self.__class__, self).__init__(*args, **kwargs)
48
49class JustificationAutreEmployeForm(inlineformset_factory(dae.Dossier,
50 dae.JustificationAutreEmploye,
51 extra=0,
52 can_delete=False,
53 exclude=('question',))):
54 """
55 Formulaire de justification d'un nouvel employé.
56 Le dossier a besoin d'être enregistré une première fois afin de prépopuler les questions.
57 """
58 def __init__(self, *args, **kwargs):
59 instance = kwargs['instance']
60 if instance.id:
1cc5e025 61 q_ids = [j.question.id for j in instance.justificationautreemploye_set.filter(dossier=instance)]
72db8238
OL
62 for q in dae.JustificationQuestion.objects.filter(type="R"):
63 if q.id in q_ids:
64 continue
65 j = dae.JustificationAutreEmploye()
66 j.dossier = instance
67 j.question = q
68 j.save()
69 super(self.__class__, self).__init__(*args, **kwargs)
5d680e84 70
8fa94e8b 71class PosteForm(WorkflowFormMixin):
5d680e84 72 """ Formulaire des postes. """
3121c13c
OL
73
74
5d680e84
NC
75 class Meta:
76 model = dae.Poste
ce110fb9 77
5d680e84 78 fields = ('poste', 'implantation', 'type_poste', 'service', 'nom',
154677c3 79 'responsable', 'local', 'expatrie', 'mise_a_disposition',
5d680e84
NC
80 'appel', 'date_debut', 'date_fin', 'actif',
81 'regime_travail', 'regime_travail_nb_heure_semaine',
82 'classement_min', 'classement_max',
83 'valeur_point_min', 'valeur_point_max',
3d627bfd 84 'devise_min', 'devise_max',
5d680e84
NC
85 'salaire_min', 'salaire_max', 'indemn_min', 'indemn_max',
86 'autre_min', 'autre_max', 'devise_comparaison',
87 'comp_locale_min', 'comp_locale_max',
88 'comp_universite_min', 'comp_universite_max',
89 'comp_fonctionpub_min', 'comp_fonctionpub_max',
90 'comp_ong_min', 'comp_ong_max',
8fa94e8b 91 'comp_autre_min', 'comp_autre_max',
2e092e0c 92 'justification',
8fa94e8b
OL
93 'etat',
94 )
154677c3 95 widgets = dict(appel=forms.RadioSelect(),
3d627bfd 96 nom=forms.TextInput(attrs={'size': 60},),
e88caaf0
OL
97 date_debut=admin_widgets.AdminDateWidget(),
98 date_fin=admin_widgets.AdminDateWidget(),
2e092e0c 99 justification=forms.Textarea(attrs={'cols': 80},),
3d627bfd 100 #devise_min=forms.Select(attrs={'disabled':'disabled'}),
101 #devise_max=forms.Select(attrs={'disabled':'disabled'}),
102 )
5d680e84 103
3121c13c
OL
104 responsable=AutoCompleteSelectField('responsables', required=True)
105 #responsable = forms.ModelChoiceField(
106 # queryset=rh.Poste.objects.select_related(depth=1))
139686f2 107
5d680e84 108 # La liste des choix est laissée vide. Voir __init__ pour la raison.
5efcd48e 109 poste = forms.ChoiceField(label="Nouveau poste ou évolution du poste",
d949462d 110 choices=(), required=False)
5d680e84 111
4dd75e7b
OL
112 valeur_point_min = forms.ModelChoiceField(queryset=rh.ValeurPoint.actuelles.all(), required=False)
113 valeur_point_max = forms.ModelChoiceField(queryset=rh.ValeurPoint.actuelles.all(), required=False)
6301bd59 114
5d680e84
NC
115 def __init__(self, *args, **kwargs):
116 """ Mise à jour dynamique du contenu du menu des postes.
117
118 Si on ne met le menu à jour de cette façon, à chaque instantiation du
119 formulaire, son contenu est mis en cache par le système et il ne
120 reflète pas les changements apportés par les ajouts, modifications,
121 etc...
122
139686f2
NC
123 Aussi, dans ce cas-ci, on ne peut pas utiliser un ModelChoiceField
124 car le "id" de chaque choix est spécial (voir _poste_choices).
125
5d680e84
NC
126 """
127 super(PosteForm, self).__init__(*args, **kwargs)
128 self.fields['poste'].choices = self._poste_choices()
129
cc3098d0
OL
130 # Quand le dae.Poste n'existe pas, on recherche dans les dossiers rhv1
131 if self.instance and self.instance.id is None:
132 dossiers = self.instance.get_dossiers()
133 if len(dossiers) > 0:
134 self.initial['service'] = dossiers[0].service_id
9508a5b8
OL
135 self.initial['nom'] = "%s %s" % (self.initial['nom'], self.instance.get_complement_nom())
136
cc3098d0 137
5d680e84
NC
138 def _poste_choices(self):
139 """ Menu déroulant pour les postes.
140
141 Constitué des postes de dae et des postes de rh_v1 qui n'ont pas
142 d'équivalent dans dae.
143
144 """
6d704629 145 dae_ = dae.Poste.objects.filter(actif=True, id_rh__isnull=True)
5d680e84
NC
146 copies = dae.Poste.objects.exclude(id_rh__isnull=True)
147 id_copies = [p.id_rh_id for p in copies.all()]
6d704629 148 rhv1 = rh.Poste.objects.filter(actif=True).exclude(id__in=id_copies)
139686f2
NC
149 # Optimisation de la requête
150 rhv1 = rhv1.select_related(depth=1)
5d680e84 151
98d51b59 152 return [('', 'Nouveau poste')] + \
4bce4d24
OL
153 sorted([('dae-%s' % p.id, label_poste_display(p)) for p in dae_ | copies] +
154 [('rh-%s' % p.id, label_poste_display(p)) for p in rhv1],
5d680e84 155 key=lambda t: t[1])
3ed49093 156
4dd75e7b
OL
157 def clean(self):
158 """
159 Validation conditionnelles de certains champs.
160 """
161 cleaned_data = self.cleaned_data
162
163 # Gestion de la mise à disposition
164 mise_a_disposition = cleaned_data.get("mise_a_disposition")
165 valeur_point_min = cleaned_data.get("valeur_point_min")
166 valeur_point_max = cleaned_data.get("valeur_point_max")
167 if mise_a_disposition is False and (valeur_point_min is None or valeur_point_max is None):
168 msg = u"Ce champ est obligatoire."
169 self._errors["valeur_point_min"] = self.error_class([msg])
170 self._errors["valeur_point_max"] = self.error_class([msg])
171 raise forms.ValidationError("Les valeurs de point sont vides")
172
173 return cleaned_data
174
175
176
494ff2be
NC
177 def save(self, *args, **kwargs):
178 kwargs2 = kwargs.copy()
179 kwargs2['commit'] = False
180 poste = super(PosteForm, self).save(*args, **kwargs2)
181 # id_rh
182 if 'commit' not in kwargs or kwargs['commit']:
183 poste.save()
184 return poste
185
3ed49093 186
139686f2
NC
187class ChoosePosteForm(forms.ModelForm):
188 class Meta:
189 model = dae.Poste
190 fields = ('poste',)
191
192 # La liste des choix est laissée vide. Voir PosteForm.__init__.
193 poste = forms.ChoiceField(choices=(), required=False)
194
195 def __init__(self, *args, **kwargs):
196 super(ChoosePosteForm, self).__init__(*args, **kwargs)
197 self.fields['poste'].choices = self._poste_choices()
198
199 def _poste_choices(self):
200 """ Menu déroulant pour les postes. """
201 dae_ = dae.Poste.objects.filter(id_rh__isnull=True)
202 copies = dae.Poste.objects.exclude(id_rh__isnull=True)
203 id_copies = [p.id_rh_id for p in copies.all()]
204
98d51b59 205 return [('', '----------')] + \
139686f2
NC
206 sorted([('dae-%s' % p.id, unicode(p)) for p in dae_ | copies],
207 key=lambda t: t[1])
208
209
139686f2
NC
210class EmployeForm(forms.ModelForm):
211 """ Formulaire des employés. """
212 class Meta:
213 model = dae.Employe
214 fields = ('employe', 'nom', 'prenom', 'genre')
215
216 # La liste des choix est laissée vide. Voir Poste.__init__ pour la raison.
217 employe = forms.ChoiceField(choices=(), required=False)
218
219 def __init__(self, *args, **kwargs):
220 """ Mise à jour dynamique du contenu du menu des employés. """
221 super(EmployeForm, self).__init__(*args, **kwargs)
222 self.fields['employe'].choices = self._employe_choices()
223
224 def _employe_choices(self):
225 """ Menu déroulant pour les employés. """
226 dae_ = dae.Employe.objects.filter(id_rh__isnull=True)
227 copies = dae.Employe.objects.exclude(id_rh__isnull=True)
228 id_copies = [p.id_rh_id for p in copies.all()]
229 rhv1 = rh.Employe.objects.exclude(id__in=id_copies)
230
f2a9bc7a
OL
231 def option_label(employe):
232 return "%s %s" % (employe.nom.upper(), employe.prenom.title())
233
139686f2 234 return [('', 'Nouvel employé')] + \
f2a9bc7a
OL
235 sorted([('dae-%s' % p.id, option_label(p)) for p in dae_ | copies] +
236 [('rh-%s' % p.id, option_label(p)) for p in rhv1],
139686f2
NC
237 key=lambda t: t[1])
238
239
240class DossierForm(forms.ModelForm):
241 """ Formulaire des dossiers. """
242 class Meta:
243 model = dae.Dossier
4d25e2ba 244 widgets = dict(statut_residence=forms.RadioSelect(),
0e0aeb7e
OL
245 contrat_date_debut=admin_widgets.AdminDateWidget(),
246 contrat_date_fin=admin_widgets.AdminDateWidget(),
4d25e2ba 247 )