d601326ffb682db52aa782525d4f7051a0d3ad41
[auf_rh_dae.git] / project / dae / forms.py
1 # -*- encoding: utf-8 -*-
2
3 from django import forms
4 from django.forms.models import inlineformset_factory
5 from django.contrib.admin import widgets as admin_widgets
6 from auf.django.workflow.forms import WorkflowFormMixin
7 from datamaster_modeles import models as ref
8
9 from dae import models as dae
10 from rh_v1 import models as rh
11
12
13 class PostePieceForm(inlineformset_factory(dae.Poste, dae.PostePiece)):
14 pass
15
16 class DossierPieceForm(inlineformset_factory(dae.Dossier, dae.DossierPiece)):
17 pass
18
19
20 class PosteValidationForm(forms.ModelForm):
21 """ Validation d'un poste"""
22 class Meta:
23 model = dae.Poste
24 fields = (
25 'validation_bureau_regional',
26 'validation_drh',
27 'validation_secretaire_general',
28 'validation_recteur',
29 )
30
31 class PosteForm(WorkflowFormMixin):
32 """ Formulaire des postes. """
33 class Meta:
34 model = dae.Poste
35
36 fields = ('poste', 'implantation', 'type_poste', 'service', 'nom',
37 'responsable', 'statut_residence', 'mise_a_disposition',
38 'appel', 'date_debut', 'date_fin', 'actif',
39 'regime_travail', 'regime_travail_nb_heure_semaine',
40 'classement_min', 'classement_max',
41 'coefficient_min', 'coefficient_max',
42 'valeur_point_min', 'valeur_point_max',
43 'devise_min', 'devise_max',
44 'salaire_min', 'salaire_max', 'indemn_min', 'indemn_max',
45 'autre_min', 'autre_max', 'devise_comparaison',
46 'comp_locale_min', 'comp_locale_max',
47 'comp_universite_min', 'comp_universite_max',
48 'comp_fonctionpub_min', 'comp_fonctionpub_max',
49 'comp_ong_min', 'comp_ong_max',
50 'comp_autre_min', 'comp_autre_max',
51 'etat',
52 )
53 widgets = dict(statut_residence=forms.RadioSelect(),
54 appel=forms.RadioSelect(),
55 nom=forms.TextInput(attrs={'size': 60},),
56 date_debut=admin_widgets.AdminDateWidget(),
57 date_fin=admin_widgets.AdminDateWidget(),
58 #devise_min=forms.Select(attrs={'disabled':'disabled'}),
59 #devise_max=forms.Select(attrs={'disabled':'disabled'}),
60 )
61
62 responsable = forms.ModelChoiceField(
63 queryset=rh.Poste.objects.select_related(depth=1))
64
65 # La liste des choix est laissée vide. Voir __init__ pour la raison.
66 poste = forms.ChoiceField(label="Nouveau poste ou évolution du poste",
67 choices=(), required=False)
68
69 valeur_point_min = forms.ModelChoiceField(queryset=rh.ValeurPoint.actuelles.all(), required=False)
70 valeur_point_max = forms.ModelChoiceField(queryset=rh.ValeurPoint.actuelles.all(), required=False)
71
72 def __init__(self, *args, **kwargs):
73 """ Mise à jour dynamique du contenu du menu des postes.
74
75 Si on ne met le menu à jour de cette façon, à chaque instantiation du
76 formulaire, son contenu est mis en cache par le système et il ne
77 reflète pas les changements apportés par les ajouts, modifications,
78 etc...
79
80 Aussi, dans ce cas-ci, on ne peut pas utiliser un ModelChoiceField
81 car le "id" de chaque choix est spécial (voir _poste_choices).
82
83 """
84 super(PosteForm, self).__init__(*args, **kwargs)
85 self.fields['poste'].choices = self._poste_choices()
86
87 # Quand le dae.Poste n'existe pas, on recherche dans les dossiers rhv1
88 if self.instance and self.instance.id is None:
89 dossiers = self.instance.get_dossiers()
90 if len(dossiers) > 0:
91 self.initial['service'] = dossiers[0].service_id
92 self.initial['nom'] = "%s %s" % (self.initial['nom'], self.instance.get_complement_nom())
93
94
95 def _poste_choices(self):
96 """ Menu déroulant pour les postes.
97
98 Constitué des postes de dae et des postes de rh_v1 qui n'ont pas
99 d'équivalent dans dae.
100
101 """
102 dae_ = dae.Poste.objects.filter(actif=True, id_rh__isnull=True)
103 copies = dae.Poste.objects.exclude(id_rh__isnull=True)
104 id_copies = [p.id_rh_id for p in copies.all()]
105 rhv1 = rh.Poste.objects.filter(actif=True).exclude(id__in=id_copies)
106 # Optimisation de la requête
107 rhv1 = rhv1.select_related(depth=1)
108
109 return [('', 'Nouveau poste')] + \
110 sorted([('dae-%s' % p.id, unicode(p)) for p in dae_ | copies] +
111 [('rh-%s' % p.id, unicode(p)) for p in rhv1],
112 key=lambda t: t[1])
113
114 def clean(self):
115 """
116 Validation conditionnelles de certains champs.
117 """
118 cleaned_data = self.cleaned_data
119
120 # Gestion de la mise à disposition
121 mise_a_disposition = cleaned_data.get("mise_a_disposition")
122 valeur_point_min = cleaned_data.get("valeur_point_min")
123 valeur_point_max = cleaned_data.get("valeur_point_max")
124 if mise_a_disposition is False and (valeur_point_min is None or valeur_point_max is None):
125 msg = u"Ce champ est obligatoire."
126 self._errors["valeur_point_min"] = self.error_class([msg])
127 self._errors["valeur_point_max"] = self.error_class([msg])
128 raise forms.ValidationError("Les valeurs de point sont vides")
129
130 return cleaned_data
131
132
133
134 def save(self, *args, **kwargs):
135 kwargs2 = kwargs.copy()
136 kwargs2['commit'] = False
137 poste = super(PosteForm, self).save(*args, **kwargs2)
138 # id_rh
139 if 'commit' not in kwargs or kwargs['commit']:
140 poste.save()
141 return poste
142
143
144 class ChoosePosteForm(forms.ModelForm):
145 class Meta:
146 model = dae.Poste
147 fields = ('poste',)
148
149 # La liste des choix est laissée vide. Voir PosteForm.__init__.
150 poste = forms.ChoiceField(choices=(), required=False)
151
152 def __init__(self, *args, **kwargs):
153 super(ChoosePosteForm, self).__init__(*args, **kwargs)
154 self.fields['poste'].choices = self._poste_choices()
155
156 def _poste_choices(self):
157 """ Menu déroulant pour les postes. """
158 dae_ = dae.Poste.objects.filter(id_rh__isnull=True)
159 copies = dae.Poste.objects.exclude(id_rh__isnull=True)
160 id_copies = [p.id_rh_id for p in copies.all()]
161
162 return [('', '----------')] + \
163 sorted([('dae-%s' % p.id, unicode(p)) for p in dae_ | copies],
164 key=lambda t: t[1])
165
166
167 class PosteFinancementForm(forms.ModelForm):
168 """ Formulaire des sources de financement pour un poste. """
169 class Meta:
170 model = dae.PosteFinancement
171 fields = ('type', 'montant', 'pourcentage', 'commentaire')
172
173
174 class EmployeForm(forms.ModelForm):
175 """ Formulaire des employés. """
176 class Meta:
177 model = dae.Employe
178 fields = ('employe', 'nom', 'prenom', 'genre')
179
180 # La liste des choix est laissée vide. Voir Poste.__init__ pour la raison.
181 employe = forms.ChoiceField(choices=(), required=False)
182
183 def __init__(self, *args, **kwargs):
184 """ Mise à jour dynamique du contenu du menu des employés. """
185 super(EmployeForm, self).__init__(*args, **kwargs)
186 self.fields['employe'].choices = self._employe_choices()
187
188 def _employe_choices(self):
189 """ Menu déroulant pour les employés. """
190 dae_ = dae.Employe.objects.filter(id_rh__isnull=True)
191 copies = dae.Employe.objects.exclude(id_rh__isnull=True)
192 id_copies = [p.id_rh_id for p in copies.all()]
193 rhv1 = rh.Employe.objects.exclude(id__in=id_copies)
194
195 return [('', 'Nouvel employé')] + \
196 sorted([('dae-%s' % p.id, unicode(p)) for p in dae_ | copies] +
197 [('rh-%s' % p.id, unicode(p)) for p in rhv1],
198 key=lambda t: t[1])
199
200
201 class DossierForm(forms.ModelForm):
202 """ Formulaire des dossiers. """
203 class Meta:
204 model = dae.Dossier
205 widgets = dict(statut_residence=forms.RadioSelect(),
206 contrat_date_debut=admin_widgets.AdminDateWidget(),
207 contrat_date_fin=admin_widgets.AdminDateWidget(),
208 )