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