fix #1570
[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 = (
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_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 user_groupes = request.user.groups.all()
170 if grp_accior in user_groupes or grp_afb in user_groupes:
171 return False
172
173 user_groupes = request.user.groups.all()
174 for g, etats in MAP_GROUPE_ETATS_A_FAIRE.items():
175 if g in user_groupes and self.etat in etats:
176 return True
177 return False
178
179 @acces_etat_refuse
180 def acces_directeur_bureau(self, action, request):
181 if is_user_dans_services_centraux(request.user):
182 return False
183 for g in request.user.groups.all():
184 if g in (grp_administrateurs, grp_drh,):
185 return True
186 return False
187
188 @acces_etat_refuse
189 def acces_administrateur(self, action, request):
190 for g in request.user.groups.all():
191 if g in (grp_correspondants_rh, grp_drh,):
192 return True
193 return False
194
195 @acces_etat_refuse
196 def acces_drh_controle(self, action, request):
197 for g in request.user.groups.all():
198 if g in (grp_directeurs_bureau, grp_service_utilisateurs, grp_drh,):
199 return True
200 return False
201
202 @acces_etat_refuse
203 def acces_srv_utilisateurs(self, action, request):
204 if not is_user_dans_services_centraux(request.user):
205 return False
206 for g in request.user.groups.all():
207 if g in (grp_administrateurs, grp_drh, ):
208 return True
209 return False
210
211 @acces_etat_refuse
212 def acces_accior(self, action, request):
213 for g in request.user.groups.all():
214 if g in (grp_drh, ):
215 return True
216 return False
217
218 @acces_etat_refuse
219 def acces_afb(self, action, request):
220 for g in request.user.groups.all():
221 if g in (grp_accior, grp_drh, ):
222 return True
223 return False
224
225 @acces_etat_refuse
226 def acces_haute_direction(self, action, request):
227 for g in request.user.groups.all():
228 if g in (grp_afb, grp_drh, ):
229 return True
230 return False
231
232 @acces_etat_refuse
233 def acces_drh_finalisation(self, action, request):
234 for g in request.user.groups.all():
235 if g in (grp_haute_direction, grp_drh, ):
236 return True
237 return False
238
239
240 #codes actions
241 DOSSIER_ETAT_REFUSE = POSTE_ETAT_REFUSE
242 DOSSIER_ETAT_BROUILLON = POSTE_ETAT_BROUILLON
243 DOSSIER_ETAT_ADMINISTRATEUR = POSTE_ETAT_ADMINISTRATEUR
244 DOSSIER_ETAT_DIRECTEUR_BUREAU = POSTE_ETAT_DIRECTEUR_BUREAU
245 DOSSIER_ETAT_SERVICE_UTILISATEURS = POSTE_ETAT_SERVICE_UTILISATEURS
246 DOSSIER_ETAT_DRH_CONTROLE = POSTE_ETAT_DRH_CONTROLE
247 DOSSIER_ETAT_ACCIOR = POSTE_ETAT_ACCIOR
248 DOSSIER_ETAT_AFB = POSTE_ETAT_AFB
249 DOSSIER_ETAT_HAUTE_DIRECTION = POSTE_ETAT_HAUTE_DIRECTION
250 DOSSIER_ETAT_DRH_FINALISATION = POSTE_ETAT_DRH_FINALISATION
251
252 class DossierWorkflow(PosteWorkflow):
253
254 class Meta:
255 abstract = True
256
257 def save(self, force_insert=False, force_update=False, using=None):
258 """
259 Lorsqu'un dossier est retenu, on flag le poste pourvu
260 """
261 super(PosteWorkflow, self).save(force_insert, force_update, using)
262 if self.etat == DOSSIER_ETAT_DRH_FINALISATION:
263 self.poste.pourvu = True
264 self.poste.save()
265
266
267 MAP_GROUPE_ETATS_A_FAIRE = {
268 grp_correspondants_rh : (POSTE_ETAT_BROUILLON, DOSSIER_ETAT_BROUILLON, ),
269 grp_service_utilisateurs : (POSTE_ETAT_SERVICE_UTILISATEURS, DOSSIER_ETAT_SERVICE_UTILISATEURS,),
270 grp_administrateurs : (POSTE_ETAT_ADMINISTRATEUR, DOSSIER_ETAT_ADMINISTRATEUR, ),
271 grp_directeurs_bureau : (POSTE_ETAT_DIRECTEUR_BUREAU, DOSSIER_ETAT_DIRECTEUR_BUREAU, ),
272 grp_drh : (POSTE_ETAT_DRH_CONTROLE, POSTE_ETAT_DRH_FINALISATION, DOSSIER_ETAT_DRH_CONTROLE, DOSSIER_ETAT_DRH_FINALISATION,),
273 grp_accior : (POSTE_ETAT_ACCIOR, DOSSIER_ETAT_ACCIOR, ),
274 grp_afb : (POSTE_ETAT_AFB, DOSSIER_ETAT_AFB, ),
275 grp_haute_direction : (POSTE_ETAT_HAUTE_DIRECTION, DOSSIER_ETAT_HAUTE_DIRECTION, ),
276 }
277
278
279 ETATS_EDITABLE = (POSTE_ETAT_REFUSE, POSTE_ETAT_BROUILLON, POSTE_ETAT_ADMINISTRATEUR, POSTE_ETAT_DRH_CONTROLE, POSTE_ETAT_DIRECTEUR_BUREAU, POSTE_ETAT_SERVICE_UTILISATEURS,
280 DOSSIER_ETAT_REFUSE, DOSSIER_ETAT_BROUILLON, DOSSIER_ETAT_ADMINISTRATEUR, DOSSIER_ETAT_DRH_CONTROLE, DOSSIER_ETAT_DIRECTEUR_BUREAU, DOSSIER_ETAT_SERVICE_UTILISATEURS,
281 )
282