Small js refactoring
[auf_rh_dae.git] / project / dae / forms.py
CommitLineData
5d680e84 1# -*- encoding: utf-8 -*-
ce110fb9 2
bed0c4c9 3import datetime
5a1f75cb 4from django import forms
80be36aa 5from django.core.urlresolvers import reverse
2e672700 6from django.forms.models import BaseInlineFormSet
4718c21c
BS
7from django.forms.models import (
8 inlineformset_factory,
9 modelformset_factory,
10 _get_foreign_key,
11 )
80be36aa
OL
12from django.db.models import Q, Max, Count
13from django.shortcuts import redirect
14from django.contrib.admin import widgets as admin_widgets
5a1f75cb 15
75f0e87b
DB
16from ajax_select.fields import AutoCompleteSelectField
17
18from auf.django.references import models as ref
19from auf.django.workflow.forms import WorkflowFormMixin
66fefd2f 20from auf.django.workflow.models import WorkflowCommentaire
75f0e87b 21
3383b2d1 22from project import groups
17c90428 23from project.rh import models as rh
17c90428 24from project.dae import models as dae
4718c21c 25from .widgets import ReadOnlyChoiceWidget
34950f36 26from project.dae.workflow import POSTE_ETATS_BOUTONS, POSTE_ETAT_FINALISE
1b31de9f 27
f258e4e7 28
2e672700
OL
29class BaseInlineFormSetWithInitial(BaseInlineFormSet):
30 """
31 Cette classe permet de fournir l'option initial aux inlineformsets.
32 Elle devient désuette en django 1.4.
33 """
34 def __init__(self, data=None, files=None, instance=None,
35 save_as_new=False, prefix=None, queryset=None, **kwargs):
36
37 self.initial_extra = kwargs.pop('initial', None)
38
39 from django.db.models.fields.related import RelatedObject
40 if instance is None:
41 self.instance = self.fk.rel.to()
42 else:
43 self.instance = instance
44 self.save_as_new = save_as_new
45 # is there a better way to get the object descriptor?
46 self.rel_name = RelatedObject(self.fk.rel.to, self.model, self.fk).get_accessor_name()
47 if queryset is None:
48 queryset = self.model._default_manager
49 qs = queryset.filter(**{self.fk.name: self.instance})
50 super(BaseInlineFormSetWithInitial, self).__init__(data, files, prefix=prefix,
51 queryset=qs, **kwargs)
52
53 def _construct_form(self, i, **kwargs):
54 if self.is_bound and i < self.initial_form_count():
55 # Import goes here instead of module-level because importing
56 # django.db has side effects.
57 from django.db import connections
58 pk_key = "%s-%s" % (self.add_prefix(i), self.model._meta.pk.name)
59 pk = self.data[pk_key]
60 pk_field = self.model._meta.pk
61 pk = pk_field.get_db_prep_lookup('exact', pk,
62 connection=connections[self.get_queryset().db])
63 if isinstance(pk, list):
64 pk = pk[0]
65 kwargs['instance'] = self._existing_object(pk)
66 if i < self.initial_form_count() and not kwargs.get('instance'):
67 kwargs['instance'] = self.get_queryset()[i]
68 if i >= self.initial_form_count() and self.initial_extra:
69 # Set initial values for extra forms
70 try:
71 kwargs['initial'] = self.initial_extra[i-self.initial_form_count()]
72 except IndexError:
73 pass
74
75 defaults = {'auto_id': self.auto_id, 'prefix': self.add_prefix(i)}
76 if self.is_bound:
77 defaults['data'] = self.data
78 defaults['files'] = self.files
79 if self.initial:
80 try:
81 defaults['initial'] = self.initial[i]
82 except IndexError:
83 pass
84 # Allow extra forms to be empty.
85 if i >= self.initial_form_count():
86 defaults['empty_permitted'] = True
87 defaults.update(kwargs)
88 form = self.form(**defaults)
89 self.add_fields(form, i)
90 return form
91
92
f258e4e7
OL
93def _implantation_choices(obj, request):
94 # TRAITEMENT NORMAL
3383b2d1 95 employe = groups.get_employe_from_user(request.user)
b0cf30b8 96 q = Q(**{'zone_administrative': employe.implantation.zone_administrative})
f258e4e7
OL
97
98 # TRAITEMENT DRH
3383b2d1 99 user_groupes = [g.name for g in request.user.groups.all()]
713b824a
OL
100 if groups.DRH_NIVEAU_1 in user_groupes or \
101 groups.DRH_NIVEAU_2 in user_groupes:
f258e4e7 102 q = Q()
5a1f75cb
EMS
103 return [('', '----------')] + \
104 [(i.id, unicode(i), )for i in ref.Implantation.objects.filter(q)]
105
f258e4e7
OL
106
107def _employe_choices(obj, request):
f258e4e7 108 # TRAITEMENT NORMAL
3383b2d1 109 employe = groups.get_employe_from_user(request.user)
b0cf30b8
EMS
110 q_dae_region_service = Q(
111 poste__implantation__zone_administrative=(
112 employe.implantation.zone_administrative
5a1f75cb 113 )
b0cf30b8
EMS
114 )
115 q_rh_region_service = Q(
116 poste__implantation__zone_administrative=(
117 employe.implantation.zone_administrative
5a1f75cb 118 )
b0cf30b8 119 )
f258e4e7 120 # TRAITEMENT DRH
3383b2d1 121 user_groupes = [g.name for g in request.user.groups.all()]
713b824a
OL
122 if groups.DRH_NIVEAU_1 in user_groupes or \
123 groups.DRH_NIVEAU_2 in user_groupes:
072820fc
OL
124 q_dae_region_service = Q()
125 q_rh_region_service = Q()
f258e4e7 126
5a1f75cb
EMS
127 # On filtre les employes avec les droits régionaux et on s'assure que
128 # c'est bien le dernier dossier en date pour sortir l'employe. On retient
129 # un employé qui travaille présentement dans la même région que le user
130 # connecté.
131 dossiers_regionaux_ids = [
132 d.id for d in dae.Dossier.objects.filter(q_dae_region_service)
133 ]
134 employes_ids = [
135 d['employe']
136 for d in dae.Dossier.objects
137 .values('employe')
138 .annotate(dernier_dossier=Max('id'))
139 if d['dernier_dossier'] in dossiers_regionaux_ids
140 ]
072820fc
OL
141 dae_employe = dae.Employe.objects.filter(id__in=employes_ids)
142 dae_ = dae_employe.filter(id_rh__isnull=True)
143 copies = dae_employe.filter(Q(id_rh__isnull=False))
f258e4e7 144 id_copies = [p.id_rh_id for p in copies.all()]
072820fc 145
5a1f75cb
EMS
146 dossiers_regionaux_ids = [
147 d.id for d in rh.Dossier.objects.filter(q_rh_region_service)
148 ]
149 employes_ids = [
150 d['employe']
151 for d in rh.Dossier.objects
152 .values('employe')
153 .annotate(dernier_dossier=Max('id'))
154 if d['dernier_dossier'] in dossiers_regionaux_ids
155 ]
156 rhv1 = rh.Employe.objects \
157 .filter(id__in=employes_ids) \
158 .exclude(id__in=id_copies)
159
160 # On ajoute les nouveaux Employés DAE qui ont été crées, mais qui n'ont
161 # pas de Dossier associés
67c15007
OL
162 employes_avec_dae = [d.employe_id for d in dae.Dossier.objects.all()]
163 employes_orphelins = dae.Employe.objects.exclude(id__in=employes_avec_dae)
164
0339920c
OL
165 def option_label(employe, extra=""):
166 if extra:
167 extra = " [%s]" % extra
168 return "%s %s %s" % (employe.nom.upper(), employe.prenom.title(), extra)
f258e4e7 169
0339920c
OL
170 lbl_rh = sorted([('rh-%s' % p.id, option_label(p, "existant dans rh")) for p in rhv1],
171 key=lambda t: t[1])
172 lbl_dae = sorted([('dae-%s' % p.id, option_label(p)) for p in dae_ | copies | employes_orphelins],
173 key=lambda t: t[1])
174 return [('', 'Nouvel employé')] + lbl_rh + lbl_dae
5a1f75cb 175
f258e4e7 176
4bce4d24
OL
177def label_poste_display(poste):
178 """Formate un visuel pour un poste dans une liste déroulante"""
23294f7d
OL
179 annee = ""
180 if poste.date_debut:
181 annee = poste.date_debut.year
9c1ff333
OL
182
183 nom = poste.nom
67ae0181 184 label = u"%s (%s) %s [%s]" % (
34950f36
OL
185 annee,
186 poste.implantation.nom_court,
187 nom,
67ae0181 188 #poste.type_poste.categorie_emploi.nom,
34950f36 189 poste.id,
93817ef3 190 )
4bce4d24 191 return label
9cb4de55 192
2e672700 193
874949f3 194PostePieceFormSet = inlineformset_factory(dae.Poste, dae.PostePiece,)
25086dcf 195DossierPieceForm = inlineformset_factory(dae.Dossier, dae.DossierPiece)
2e672700 196
874949f3
OL
197# Ce formset est utilisé dans le cas de la création de poste prépopulé avec les
198# données de RH
199FinancementFormSetInitial = inlineformset_factory(
2e672700
OL
200 dae.Poste,
201 dae.PosteFinancement,
202 formset=BaseInlineFormSetWithInitial,
203 extra=2
5a1f75cb 204)
874949f3
OL
205FinancementFormSet = inlineformset_factory(
206 dae.Poste,
207 dae.PosteFinancement,
208 extra=2
209)
5a1f75cb 210
03b395db
OL
211
212class DossierComparaisonForm(forms.ModelForm):
11f22317 213
03b395db 214 recherche = AutoCompleteSelectField('dossiers', required=False)
5a1f75cb
EMS
215 poste = forms.CharField(
216 max_length=255, widget=forms.TextInput(attrs={'size': '60'})
217 )
03b395db 218
320d7584 219 class Meta:
03b395db 220 model = dae.DossierComparaison
320d7584 221 exclude = ('dossier',)
03b395db 222
320d7584
EMS
223DossierComparaisonFormSet = modelformset_factory(
224 dae.DossierComparaison, extra=3, max_num=3, form=DossierComparaisonForm
25086dcf 225)
03b395db 226
5a1f75cb 227
068d1462 228class PosteComparaisonForm(forms.ModelForm):
11f22317 229
e503e64d 230 recherche = AutoCompleteSelectField('dae_postes', required=False)
068d1462 231
320d7584 232 class Meta:
068d1462 233 model = dae.PosteComparaison
320d7584 234 exclude = ('poste',)
068d1462 235
874949f3
OL
236# Ce formset est utilisé dans le cas de la création de poste prépopulé avec les
237# données de RH
238PosteComparaisonFormSetInitial = inlineformset_factory(
2e672700
OL
239 dae.Poste,
240 dae.PosteComparaison,
241 extra=3,
242 max_num=3,
243 form=PosteComparaisonForm,
2e672700 244 formset=BaseInlineFormSetWithInitial,
25086dcf 245)
874949f3
OL
246PosteComparaisonFormSet = inlineformset_factory(
247 dae.Poste,
248 dae.PosteComparaison,
249 extra=3,
250 max_num=3,
251 form=PosteComparaisonForm,
252)
068d1462 253
5a1f75cb 254
0a085c42
OL
255class FlexibleRemunForm(forms.ModelForm):
256
257 montant_mensuel = forms.DecimalField(required=False)
258 montant = forms.DecimalField(required=True, label='Montant annuel')
259
260 class Meta:
261 model = dae.Remuneration
262
4718c21c
BS
263 def __init__(self, *a, **kw):
264 super(FlexibleRemunForm, self).__init__(*a, **kw)
265 self.fields['type'].widget = ReadOnlyChoiceWidget(choices=self.fields['type'].choices)
266
dc4b78a7
OL
267 def clean_devise(self):
268 devise = self.cleaned_data['devise']
67173010
OL
269 if devise.code == 'EUR':
270 return devise
5a1f75cb
EMS
271 implantation = ref.Implantation.objects.get(
272 id=self.data['implantation']
273 )
2455f48d 274 liste_taux = devise.tauxchange_set.order_by('-annee')
dc4b78a7 275 if len(liste_taux) == 0:
5a1f75cb
EMS
276 raise forms.ValidationError(
277 u"La devise %s n'a pas de taux pour l'implantation %s" %
278 (devise, implantation)
279 )
dc4b78a7
OL
280 else:
281 return devise
282
4718c21c
BS
283
284class GroupedInlineFormset(BaseInlineFormSet):
285
286 def set_groups(self, group_accessor):
287 """
288 group_accessor: A function that will get the key and name from
289 each form.
290 """
291
292 # Build group list.
293 self.groups = {}
294 # self.groups_and_forms = []
295 for form in self.forms:
296 group_key, group_name = group_accessor(form)
297 if not self.groups.has_key(group_key):
298 self.groups[group_key] = {
299 'name': group_name,
300 'forms': [],
301 }
302 self.groups[group_key]['forms'].append(form)
303 self.group_list = self.groups.values()
304
305
306def remun_formset_factory(parent_model,
307 model,
308 form=forms.ModelForm,
309 formset=GroupedInlineFormset,
310 fk_name=None,
311 fields=None,
312 exclude=None,
313 can_order=False,
314 can_delete=True,
315 max_num=None,
316 formfield_callback=None):
317 """
318 Returns an ``InlineFormSet`` for the given kwargs.
319
320 You must provide ``fk_name`` if ``model`` has more than one ``ForeignKey``
321 to ``parent_model``.
322 """
323 trs = rh.TypeRemuneration.objects.all()
324 extra = max_num = trs.count()
325 fk = _get_foreign_key(parent_model, model, fk_name=fk_name)
326 # enforce a max_num=1 when the foreign key to the parent model is unique.
327 if fk.unique:
328 max_num = 1
329 kwargs = {
330 'form': form,
331 'formfield_callback': formfield_callback,
332 'formset': formset,
333 'extra': extra,
334 'can_delete': can_delete,
335 'can_order': can_order,
336 'fields': fields,
337 'exclude': exclude,
338 'max_num': max_num,
339 }
340 FormSet = modelformset_factory(model, **kwargs)
341 FormSet.fk = fk
342
343 def grouper(form):
344 if 'type' in form.initial and form.initial['type']:
345 return (form.initial['type'].nature_remuneration,
346 form.initial['type'].nature_remuneration,
347 )
348
349 def __init__(inst, *a, **kw):
350 super(FormSet, inst).__init__(*a, **kw)
351
352 # Set initial data.
353 for form, tr in zip(inst.forms, trs):
354 form.initial = {
355 'type': tr,
356 }
357
358 # Set form grouping.
359 inst.set_groups(grouper)
360
361 FormSet.__init__ = __init__
362
363 return FormSet
364
365
366RemunForm = remun_formset_factory(
367 dae.Dossier, dae.Remuneration, form=FlexibleRemunForm
368 )
0a085c42 369
5a1f75cb 370
1b217058 371class PosteForm(forms.ModelForm):
5d680e84 372 """ Formulaire des postes. """
12c7f8a7 373
ea7adc69 374 # On ne propose que les services actifs
5a1f75cb
EMS
375 service = forms.ModelChoiceField(
376 queryset=rh.Service.objects.all(), required=True
377 )
ea7adc69 378
5a1f75cb 379 responsable = AutoCompleteSelectField('responsables', required=True)
12c7f8a7
OL
380 #responsable = forms.ModelChoiceField(
381 # queryset=rh.Poste.objects.select_related(depth=1))
382
383 # La liste des choix est laissée vide. Voir __init__ pour la raison.
384 poste = forms.ChoiceField(label="Nouveau poste ou évolution du poste",
385 choices=(), required=False)
11f22317 386
5a1f75cb
EMS
387 valeur_point_min = forms.ModelChoiceField(
388 queryset=rh.ValeurPoint.actuelles.all(), required=False
389 )
390 valeur_point_max = forms.ModelChoiceField(
391 queryset=rh.ValeurPoint.actuelles.all(), required=False
392 )
11f22317 393
5d680e84
NC
394 class Meta:
395 model = dae.Poste
c3be904d
OL
396 fields = ('type_intervention',
397 'poste', 'implantation', 'type_poste', 'service', 'nom',
154677c3 398 'responsable', 'local', 'expatrie', 'mise_a_disposition',
b15bf543 399 'appel', 'date_debut', 'date_fin',
5d680e84
NC
400 'regime_travail', 'regime_travail_nb_heure_semaine',
401 'classement_min', 'classement_max',
402 'valeur_point_min', 'valeur_point_max',
3d627bfd 403 'devise_min', 'devise_max',
5f61bccb
OL
404 'salaire_min', 'salaire_max',
405 'indemn_expat_min', 'indemn_expat_max',
406 'indemn_fct_min', 'indemn_fct_max',
407 'charges_patronales_min', 'charges_patronales_max',
5d680e84
NC
408 'autre_min', 'autre_max', 'devise_comparaison',
409 'comp_locale_min', 'comp_locale_max',
410 'comp_universite_min', 'comp_universite_max',
411 'comp_fonctionpub_min', 'comp_fonctionpub_max',
412 'comp_ong_min', 'comp_ong_max',
8fa94e8b 413 'comp_autre_min', 'comp_autre_max',
2e092e0c 414 'justification',
8fa94e8b 415 )
c3be904d
OL
416 widgets = dict(type_intervention=forms.RadioSelect(),
417 appel=forms.RadioSelect(),
3d627bfd 418 nom=forms.TextInput(attrs={'size': 60},),
e88caaf0
OL
419 date_debut=admin_widgets.AdminDateWidget(),
420 date_fin=admin_widgets.AdminDateWidget(),
2e092e0c 421 justification=forms.Textarea(attrs={'cols': 80},),
3d627bfd 422 #devise_min=forms.Select(attrs={'disabled':'disabled'}),
423 #devise_max=forms.Select(attrs={'disabled':'disabled'}),
424 )
5d680e84 425
c2458db6 426 def __init__(self, *args, **kwargs):
5d680e84
NC
427 """ Mise à jour dynamique du contenu du menu des postes.
428
429 Si on ne met le menu à jour de cette façon, à chaque instantiation du
430 formulaire, son contenu est mis en cache par le système et il ne
431 reflète pas les changements apportés par les ajouts, modifications,
432 etc...
433
139686f2
NC
434 Aussi, dans ce cas-ci, on ne peut pas utiliser un ModelChoiceField
435 car le "id" de chaque choix est spécial (voir _poste_choices).
436
5d680e84 437 """
c2458db6 438 request = kwargs.pop('request')
5d680e84 439 super(PosteForm, self).__init__(*args, **kwargs)
f258e4e7 440 self.fields['poste'].choices = self._poste_choices(request)
9c1ff333 441
5a1f75cb
EMS
442 self.fields['implantation'].choices = \
443 _implantation_choices(self, request)
5d680e84 444
cc3098d0
OL
445 # Quand le dae.Poste n'existe pas, on recherche dans les dossiers rhv1
446 if self.instance and self.instance.id is None:
447 dossiers = self.instance.get_dossiers()
448 if len(dossiers) > 0:
09aa8374 449 self.initial['service'] = dossiers[0].poste.service
9508a5b8 450
f258e4e7 451 def _poste_choices(self, request):
5d680e84 452 """ Menu déroulant pour les postes.
9c1ff333 453 Constitué des postes de RH
5d680e84 454 """
9c1ff333
OL
455 postes_rh = rh.Poste.objects.ma_region_ou_service(request.user).all()
456 postes_rh = postes_rh.select_related(depth=1)
5d680e84 457
98d51b59 458 return [('', 'Nouveau poste')] + \
9c1ff333
OL
459 sorted([('rh-%s' % p.id, label_poste_display(p)) for p in
460 postes_rh],
5d680e84 461 key=lambda t: t[1])
3ed49093 462
4dd75e7b
OL
463 def clean(self):
464 """
465 Validation conditionnelles de certains champs.
466 """
5a1f75cb 467 cleaned_data = self.cleaned_data
4dd75e7b 468
5a1f75cb
EMS
469 if cleaned_data.get("local") is False \
470 and cleaned_data.get("expatrie") is False:
471 msg = "Le poste doit au moins être ouvert localement " \
472 "ou aux expatriés"
f42c6e20
OL
473 self._errors["local"] = self.error_class([msg])
474 self._errors["expatrie"] = ''
475 raise forms.ValidationError(msg)
f42c6e20 476
4dd75e7b
OL
477 return cleaned_data
478
3ed49093 479
34950f36 480class ChoosePosteForm(forms.Form):
139686f2 481 class Meta:
139686f2
NC
482 fields = ('poste',)
483
484 # La liste des choix est laissée vide. Voir PosteForm.__init__.
34950f36
OL
485 postes_dae = forms.ChoiceField(choices=(), required=False)
486 postes_rh = forms.ChoiceField(choices=(), required=False)
139686f2 487
4ee6d70a 488 def __init__(self, request=None, *args, **kwargs):
139686f2 489 super(ChoosePosteForm, self).__init__(*args, **kwargs)
34950f36
OL
490 self.fields['postes_dae'].choices = self._poste_dae_choices(request)
491 self.fields['postes_rh'].choices = self._poste_rh_choices(request)
139686f2 492
34950f36
OL
493 def _poste_dae_choices(self, request):
494 """ Menu déroulant pour les postes."""
495 postes_dae = dae.Poste.objects.ma_region_ou_service(request.user) \
496 .exclude(etat__in=(POSTE_ETAT_FINALISE, )) \
497 .annotate(num_dae=Count('dae_dossiers')) \
498 .filter(num_dae=0) \
67ae0181 499 .order_by('implantation', '-date_debut', )
139686f2 500
98d51b59 501 return [('', '----------')] + \
34950f36
OL
502 [('dae-%s' % p.id, label_poste_display(p)) for p in postes_dae]
503
504 def _poste_rh_choices(self, request):
505 """ Menu déroulant pour les postes."""
80be36aa 506 postes_dae = dae.Poste.objects.exclude(etat__in=(POSTE_ETAT_FINALISE, ))
bed0c4c9 507 today = datetime.date.today()
80be36aa 508 id_poste_dae_commences = [p.id_rh_id for p in postes_dae if p.id_rh is not None]
34950f36 509 postes_rh = rh.Poste.objects.ma_region_ou_service(request.user) \
80be36aa 510 .exclude(id__in=id_poste_dae_commences) \
bed0c4c9
BS
511 .filter(Q(date_debut__lte=today) &
512 (Q(date_fin__gte=today) |
513 Q(date_fin__isnull=True))
514 ) \
67ae0181 515 .order_by('implantation', '-date_debut', )
34950f36
OL
516
517 return [('', '----------')] + \
518 [('rh-%s' % p.id, label_poste_display(p)) for p in postes_rh]
139686f2 519
80be36aa
OL
520 def clean(self):
521 cleaned_data = super(ChoosePosteForm, self).clean()
522 postes_dae = cleaned_data.get("postes_dae")
523 postes_rh = cleaned_data.get("postes_rh")
524 if (postes_dae is u"" and postes_rh is u"") or \
525 (postes_dae is not u"" and postes_rh is not u""):
526 raise forms.ValidationError("Choisissez un poste DAE ou un poste RH")
527 return cleaned_data
528
529 def redirect(self):
530 poste_dae_key = self.cleaned_data.get("postes_dae")
531 if poste_dae_key is not u"":
532 return redirect(reverse('embauche', args=(poste_dae_key,)))
533 poste_rh_key = self.cleaned_data.get("postes_rh")
534 if poste_rh_key is not u"":
67ae0181 535 return redirect("%s?creer_dossier_dae='M'" % reverse('poste', args=(poste_rh_key,)))
139686f2 536
139686f2
NC
537class EmployeForm(forms.ModelForm):
538 """ Formulaire des employés. """
539 class Meta:
540 model = dae.Employe
541 fields = ('employe', 'nom', 'prenom', 'genre')
542
543 # La liste des choix est laissée vide. Voir Poste.__init__ pour la raison.
544 employe = forms.ChoiceField(choices=(), required=False)
545
ac6235f6 546 def __init__(self, *args, **kwargs):
139686f2 547 """ Mise à jour dynamique du contenu du menu des employés. """
ac6235f6 548 request = kwargs.pop('request', None)
139686f2 549 super(EmployeForm, self).__init__(*args, **kwargs)
f258e4e7 550 self.fields['employe'].choices = _employe_choices(self, request)
139686f2 551
139686f2 552
139686f2
NC
553class DossierForm(forms.ModelForm):
554 """ Formulaire des dossiers. """
555 class Meta:
5a1f75cb 556 exclude = ('etat', 'employe', 'poste', 'date_debut',)
139686f2 557 model = dae.Dossier
4d25e2ba 558 widgets = dict(statut_residence=forms.RadioSelect(),
0e0aeb7e
OL
559 contrat_date_debut=admin_widgets.AdminDateWidget(),
560 contrat_date_fin=admin_widgets.AdminDateWidget(),
4d25e2ba 561 )
e6f52402 562
3799cafc 563WF_HELP_TEXT = ""
e0b93e3a 564
5a1f75cb 565
e6f52402 566class PosteWorkflowForm(WorkflowFormMixin):
56589624 567 bouton_libelles = POSTE_ETATS_BOUTONS
5a1f75cb 568
e6f52402
OL
569 class Meta:
570 fields = ('etat', )
571 model = dae.Poste
9536ea21 572
e0b93e3a 573 def __init__(self, *args, **kwargs):
e54b7d5d 574 super(PosteWorkflowForm, self).__init__(*args, **kwargs)
e0b93e3a
OL
575 self.fields['etat'].help_text = WF_HELP_TEXT
576
577
e6f52402 578class DossierWorkflowForm(WorkflowFormMixin):
5a1f75cb
EMS
579 bouton_libelles = POSTE_ETATS_BOUTONS # meme workflow que poste...
580
e6f52402 581 class Meta:
9e40cfbe 582 fields = ('etat', )
e6f52402 583 model = dae.Dossier
e0b93e3a
OL
584
585 def __init__(self, *args, **kwargs):
e54b7d5d 586 super(DossierWorkflowForm, self).__init__(*args, **kwargs)
e0b93e3a 587 self.fields['etat'].help_text = WF_HELP_TEXT
e54b7d5d 588 self._etat_initial = self.instance.etat
e0b93e3a 589
e54b7d5d
EMS
590 def save(self):
591 super(DossierWorkflowForm, self).save()
592 poste = self.instance.poste
66fefd2f
OL
593
594 # créer le commentaire automatique pour le poste associé
595 commentaire = WorkflowCommentaire()
596 commentaire.content_object = poste
597 texte = u"Validation automatique à travers le dossier [%s] de %s\n%s" %(
598 self.instance.id,
599 self.instance,
600 self.data.get('commentaire', ''),
601 )
602 commentaire.texte = texte
603 commentaire.etat_initial = self.instance._etat_courant
604 commentaire.etat_final = self.instance.etat
605 commentaire.owner = self.request.user
606 commentaire.save()
607
608 # force l'état du poste
609 poste.etat = self.instance.etat
610 poste.save()
9536ea21 611
5a1f75cb 612
9536ea21
EMS
613class ContratForm(forms.ModelForm):
614
615 class Meta:
9dfa4296 616 fields = ('type_contrat', 'fichier', )
9536ea21
EMS
617 model = dae.Contrat
618
5a1f75cb 619
c3f0b49f
EMS
620class DAENumeriseeForm(forms.ModelForm):
621
622 class Meta:
623 model = dae.Dossier
624 fields = ('dae_numerisee',)
cbfd7bd4
EMS
625
626
627class DAEFinaliseesSearchForm(forms.Form):
628 q = forms.CharField(
629 label='Recherche', required=False,
630 widget=forms.TextInput(attrs={'size': 40})
631 )
632 importees = forms.ChoiceField(
633 label='Importation', required=False, choices=(
634 ('', ''),
635 ('oui', 'DAE importées seulement'),
636 ('non', 'DAE non-importées seulement'),
637 )
638 )