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