055b8a71adbc413e83f82a89cb1306be10db7daa
[auf_rh_dae.git] / project / dae / workflow.py
1 # -*- encoding: utf-8 -*-
2
3 from django.contrib.auth.models import Group
4 from auf.django.workflow.models import WorkflowMixin
5
6 def safe_create_groupe(name):
7 """
8 Création d'un groupe prédéfini. Retourne None, quand la création
9 ne peut se faire. (C'est le cas au syncdb, quand la table de groupe
10 n'a pas été crée encore).
11 """
12 try:
13 grp, created = Group.objects.get_or_create(name=name)
14 except:
15 return None
16 return grp
17
18 # Groupes impliqués dans le Worflow
19 grp_administrateurs = safe_create_groupe(name='Administrateurs')
20 grp_gestionnaires = safe_create_groupe(name='Gestionnaires')
21 grp_directeurs_bureau = safe_create_groupe(name='Directeurs de bureau')
22 grp_drh = safe_create_groupe(name='DRH')
23 grp_pole_financier = safe_create_groupe(name='Pôle financier')
24 grp_haute_direction = safe_create_groupe(name='Haute direction')
25 grp_service_utilisateurs = safe_create_groupe(name='Service utilisateurs')
26 grp_directeurs_service = safe_create_groupe(name='Directeurs de service / pôle')
27 grp_correspondants_rh = safe_create_groupe(name='Correspondants RH')
28
29 dae_groupes = (grp_administrateurs, grp_gestionnaires, grp_directeurs_bureau, grp_drh,
30 grp_pole_financier, grp_haute_direction, grp_service_utilisateurs,
31 grp_directeurs_service, grp_correspondants_rh, )
32
33 # codes états
34 POSTE_ETAT_REFUSE = 'REFUSE'
35 POSTE_ETAT_BROUILLON = 'BROUILLON'
36 POSTE_ETAT_DIRECTEUR_BUREAU_OU_SERVICE = 'DIRECTEUR_BUR_SRV'
37 POSTE_ETAT_ADMINISTRATEUR = 'ADMINISTRATEUR'
38 POSTE_ETAT_DRH_CONTROLE = 'DRH_CONTROLE'
39 POSTE_ETAT_POLE_FINANCIER = 'FINANCE'
40 POSTE_ETAT_HAUTE_DIRECTION = 'HAUTE_DIRECTION'
41 POSTE_ETAT_DRH_FINALISATION = 'DRH_FINALISATION'
42
43 #codes actions
44 POSTE_ACTION_ENVOYER_REFUSE = POSTE_ETAT_REFUSE
45 POSTE_ACTION_ENVOYER_BROUILLON = POSTE_ETAT_BROUILLON
46 POSTE_ACTION_ENVOYER_DIRECTEUR_BUREAU_OU_SERVICE = POSTE_ETAT_DIRECTEUR_BUREAU_OU_SERVICE
47 POSTE_ACTION_ENVOYER_ADMINISTRATEUR = POSTE_ETAT_ADMINISTRATEUR
48 POSTE_ACTION_ENVOYER_DRH_CONTROLE = POSTE_ETAT_DRH_CONTROLE
49 POSTE_ACTION_ENVOYER_POLE_FINANCIER = POSTE_ETAT_POLE_FINANCIER
50 POSTE_ACTION_ENVOYER_HAUTE_DIRECTION = POSTE_ETAT_HAUTE_DIRECTION
51 POSTE_ACTION_ENVOYER_DRH_FINALISATION = POSTE_ETAT_DRH_FINALISATION
52
53 #libellés états
54 POSTE_ETATS = {
55 POSTE_ETAT_REFUSE : u"Refusé",
56 POSTE_ETAT_BROUILLON : u"En rédaction",
57 POSTE_ETAT_DIRECTEUR_BUREAU_OU_SERVICE : u"Directeur de bureau, pôle ou service",
58 POSTE_ETAT_ADMINISTRATEUR : u"Validation de l'adminstrateur",
59 POSTE_ETAT_DRH_CONTROLE : u"Validation DRH",
60 POSTE_ETAT_POLE_FINANCIER : u"Pôle finances",
61 POSTE_ETAT_HAUTE_DIRECTION : u"Validation : Secrétaire général / Recteur",
62 POSTE_ETAT_DRH_FINALISATION : u'Retour à la DRH et région',
63 }
64
65 #libellés états pour boutons
66 POSTE_ETATS_BOUTONS = {
67 POSTE_ETAT_REFUSE : u"Refuser",
68 POSTE_ETAT_DIRECTEUR_BUREAU_OU_SERVICE : u"Envoyer au directeur de bureau, pôle ou service",
69 POSTE_ETAT_ADMINISTRATEUR : u"Envoyer à l'adminstrateur",
70 POSTE_ETAT_DRH_CONTROLE : u"Envoyer à la DRH (validation)",
71 POSTE_ETAT_POLE_FINANCIER : u"Envoyer au pôle finances",
72 POSTE_ETAT_HAUTE_DIRECTION : u"Envoyer à la haute direction",
73 POSTE_ETAT_DRH_FINALISATION : u'Envoyer à la DRH (traitement)',
74 }
75
76 # définition du worflow séquentiel
77 POSTE_ACTIONS = {
78 POSTE_ACTION_ENVOYER_REFUSE : {
79 'nom' : u'Refuser',
80 'etat_initial' : (POSTE_ETAT_DIRECTEUR_BUREAU_OU_SERVICE, POSTE_ETAT_ADMINISTRATEUR, POSTE_ETAT_DRH_CONTROLE, POSTE_ETAT_POLE_FINANCIER, POSTE_ETAT_HAUTE_DIRECTION),
81 'etat_final' : POSTE_ETAT_REFUSE,
82 },
83 POSTE_ACTION_ENVOYER_BROUILLON : {
84 'nom' : u'Créer',
85 'etat_initial' : None,
86 'etat_final' : POSTE_ETAT_BROUILLON,
87 },
88 POSTE_ACTION_ENVOYER_DIRECTEUR_BUREAU_OU_SERVICE : {
89 'nom' : u'Envoyer',
90 'etat_initial' : POSTE_ETAT_BROUILLON,
91 'etat_final' : POSTE_ETAT_DIRECTEUR_BUREAU_OU_SERVICE,
92 },
93 POSTE_ACTION_ENVOYER_ADMINISTRATEUR : {
94 'nom' : u'Envoyer',
95 'etat_initial' : (POSTE_ETAT_REFUSE, POSTE_ETAT_DIRECTEUR_BUREAU_OU_SERVICE),
96 'etat_final' : POSTE_ETAT_ADMINISTRATEUR,
97 },
98 POSTE_ACTION_ENVOYER_DRH_CONTROLE : {
99 'nom' : u'Envoyer',
100 'etat_initial' : (POSTE_ETAT_REFUSE, POSTE_ETAT_DIRECTEUR_BUREAU_OU_SERVICE, POSTE_ETAT_ADMINISTRATEUR, ),
101 'etat_final' : POSTE_ETAT_DRH_CONTROLE,
102 },
103 POSTE_ACTION_ENVOYER_POLE_FINANCIER : {
104 'nom' : u'Envoyer',
105 'etat_initial' : (POSTE_ETAT_REFUSE, POSTE_ETAT_DRH_CONTROLE, ),
106 'etat_final' : POSTE_ETAT_POLE_FINANCIER,
107 },
108 POSTE_ACTION_ENVOYER_HAUTE_DIRECTION : {
109 'nom' : u'Envoyer',
110 'etat_initial' : (POSTE_ETAT_REFUSE, POSTE_ETAT_POLE_FINANCIER, ),
111 'etat_final' : POSTE_ETAT_HAUTE_DIRECTION,
112 },
113 POSTE_ACTION_ENVOYER_DRH_FINALISATION : {
114 'nom' : u'Envoyer',
115 'etat_initial' : (POSTE_ETAT_REFUSE, POSTE_ETAT_HAUTE_DIRECTION, ),
116 'etat_final' : POSTE_ETAT_DRH_FINALISATION,
117 },
118 }
119
120
121 def refuse_sauf_pour_drh(f):
122 """
123 Personne ne peut manipuler quelque chose à l'état refusé excepté la DRH
124 """
125 def inner(obj, action, request):
126 if obj.etat != 'REFUSE':
127 return f(obj, action, request)
128 if grp_drh in request.user.groups.all():
129 return f(obj, action, request)
130 else:
131 return False
132 return inner
133
134 class PosteWorkflow(WorkflowMixin):
135 etat_initial = POSTE_ETAT_BROUILLON
136 etats = POSTE_ETATS
137 actions = POSTE_ACTIONS
138
139 class Meta:
140 abstract = True
141
142 def acces_refuse(self, action, request):
143 if grp_pole_financier in request.user.groups.all():
144 return False
145
146 user_groupes = request.user.groups.all()
147 for g, etats in MAP_GROUPE_ETATS_A_FAIRE.items():
148 if g in user_groupes and self.etat in etats:
149 return True
150 return False
151
152 @refuse_sauf_pour_drh
153 def acces_directeur_bur_srv(self, action, request):
154 for g in request.user.groups.all():
155 if g in (grp_administrateurs, grp_gestionnaires, grp_service_utilisateurs, grp_correspondants_rh, grp_drh,):
156 return True
157 return False
158
159 @refuse_sauf_pour_drh
160 def acces_administrateur(self, action, request):
161 for g in request.user.groups.all():
162 if g in (grp_directeurs_service, grp_drh,):
163 return True
164 return False
165
166 @refuse_sauf_pour_drh
167 def acces_drh_controle(self, action, request):
168 for g in request.user.groups.all():
169 if g in (grp_directeurs_bureau, grp_administrateurs, grp_drh,):
170 return True
171 return False
172
173 @refuse_sauf_pour_drh
174 def acces_finance(self, action, request):
175 for g in request.user.groups.all():
176 if g in (grp_drh, ):
177 return True
178 return False
179
180 @refuse_sauf_pour_drh
181 def acces_haute_direction(self, action, request):
182 for g in request.user.groups.all():
183 if g in (grp_pole_financier, grp_drh, ):
184 return True
185 return False
186
187 @refuse_sauf_pour_drh
188 def acces_drh_finalisation(self, action, request):
189 for g in request.user.groups.all():
190 if g in (grp_haute_direction, grp_drh, ):
191 return True
192 return False
193
194
195 #codes actions
196 DOSSIER_ETAT_REFUSE = POSTE_ETAT_REFUSE
197 DOSSIER_ETAT_BROUILLON = POSTE_ETAT_BROUILLON
198 DOSSIER_ETAT_DIRECTEUR_BUREAU_OU_SERVICE = POSTE_ETAT_DIRECTEUR_BUREAU_OU_SERVICE
199 DOSSIER_ETAT_ADMINISTRATEUR = POSTE_ETAT_ADMINISTRATEUR
200 DOSSIER_ETAT_DRH_CONTROLE = POSTE_ETAT_DRH_CONTROLE
201 DOSSIER_ETAT_POLE_FINANCIER = POSTE_ETAT_POLE_FINANCIER
202 DOSSIER_ETAT_HAUTE_DIRECTION = POSTE_ETAT_HAUTE_DIRECTION
203 DOSSIER_ETAT_DRH_FINALISATION = POSTE_ETAT_DRH_FINALISATION
204
205 class DossierWorkflow(PosteWorkflow):
206
207 class Meta:
208 abstract = True
209
210 def save(self, force_insert=False, force_update=False, using=None):
211 """
212 Lorsqu'un dossier est retenu, on flag le poste pourvu
213 """
214 super(PosteWorkflow, self).save(force_insert, force_update, using)
215 if self.etat == DOSSIER_ETAT_DRH_FINALISATION:
216 self.poste.pourvu = True
217 self.poste.save()
218
219
220 MAP_GROUPE_ETATS_A_FAIRE = {
221 grp_gestionnaires : (),
222 grp_service_utilisateurs : (),
223 grp_correspondants_rh : (),
224 grp_administrateurs : (POSTE_ETAT_ADMINISTRATEUR, DOSSIER_ETAT_ADMINISTRATEUR,),
225 grp_directeurs_bureau : (POSTE_ETAT_DIRECTEUR_BUREAU_OU_SERVICE, DOSSIER_ETAT_DIRECTEUR_BUREAU_OU_SERVICE,),
226 grp_drh : (POSTE_ETAT_DRH_CONTROLE, POSTE_ETAT_DRH_FINALISATION, DOSSIER_ETAT_DRH_CONTROLE, DOSSIER_ETAT_DRH_FINALISATION,),
227 grp_pole_financier : (POSTE_ETAT_POLE_FINANCIER, DOSSIER_ETAT_POLE_FINANCIER, ),
228 grp_haute_direction : (POSTE_ETAT_HAUTE_DIRECTION, DOSSIER_ETAT_HAUTE_DIRECTION, ),
229 grp_directeurs_service : (POSTE_ETAT_DIRECTEUR_BUREAU_OU_SERVICE, DOSSIER_ETAT_DIRECTEUR_BUREAU_OU_SERVICE,),
230 }
231
232
233 ETATS_EDITABLE = (POSTE_ETAT_BROUILLON, POSTE_ETAT_ADMINISTRATEUR, POSTE_ETAT_DRH_CONTROLE, POSTE_ETAT_DIRECTEUR_BUREAU_OU_SERVICE,
234 DOSSIER_ETAT_BROUILLON, DOSSIER_ETAT_ADMINISTRATEUR, DOSSIER_ETAT_DRH_CONTROLE, DOSSIER_ETAT_DIRECTEUR_BUREAU_OU_SERVICE,
235 )
236