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