#1562, #1552, #1549, #1535
[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 from utils import is_user_dans_services_centraux
6
7 def safe_create_groupe(name):
8 """
9 Création d'un groupe prédéfini. Retourne None, quand la création
10 ne peut se faire. (C'est le cas au syncdb, quand la table de groupe
11 n'a pas été crée encore).
12 """
13 try:
14 grp, created = Group.objects.get_or_create(name=name)
15 except:
16 return None
17 return grp
18
19 # Groupes impliqués dans le Worflow
20 grp_correspondants_rh = safe_create_groupe(name='Correspondants RH')
21 grp_administrateurs = safe_create_groupe(name='Administrateurs')
22 grp_directeurs_bureau = safe_create_groupe(name='Directeurs de bureau')
23 grp_drh = safe_create_groupe(name='DRH')
24 grp_accior = safe_create_groupe(name='ACCIOR')
25 grp_afb = safe_create_groupe(name='AFB')
26 grp_haute_direction = safe_create_groupe(name='Haute direction')
27 grp_service_utilisateurs = safe_create_groupe(name='Service utilisateurs')
28
29 dae_groupes = (grp_administrateurs, grp_directeurs_bureau, grp_drh,
30 grp_accior, grp_afb, grp_haute_direction, grp_service_utilisateurs,
31 grp_correspondants_rh, )
32
33 # codes états
34 POSTE_ETAT_REFUSE = 'REFUSE'
35 POSTE_ETAT_BROUILLON = 'BROUILLON'
36 POSTE_ETAT_ADMINISTRATEUR = 'ADMINISTRATEUR'
37 POSTE_ETAT_DIRECTEUR_BUREAU = 'DIRECTEUR_BUREAU'
38 POSTE_ETAT_SERVICE_UTILISATEURS = 'SRV_UTILISATEURS'
39 POSTE_ETAT_DRH_CONTROLE = 'DRH_CONTROLE'
40 POSTE_ETAT_ACCIOR = 'ACCIOR'
41 POSTE_ETAT_AFB = 'AFB'
42 POSTE_ETAT_HAUTE_DIRECTION = 'HAUTE_DIRECTION'
43 POSTE_ETAT_DRH_FINALISATION = 'DRH_FINALISATION'
44
45 #codes actions
46 POSTE_ACTION_ENVOYER_REFUSE = POSTE_ETAT_REFUSE
47 POSTE_ACTION_ENVOYER_BROUILLON = POSTE_ETAT_BROUILLON
48 POSTE_ACTION_ENVOYER_ADMINISTRATEUR = POSTE_ETAT_ADMINISTRATEUR
49 POSTE_ACTION_ENVOYER_DIRECTEUR_BUREAU = POSTE_ETAT_DIRECTEUR_BUREAU
50 POSTE_ACTION_ENVOYER_SRV_UTILISATEURS = POSTE_ETAT_SERVICE_UTILISATEURS
51 POSTE_ACTION_ENVOYER_DRH_CONTROLE = POSTE_ETAT_DRH_CONTROLE
52 POSTE_ACTION_ENVOYER_ACCIOR = POSTE_ETAT_ACCIOR
53 POSTE_ACTION_ENVOYER_AFB = POSTE_ETAT_AFB
54 POSTE_ACTION_ENVOYER_HAUTE_DIRECTION = POSTE_ETAT_HAUTE_DIRECTION
55 POSTE_ACTION_ENVOYER_DRH_FINALISATION = POSTE_ETAT_DRH_FINALISATION
56
57 #libellés états
58 POSTE_ETATS = {
59 POSTE_ETAT_REFUSE : u"Refusé",
60 POSTE_ETAT_BROUILLON : u"En rédaction",
61 POSTE_ETAT_ADMINISTRATEUR : u"Validation de l'adminstrateur",
62 POSTE_ETAT_DIRECTEUR_BUREAU : u"Directeur de bureau",
63 POSTE_ETAT_SERVICE_UTILISATEURS : u"Service utilisateurs",
64 POSTE_ETAT_DRH_CONTROLE : u"Validation DRH",
65 POSTE_ETAT_ACCIOR : u"ACCIOR",
66 POSTE_ETAT_AFB : u"AFB",
67 POSTE_ETAT_HAUTE_DIRECTION : u"Validation : Secrétaire général / Recteur",
68 POSTE_ETAT_DRH_FINALISATION : u'Retour à la DRH et région',
69 }
70
71 #libellés états pour boutons
72 POSTE_ETATS_BOUTONS = {
73 POSTE_ETAT_REFUSE : u"Refuser",
74 POSTE_ETAT_DIRECTEUR_BUREAU : u"Envoyer au directeur de bureau",
75 POSTE_ETAT_SERVICE_UTILISATEURS : u"Envoyer au service utilisateurs",
76 POSTE_ETAT_ADMINISTRATEUR : u"Envoyer à l'adminstrateur",
77 POSTE_ETAT_DRH_CONTROLE : u"Envoyer à la DRH (validation)",
78 POSTE_ETAT_ACCIOR : u"Envoyer à l'ACCIOR",
79 POSTE_ETAT_AFB : u"Envoyer à l'AFB",
80 POSTE_ETAT_HAUTE_DIRECTION : u"Envoyer à la haute direction",
81 POSTE_ETAT_DRH_FINALISATION : u'Envoyer à la DRH (traitement)',
82 }
83
84 # définition du worflow séquentiel
85 POSTE_ACTIONS = {
86 POSTE_ACTION_ENVOYER_REFUSE : {
87 'nom' : u'Refuser',
88 'etat_initial' : (POSTE_ETAT_DIRECTEUR_BUREAU, POSTE_ETAT_ADMINISTRATEUR, POSTE_ETAT_SERVICE_UTILISATEURS, POSTE_ETAT_DRH_CONTROLE, POSTE_ETAT_HAUTE_DIRECTION),
89 'etat_final' : POSTE_ETAT_REFUSE,
90 },
91 POSTE_ACTION_ENVOYER_BROUILLON : {
92 'nom' : u'Créer',
93 'etat_initial' : None,
94 'etat_final' : POSTE_ETAT_BROUILLON,
95 },
96 POSTE_ACTION_ENVOYER_ADMINISTRATEUR : {
97 'nom' : u'Envoyer',
98 'etat_initial' : (POSTE_ETAT_BROUILLON, POSTE_ETAT_REFUSE, ),
99 'etat_final' : POSTE_ETAT_ADMINISTRATEUR,
100 },
101 POSTE_ACTION_ENVOYER_SRV_UTILISATEURS : {
102 'nom' : u'Envoyer',
103 'etat_initial' : (POSTE_ETAT_ADMINISTRATEUR, POSTE_ETAT_REFUSE, ),
104 'etat_final' : POSTE_ETAT_SERVICE_UTILISATEURS,
105 },
106 POSTE_ACTION_ENVOYER_DIRECTEUR_BUREAU : {
107 'nom' : u'Envoyer',
108 'etat_initial' : (POSTE_ETAT_ADMINISTRATEUR, POSTE_ETAT_REFUSE,),
109 'etat_final' : POSTE_ETAT_DIRECTEUR_BUREAU,
110 },
111 POSTE_ACTION_ENVOYER_DRH_CONTROLE : {
112 'nom' : u'Envoyer',
113 'etat_initial' : (POSTE_ETAT_DIRECTEUR_BUREAU, POSTE_ETAT_SERVICE_UTILISATEURS, POSTE_ETAT_REFUSE, ),
114 'etat_final' : POSTE_ETAT_DRH_CONTROLE,
115 },
116 POSTE_ACTION_ENVOYER_ACCIOR : {
117 'nom' : u'Envoyer',
118 'etat_initial' : (POSTE_ETAT_DRH_CONTROLE, POSTE_ETAT_REFUSE, ),
119 'etat_final' : POSTE_ETAT_ACCIOR,
120 },
121 POSTE_ACTION_ENVOYER_AFB : {
122 'nom' : u'Envoyer',
123 'etat_initial' : (POSTE_ETAT_ACCIOR, POSTE_ETAT_REFUSE, ),
124 'etat_final' : POSTE_ETAT_AFB,
125 },
126 POSTE_ACTION_ENVOYER_HAUTE_DIRECTION : {
127 'nom' : u'Envoyer',
128 'etat_initial' : (POSTE_ETAT_AFB, POSTE_ETAT_REFUSE, ),
129 'etat_final' : POSTE_ETAT_HAUTE_DIRECTION,
130 },
131 POSTE_ACTION_ENVOYER_DRH_FINALISATION : {
132 'nom' : u'Envoyer',
133 'etat_initial' : (POSTE_ETAT_HAUTE_DIRECTION, POSTE_ETAT_REFUSE, ),
134 'etat_final' : POSTE_ETAT_DRH_FINALISATION,
135 },
136 }
137
138
139 def acces_etat_refuse(f):
140 """
141 Personne ne peut manipuler quelque chose à l'état refusé excepté la DRH et les administrateurs
142 """
143 def inner(obj, action, request):
144 if obj.etat != 'REFUSE':
145 return f(obj, action, request)
146 user_groupes = request.user.groups.all()
147 if grp_drh in user_groupes or grp_administrateurs in user_groupes:
148 return f(obj, action, request)
149 else:
150 return False
151 return inner
152
153 class PosteWorkflow(WorkflowMixin):
154 etat_initial = POSTE_ETAT_BROUILLON
155 etats = POSTE_ETATS
156 actions = POSTE_ACTIONS
157
158 class Meta:
159 abstract = True
160
161 def acces_refuse(self, action, request):
162 user_groupes = request.user.groups.all()
163 if grp_accior in user_groupes or grp_afb in user_groupes:
164 return False
165
166 user_groupes = request.user.groups.all()
167 for g, etats in MAP_GROUPE_ETATS_A_FAIRE.items():
168 if g in user_groupes and self.etat in etats:
169 return True
170 return False
171
172 @acces_etat_refuse
173 def acces_directeur_bureau(self, action, request):
174 if is_user_dans_services_centraux(request.user):
175 return False
176 for g in request.user.groups.all():
177 if g in (grp_administrateurs, grp_drh,):
178 return True
179 return False
180
181 @acces_etat_refuse
182 def acces_administrateur(self, action, request):
183 for g in request.user.groups.all():
184 if g in (grp_correspondants_rh, grp_drh,):
185 return True
186 return False
187
188 @acces_etat_refuse
189 def acces_drh_controle(self, action, request):
190 for g in request.user.groups.all():
191 if g in (grp_directeurs_bureau, grp_service_utilisateurs, grp_drh,):
192 return True
193 return False
194
195 @acces_etat_refuse
196 def acces_srv_utilisateurs(self, action, request):
197 if not is_user_dans_services_centraux(request.user):
198 return False
199 for g in request.user.groups.all():
200 if g in (grp_administrateurs, grp_drh, ):
201 return True
202 return False
203
204 @acces_etat_refuse
205 def acces_accior(self, action, request):
206 for g in request.user.groups.all():
207 if g in (grp_drh, ):
208 return True
209 return False
210
211 @acces_etat_refuse
212 def acces_afb(self, action, request):
213 for g in request.user.groups.all():
214 if g in (grp_accior, grp_drh, ):
215 return True
216 return False
217
218 @acces_etat_refuse
219 def acces_haute_direction(self, action, request):
220 for g in request.user.groups.all():
221 if g in (grp_afb, grp_drh, ):
222 return True
223 return False
224
225 @acces_etat_refuse
226 def acces_drh_finalisation(self, action, request):
227 for g in request.user.groups.all():
228 if g in (grp_haute_direction, grp_drh, ):
229 return True
230 return False
231
232
233 #codes actions
234 DOSSIER_ETAT_REFUSE = POSTE_ETAT_REFUSE
235 DOSSIER_ETAT_BROUILLON = POSTE_ETAT_BROUILLON
236 DOSSIER_ETAT_ADMINISTRATEUR = POSTE_ETAT_ADMINISTRATEUR
237 DOSSIER_ETAT_DIRECTEUR_BUREAU = POSTE_ETAT_DIRECTEUR_BUREAU
238 DOSSIER_ETAT_SERVICE_UTILISATEURS = POSTE_ETAT_SERVICE_UTILISATEURS
239 DOSSIER_ETAT_DRH_CONTROLE = POSTE_ETAT_DRH_CONTROLE
240 DOSSIER_ETAT_ACCIOR = POSTE_ETAT_ACCIOR
241 DOSSIER_ETAT_AFB = POSTE_ETAT_AFB
242 DOSSIER_ETAT_HAUTE_DIRECTION = POSTE_ETAT_HAUTE_DIRECTION
243 DOSSIER_ETAT_DRH_FINALISATION = POSTE_ETAT_DRH_FINALISATION
244
245 class DossierWorkflow(PosteWorkflow):
246
247 class Meta:
248 abstract = True
249
250 def save(self, force_insert=False, force_update=False, using=None):
251 """
252 Lorsqu'un dossier est retenu, on flag le poste pourvu
253 """
254 super(PosteWorkflow, self).save(force_insert, force_update, using)
255 if self.etat == DOSSIER_ETAT_DRH_FINALISATION:
256 self.poste.pourvu = True
257 self.poste.save()
258
259
260 MAP_GROUPE_ETATS_A_FAIRE = {
261 grp_correspondants_rh : (),
262 grp_service_utilisateurs : (POSTE_ETAT_SERVICE_UTILISATEURS, DOSSIER_ETAT_SERVICE_UTILISATEURS,),
263 grp_administrateurs : (POSTE_ETAT_ADMINISTRATEUR, DOSSIER_ETAT_ADMINISTRATEUR, ),
264 grp_directeurs_bureau : (POSTE_ETAT_DIRECTEUR_BUREAU, DOSSIER_ETAT_DIRECTEUR_BUREAU, ),
265 grp_drh : (POSTE_ETAT_DRH_CONTROLE, POSTE_ETAT_DRH_FINALISATION, DOSSIER_ETAT_DRH_CONTROLE, DOSSIER_ETAT_DRH_FINALISATION,),
266 grp_accior : (POSTE_ETAT_ACCIOR, DOSSIER_ETAT_ACCIOR, ),
267 grp_afb : (POSTE_ETAT_AFB, DOSSIER_ETAT_AFB, ),
268 grp_haute_direction : (POSTE_ETAT_HAUTE_DIRECTION, DOSSIER_ETAT_HAUTE_DIRECTION, ),
269 }
270
271
272 ETATS_EDITABLE = (POSTE_ETAT_REFUSE, POSTE_ETAT_BROUILLON, POSTE_ETAT_ADMINISTRATEUR, POSTE_ETAT_DRH_CONTROLE, POSTE_ETAT_DIRECTEUR_BUREAU, POSTE_ETAT_SERVICE_UTILISATEURS,
273 DOSSIER_ETAT_REFUSE, DOSSIER_ETAT_BROUILLON, DOSSIER_ETAT_ADMINISTRATEUR, DOSSIER_ETAT_DRH_CONTROLE, DOSSIER_ETAT_DIRECTEUR_BUREAU, DOSSIER_ETAT_SERVICE_UTILISATEURS,
274 )
275