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