1 # -*- encoding: utf-8 -*-
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 ajax_select
.fields
import AutoCompleteSelectField
7 from auf
.django
.workflow
.forms
import WorkflowFormMixin
8 from datamaster_modeles
import models
as ref
10 from dae
import models
as dae
11 from rh_v1
import models
as rh
13 def 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)
18 class PostePieceForm(inlineformset_factory(dae
.Poste
, dae
.PostePiece
)):
21 class DossierPieceForm(inlineformset_factory(dae
.Dossier
, dae
.DossierPiece
)):
24 class FinancementForm(inlineformset_factory(dae
.Poste
, dae
.PosteFinancement
, extra
=1)):
27 class JustificationNouvelEmployeForm(inlineformset_factory(dae
.Dossier
,
28 dae
.JustificationNouvelEmploye
,
31 exclude
=('question',))):
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.
36 def __init__(self
, *args
, **kwargs
):
37 instance
= kwargs
['instance']
39 q_ids
= [j
.question
.id for j
in instance
.justificationnouvelemploye_set
.filter(dossier
=instance
)]
40 for q
in dae
.JustificationQuestion
.objects
.filter(type="N"):
43 j
= dae
.JustificationNouvelEmploye()
47 super(self
.__class__
, self
).__init__(*args
, **kwargs
)
49 class JustificationAutreEmployeForm(inlineformset_factory(dae
.Dossier
,
50 dae
.JustificationAutreEmploye
,
53 exclude
=('question',))):
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.
58 def __init__(self
, *args
, **kwargs
):
59 instance
= kwargs
['instance']
61 q_ids
= [j
.question
.id for j
in instance
.justificationautreemploye_set
.filter(dossier
=instance
)]
62 for q
in dae
.JustificationQuestion
.objects
.filter(type="R"):
65 j
= dae
.JustificationAutreEmploye()
69 super(self
.__class__
, self
).__init__(*args
, **kwargs
)
71 class PosteForm(forms
.ModelForm
):
72 """ Formulaire des postes. """
78 fields
= ('poste', 'implantation', 'type_poste', 'service', 'nom',
79 'responsable', 'local', 'expatrie', 'mise_a_disposition',
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',
84 'devise_min', 'devise_max',
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',
91 'comp_autre_min', 'comp_autre_max',
95 widgets
= dict(appel
=forms
.RadioSelect(),
96 nom
=forms
.TextInput(attrs
={'size': 60},),
97 date_debut
=admin_widgets
.AdminDateWidget(),
98 date_fin
=admin_widgets
.AdminDateWidget(),
99 justification
=forms
.Textarea(attrs
={'cols': 80},),
100 #devise_min=forms.Select(attrs={'disabled':'disabled'}),
101 #devise_max=forms.Select(attrs={'disabled':'disabled'}),
104 responsable
=AutoCompleteSelectField('responsables', required
=True)
105 #responsable = forms.ModelChoiceField(
106 # queryset=rh.Poste.objects.select_related(depth=1))
108 # La liste des choix est laissée vide. Voir __init__ pour la raison.
109 poste
= forms
.ChoiceField(label
="Nouveau poste ou évolution du poste",
110 choices
=(), required
=False)
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)
115 def __init__(self
, *args
, **kwargs
):
116 """ Mise à jour dynamique du contenu du menu des postes.
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,
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).
127 super(PosteForm
, self
).__init__(*args
, **kwargs
)
128 self
.fields
['poste'].choices
= self
._poste_choices()
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
135 self
.initial
['nom'] = "%s %s" % (self
.initial
['nom'], self
.instance
.get_complement_nom())
138 def _poste_choices(self
):
139 """ Menu déroulant pour les postes.
141 Constitué des postes de dae et des postes de rh_v1 qui n'ont pas
142 d'équivalent dans dae.
145 dae_
= dae
.Poste
.objects
.filter(actif
=True, id_rh__isnull
=True)
146 copies
= dae
.Poste
.objects
.exclude(id_rh__isnull
=True)
147 id_copies
= [p
.id_rh_id
for p
in copies
.all()]
148 rhv1
= rh
.Poste
.objects
.filter(actif
=True).exclude(id__in
=id_copies
)
149 # Optimisation de la requête
150 rhv1
= rhv1
.select_related(depth
=1)
152 return [('', 'Nouveau poste')] + \
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
],
159 Validation conditionnelles de certains champs.
161 cleaned_data
= self
.cleaned_data
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")
177 def save(self
, *args
, **kwargs
):
178 kwargs2
= kwargs
.copy()
179 kwargs2
['commit'] = False
180 poste
= super(PosteForm
, self
).save(*args
, **kwargs2
)
182 if 'commit' not in kwargs
or kwargs
['commit']:
187 class ChoosePosteForm(forms
.ModelForm
):
192 # La liste des choix est laissée vide. Voir PosteForm.__init__.
193 poste
= forms
.ChoiceField(choices
=(), required
=False)
195 def __init__(self
, request
=None, *args
, **kwargs
):
196 super(ChoosePosteForm
, self
).__init__(*args
, **kwargs
)
197 self
.fields
['poste'].choices
= self
._poste_choices(request
)
199 def _poste_choices(self
, request
):
200 """ Menu déroulant pour les postes. """
201 dae_
= dae
.Poste
.objects
.ma_region_ou_service(request
.user
).filter(id_rh__isnull
=True)
202 copies
= dae
.Poste
.objects
.ma_region_ou_service(request
.user
).exclude(id_rh__isnull
=True)
203 id_copies
= [p
.id_rh_id
for p
in copies
.all()]
205 return [('', '----------')] + \
206 sorted([('dae-%s' % p
.id, unicode(p
)) for p
in dae_ | copies
],
210 class EmployeForm(forms
.ModelForm
):
211 """ Formulaire des employés. """
214 fields
= ('employe', 'nom', 'prenom', 'genre')
216 # La liste des choix est laissée vide. Voir Poste.__init__ pour la raison.
217 employe
= forms
.ChoiceField(choices
=(), required
=False)
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()
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
)
231 def option_label(employe
):
232 return "%s %s" % (employe
.nom
.upper(), employe
.prenom
.title())
234 return [('', 'Nouvel employé')] + \
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
],
240 class DossierForm(forms
.ModelForm
):
241 """ Formulaire des dossiers. """
245 widgets
= dict(statut_residence
=forms
.RadioSelect(),
246 contrat_date_debut
=admin_widgets
.AdminDateWidget(),
247 contrat_date_fin
=admin_widgets
.AdminDateWidget(),
250 class PosteWorkflowForm(WorkflowFormMixin
):
256 class DossierWorkflowForm(WorkflowFormMixin
):