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