1
|
|
|
<?php |
2
|
|
|
/************************************************************************ |
3
|
|
|
* OVIDENTIA http://www.ovidentia.org * |
4
|
|
|
************************************************************************ |
5
|
|
|
* Copyright (c) 2003 by CANTICO ( http://www.cantico.fr ) * |
6
|
|
|
* * |
7
|
|
|
* This file is part of Ovidentia. * |
8
|
|
|
* * |
9
|
|
|
* Ovidentia is free software; you can redistribute it and/or modify * |
10
|
|
|
* it under the terms of the GNU General Public License as published by * |
11
|
|
|
* the Free Software Foundation; either version 2, or (at your option) * |
12
|
|
|
* any later version. * |
13
|
|
|
* * |
14
|
|
|
* This program is distributed in the hope that it will be useful, but * |
15
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of * |
16
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * |
17
|
|
|
* See the GNU General Public License for more details. * |
18
|
|
|
* * |
19
|
|
|
* You should have received a copy of the GNU General Public License * |
20
|
|
|
* along with this program; if not, write to the Free Software * |
21
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,* |
22
|
|
|
* USA. * |
23
|
|
|
************************************************************************/ |
24
|
|
|
|
25
|
|
|
|
26
|
|
|
require_once dirname(__FILE__).'/record.class.php'; |
27
|
|
|
require_once $GLOBALS['babInstallPath'].'utilit/wfincl.php'; |
28
|
|
|
|
29
|
|
|
|
30
|
|
|
|
31
|
|
|
|
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* A user request (entry, cet deposit, workperiod recover) |
35
|
|
|
* |
36
|
|
|
* @property int $id |
37
|
|
|
* @property int $id_user |
38
|
|
|
* @property int $idfai |
39
|
|
|
* @property string $status |
40
|
|
|
* @property int $id_approver |
41
|
|
|
* @property int $appr_notified |
42
|
|
|
* @property string $comment2 |
43
|
|
|
* @property int $todelete |
44
|
|
|
* @property int $firstconfirm |
45
|
|
|
* |
46
|
|
|
*/ |
47
|
|
|
abstract class absences_Request extends absences_Record |
48
|
|
|
{ |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* |
52
|
|
|
* @var absences_Agent |
53
|
|
|
*/ |
54
|
|
|
protected $agent; |
55
|
|
|
|
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* |
59
|
|
|
* @var absences_Movement |
60
|
|
|
*/ |
61
|
|
|
private $lastMovement; |
62
|
|
|
|
63
|
|
|
|
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* @param int $id |
67
|
|
|
* @return absences_Request |
68
|
|
|
*/ |
69
|
|
|
abstract static public function getById($id); |
70
|
|
|
|
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* @return absences_Agent |
74
|
|
|
*/ |
75
|
5 |
View Code Duplication |
public function getAgent() |
|
|
|
|
76
|
|
|
{ |
77
|
5 |
|
require_once dirname(__FILE__).'/agent.class.php'; |
78
|
|
|
|
79
|
5 |
|
if (!isset($this->agent)) |
80
|
5 |
|
{ |
81
|
5 |
|
$row = $this->getRow(); |
82
|
5 |
|
$this->agent = absences_Agent::getFromIdUser($row['id_user']); |
83
|
5 |
|
} |
84
|
|
|
|
85
|
5 |
|
return $this->agent; |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
|
89
|
|
|
|
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Method to sort requests by creation date |
93
|
|
|
*/ |
94
|
|
|
public function createdOn() |
95
|
|
|
{ |
96
|
|
|
return $this->createdOn; |
|
|
|
|
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* Method to sort requests by modification date |
101
|
|
|
*/ |
102
|
|
|
public function modifiedOn() |
103
|
|
|
{ |
104
|
|
|
return $this->modifiedOn; |
|
|
|
|
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* |
109
|
|
|
* @return string |
110
|
|
|
*/ |
111
|
|
|
public function getUserName() |
112
|
|
|
{ |
113
|
|
|
return bab_getUserName($this->id_user); |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
|
117
|
|
|
protected function labelledValue($title, $value) |
118
|
|
|
{ |
119
|
|
|
$W = bab_Widgets(); |
120
|
|
|
return $W->FlowItems($W->Label($title)->addClass('widget-strong')->colon(), $W->Label($value))->setHorizontalSpacing(.4,'em'); |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* |
125
|
|
|
* @return string |
126
|
|
|
*/ |
127
|
|
|
abstract public function getRequestType(); |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* Get status on date |
131
|
|
|
* @param string $date |
132
|
|
|
* @return string |
133
|
|
|
*/ |
134
|
10 |
|
public function getDateStatus($date) |
135
|
|
|
{ |
136
|
10 |
|
if (!isset($date) || '0000-00-00' === $date) { |
137
|
4 |
|
return $this->status; |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
|
141
|
7 |
|
require_once dirname(__FILE__).'/movement.class.php'; |
142
|
7 |
|
$I = new absences_MovementIterator(); |
143
|
7 |
|
$I->setRequest($this); |
144
|
7 |
|
$I->createdOn = $date; |
145
|
|
|
|
146
|
7 |
|
foreach($I as $movement) { |
147
|
|
|
|
148
|
|
|
// mouvement le plus recent avant la date |
149
|
|
|
|
150
|
4 |
|
if (!isset($movement->status)) { |
151
|
|
|
// movement created before status field in database |
152
|
|
|
return $this->status; |
153
|
|
|
} |
154
|
|
|
|
155
|
4 |
|
return $movement->status; |
156
|
|
|
|
157
|
6 |
|
} |
158
|
|
|
|
159
|
6 |
|
return $this->status; |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
/** |
163
|
|
|
* @return string |
164
|
|
|
*/ |
165
|
1 |
|
public function getShortStatusStr() |
166
|
|
|
{ |
167
|
1 |
|
switch($this->status) |
168
|
|
|
{ |
169
|
1 |
|
case 'Y': |
170
|
1 |
|
return absences_translate("Accepted"); |
171
|
|
|
case 'N': |
172
|
|
|
return absences_translate("Refused"); |
173
|
|
|
case 'P': |
174
|
|
|
return absences_translate("Previsional request"); |
175
|
|
|
default: |
176
|
|
|
return absences_translate("Waiting approval"); |
177
|
|
|
} |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
|
181
|
|
|
|
182
|
|
|
private function endApprovalOnMissingApprovers() |
183
|
|
|
{ |
184
|
|
|
$arr = bab_WFGetWaitingApproversInstance($this->idfai); |
185
|
|
|
|
186
|
|
|
if (0 === count($arr)) { |
187
|
|
|
$this->acceptApprovalWorkflow(); |
188
|
|
|
$this->save(); |
189
|
|
|
} |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
|
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* Get status as a string |
196
|
|
|
* @return string |
197
|
|
|
*/ |
198
|
|
|
public function getStatusStr() |
199
|
|
|
{ |
200
|
|
|
if ('' === $this->status) { |
201
|
|
|
$this->endApprovalOnMissingApprovers(); |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
switch($this->status) |
205
|
|
|
{ |
206
|
|
|
case 'Y': |
207
|
|
|
return absences_translate("Accepted"); |
208
|
|
|
case 'N': |
209
|
|
|
return absences_translate("Refused"); |
210
|
|
|
case 'P': |
211
|
|
|
return absences_translate("Previsional request"); |
212
|
|
|
default: |
213
|
|
|
if ($this->todelete) { |
214
|
|
|
return sprintf(absences_translate("Will be deleted after approval by %s"), $this->getNextApprovers()); |
215
|
|
|
} |
216
|
|
|
return sprintf(absences_translate("Waiting approval by %s"), $this->getNextApprovers()); |
217
|
|
|
} |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
|
221
|
|
|
|
222
|
|
|
/** |
223
|
|
|
* @return Widget_Icon |
224
|
|
|
*/ |
225
|
|
|
public function getStatusIcon() |
226
|
|
|
{ |
227
|
|
|
$W = bab_Widgets(); |
228
|
|
|
|
229
|
|
|
switch($this->status) |
230
|
|
|
{ |
231
|
|
|
case 'Y': |
232
|
|
|
$icon = Func_Icons::ACTIONS_DIALOG_OK; |
233
|
|
|
break; |
234
|
|
|
case 'N': |
235
|
|
|
$icon = Func_Icons::ACTIONS_DIALOG_CANCEL; |
236
|
|
|
break; |
237
|
|
|
case 'P': |
238
|
|
|
$icon = Func_Icons::STATUS_DIALOG_QUESTION; |
239
|
|
|
break; |
240
|
|
|
default: |
241
|
|
|
$icon = Func_Icons::ACTIONS_VIEW_HISTORY; |
242
|
|
|
break; |
243
|
4 |
|
} |
244
|
4 |
|
|
245
|
|
|
return $W->Icon($this->getStatusStr(), $icon); |
246
|
|
|
} |
247
|
|
|
|
248
|
4 |
|
|
249
|
|
|
/** |
250
|
|
|
* Test if the has been fixed by a manager (not modifiable by the user) |
251
|
|
|
* @return bool |
252
|
|
|
*/ |
253
|
|
|
public function isFixed() |
254
|
|
|
{ |
255
|
|
|
return false; |
256
|
|
|
|
257
|
|
|
} |
258
|
|
|
|
259
|
4 |
|
|
260
|
|
|
private function getNames($arr) |
261
|
4 |
|
{ |
262
|
|
|
$return = array(); |
263
|
|
|
|
264
|
|
|
foreach($arr as $k => $id_user) |
265
|
|
|
{ |
266
|
|
|
$return[$k] = bab_getUserName($id_user); |
267
|
|
|
} |
268
|
4 |
|
|
269
|
|
|
return $return; |
270
|
|
|
} |
271
|
|
|
|
272
|
|
|
|
273
|
|
|
/** |
274
|
|
|
* @return string |
275
|
|
|
*/ |
276
|
|
|
public function getNextApprovers() |
277
|
|
|
{ |
278
|
|
|
$arr = bab_WFGetWaitingApproversInstance($this->idfai); |
279
|
|
|
|
280
|
4 |
|
if (count($arr) <= 3) |
281
|
|
|
{ |
282
|
|
|
return implode(', ', $this->getNames($arr)); |
283
|
|
|
} |
284
|
|
|
|
285
|
|
|
$first = array_shift($arr); |
286
|
|
|
$second = array_shift($arr); |
287
|
4 |
|
|
288
|
|
|
return sprintf(absences_translate('%s, %s and %d other approvers'), bab_getUserName($first), bab_getUserName($second), count($arr)); |
289
|
|
|
} |
290
|
|
|
|
291
|
4 |
|
/** |
292
|
|
|
* Get the apporbation sheme ID for the request |
293
|
4 |
|
* @return int |
294
|
|
|
*/ |
295
|
|
|
abstract public function getApprobationId(); |
296
|
|
|
|
297
|
4 |
|
|
298
|
|
|
|
299
|
|
|
/** |
300
|
|
|
* @return bool |
301
|
|
|
*/ |
302
|
|
|
protected function autoApproval() |
303
|
4 |
|
{ |
304
|
4 |
|
if (isset($this->todelete) && $this->todelete) { |
305
|
|
|
$this->addMovement(sprintf(absences_translate('The %s has been deleted with auto-approval'), $this->getTitle())); |
306
|
|
|
$this->delete(); |
307
|
4 |
|
return false; |
308
|
|
|
} |
309
|
|
|
|
310
|
|
|
|
311
|
|
|
$this->onConfirm(); |
312
|
|
|
$this->addMovement(sprintf(absences_translate('The %s has been accepted with auto-approval'), $this->getTitle())); |
313
|
|
|
return false; |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
|
317
|
|
|
|
318
|
|
|
private function getAutoApprovalUserId() |
319
|
4 |
|
{ |
320
|
|
|
if (!absences_getVacationOption('auto_approval')) { |
321
|
|
|
return 0; |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
return bab_getUserId(); |
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
|
328
|
|
|
|
329
|
|
|
/** |
330
|
|
|
* Create approbation instance and set it "notified" but do not send email notification |
331
|
|
|
* retourne TRUE si la demande est bien devenue en attente d'approbation |
332
|
|
|
* @return bool |
333
|
|
|
*/ |
334
|
|
|
public function createApprobationInstance() |
335
|
|
|
{ |
336
|
|
|
|
337
|
|
|
if (isset($this->idfai) && $this->idfai > 0) |
338
|
|
|
{ |
339
|
|
|
bab_WFDeleteInstance($this->idfai); |
340
|
|
|
} |
341
|
|
|
|
342
|
|
|
// si le 3eme parametre est passe avec l'id user en cours, cela active l'auto-approbation |
343
|
4 |
|
// l'auto-approbation a ete active a partir de la version 2.21 du module |
344
|
4 |
|
// le dernier parametre necessite la version 8.0.100 d'ovidentia pour fonctionner (correction du bug de detection du supperieur hierarchique quand le gestionnaire depose l'absence) |
345
|
4 |
|
|
346
|
|
|
$idfai = bab_WFMakeInstance($this->getApprobationId(), get_class($this).':'.$this->id, $this->getAutoApprovalUserId(), $this->id_user); |
347
|
4 |
|
if (is_int($idfai)) |
348
|
4 |
|
{ |
349
|
4 |
|
$users = bab_WFGetWaitingApproversInstance($idfai, true); |
350
|
4 |
|
if (count($users) == 0) |
351
|
|
|
{ |
352
|
|
|
$a = bab_WFGetApprobationInfos($this->getApprobationId()); |
353
|
|
|
|
354
|
|
|
// l'instance n'a pas fonctionne |
355
|
|
|
bab_WFDeleteInstance($idfai); |
356
|
|
|
//TRANSLATORS: \n%1: request type (vacation request), \n%2: schema type (Staff schema), \n%3: schema name |
357
|
|
|
$this->addMovement(sprintf(absences_translate('The approval initialisation failed on the %s because no approvers were found on %s %s'), $this->getTitle(), mb_strtolower($a['type']), $a['name'])); |
358
|
|
|
return $this->autoApproval(); |
359
|
|
|
} |
360
|
|
|
|
361
|
|
|
if (isset($this->todelete) && $this->todelete) { |
362
|
|
|
$this->addMovement(sprintf(absences_translate('The %s has been sent to deletion approval'), $this->getTitle())); |
363
|
|
|
} else { |
364
|
|
|
$this->addMovement(sprintf(absences_translate('The %s has been sent for approval'), $this->getTitle())); |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
} else { // $idfai == TRUE : auto-approbation end schema |
368
|
|
|
return $this->autoApproval(); |
369
|
|
|
} |
370
|
|
|
|
371
|
|
|
$this->idfai = $idfai; |
372
|
|
|
$this->status = ''; |
373
|
|
|
$this->id_approver = 0; |
374
|
|
|
$this->appr_notified = 0; |
375
|
|
|
$this->comment2 = ''; |
376
|
|
|
$this->save(); |
377
|
|
|
|
378
|
|
|
return true; |
379
|
|
|
} |
380
|
|
|
|
381
|
|
|
|
382
|
|
|
protected function rejectApprovalWorkflow() |
383
|
|
|
{ |
384
|
|
|
bab_WFDeleteInstance($this->idfai); |
385
|
|
|
$this->idfai = 0; |
386
|
|
|
if ($this->todelete) { |
387
|
|
|
|
388
|
|
|
// demande de suppression refusee |
389
|
|
|
$this->status = 'Y'; |
390
|
|
|
} else { |
391
|
|
|
$this->status = 'N'; |
392
|
|
|
} |
393
|
|
|
$this->onReject(); |
394
|
|
|
} |
395
|
|
|
|
396
|
|
|
|
397
|
|
|
protected function acceptApprovalWorkflow() |
398
|
|
|
{ |
399
|
|
|
bab_WFDeleteInstance($this->idfai); |
400
|
|
|
$this->idfai = 0; |
401
|
|
|
$this->status = 'Y'; |
402
|
|
|
|
403
|
|
|
if (!$this->firstconfirm) { |
404
|
|
|
$this->firstconfirm = 1; |
405
|
|
|
} |
406
|
|
|
|
407
|
|
|
if ($this->todelete) { |
408
|
|
|
return $this->delete(); |
409
|
|
|
} |
410
|
|
|
$this->onConfirm(); |
411
|
|
|
} |
412
|
|
|
|
413
|
|
|
|
414
|
|
|
/** |
415
|
|
|
* Approbator confirm |
416
|
|
|
* move to next approbator or close instance and set the request accepted |
417
|
|
|
* |
418
|
|
|
* |
419
|
|
|
* @param bool $status Accept or reject approbation step |
420
|
|
|
* @param string $approver_comment |
421
|
|
|
* |
422
|
|
|
*/ |
423
|
|
|
public function approbationNext($status, $approver_comment) |
424
|
|
|
{ |
425
|
|
|
|
426
|
|
|
$res = bab_WFUpdateInstance($this->idfai, bab_getUserId(), $status); |
427
|
|
|
|
428
|
|
|
switch ($res) { |
429
|
|
|
case 0: |
430
|
|
|
$this->rejectApprovalWorkflow(); |
431
|
|
|
break; |
432
|
|
|
|
433
|
|
|
case 1: |
434
|
|
|
$this->acceptApprovalWorkflow(); |
435
|
|
|
break; |
436
|
|
|
|
437
|
|
|
|
438
|
|
|
default: // -1 |
439
|
|
|
$nfusers = bab_WFGetWaitingApproversInstance($this->idfai, true); |
440
|
|
|
if (count($nfusers) > 0) { |
441
|
|
|
$this->appr_notified = 0; |
442
|
|
|
} else { |
443
|
|
|
// no approvers found or approvers allready notified (all user must confirm without order) |
444
|
|
|
// do nothing |
445
|
|
|
} |
446
|
|
|
|
447
|
|
|
break; |
448
|
|
|
} |
449
|
|
|
|
450
|
|
|
$this->id_approver = bab_getUserId(); |
451
|
|
|
$this->comment2 = $approver_comment; |
452
|
|
|
$this->save(); |
453
|
|
|
|
454
|
|
|
|
455
|
|
|
$str_status = $status ? absences_translate('accepted') :absences_translate('rejected'); |
456
|
|
|
|
457
|
|
|
// movement must be saved after status modification to save the new status in movement |
458
|
|
|
$this->addMovement( |
459
|
|
|
sprintf(absences_translate('The %s has been %s by %s'), $this->getTitle(), $str_status, bab_getUserName(bab_getUserId())), |
460
|
|
|
$approver_comment |
461
|
|
|
); |
462
|
|
|
|
463
|
|
|
} |
464
|
|
|
|
465
|
|
|
|
466
|
|
|
|
467
|
|
|
/** |
468
|
|
|
* Auto confirm the request |
469
|
|
|
*/ |
470
|
|
|
public function autoConfirm() |
471
|
|
|
{ |
472
|
|
|
$this->addMovement( |
473
|
|
|
sprintf(absences_translate('The %s has been confirmed automatically because of the validation timout'), $this->getTitle()) |
474
|
|
|
); |
475
|
|
|
|
476
|
|
|
|
477
|
|
|
if ($this->idfai > 0) |
478
|
|
|
{ |
479
|
|
|
bab_WFDeleteInstance($this->idfai); |
480
|
|
|
} |
481
|
|
|
|
482
|
|
|
$this->idfai = 0; |
483
|
|
|
$this->status = 'Y'; |
484
|
|
|
$this->onConfirm(); |
485
|
|
|
|
486
|
|
|
$this->id_approver = 0; |
487
|
|
|
$this->save(); |
488
|
|
|
$this->notifyOwner(); |
489
|
|
|
} |
490
|
|
|
|
491
|
|
|
|
492
|
|
|
|
493
|
|
|
/** |
494
|
|
|
* Test if the logged in user can modify the entry |
495
|
|
|
* @return bool |
496
|
|
|
*/ |
497
|
|
|
public function canModify() |
498
|
|
|
{ |
499
|
|
|
$modify_waiting = (bool) absences_getVacationOption('modify_waiting'); |
500
|
|
|
$modify_confirmed = (bool) absences_getVacationOption('modify_confirmed'); |
501
|
|
|
|
502
|
|
|
require_once dirname(__FILE__).'/agent.class.php'; |
503
|
|
|
$agent = absences_Agent::getCurrentUser(); |
504
|
|
|
|
505
|
|
|
$personal = ($agent->isInPersonnel() && $agent->id_user === $this->id_user); |
506
|
|
|
|
507
|
|
|
switch($this->status) |
508
|
|
|
{ |
509
|
|
|
case 'Y': // confirmed |
510
|
|
|
if ($this->isFixed()) { |
511
|
|
|
return false; |
512
|
|
|
} |
513
|
|
|
|
514
|
|
|
if ($modify_confirmed) { |
515
|
|
|
return true; |
516
|
|
|
} |
517
|
|
|
|
518
|
|
|
return !$personal; // ce n'est pas ma propre demande, je suis gestionnaire delegue |
519
|
|
|
|
520
|
|
|
|
521
|
|
|
|
522
|
|
|
case 'N': // rejected |
523
|
|
|
return false; |
524
|
|
|
|
525
|
|
|
case 'P': // previsional |
526
|
|
|
return $personal; |
527
|
|
|
|
528
|
|
|
default: // waiting |
529
|
|
|
return ($personal && $modify_waiting); |
530
|
|
|
} |
531
|
|
|
} |
532
|
|
|
|
533
|
|
|
|
534
|
|
|
/** |
535
|
|
|
* Test if the user can delete the entry |
536
|
|
|
* @return bool |
537
|
|
|
*/ |
538
|
|
|
public function canDelete() |
539
|
|
|
{ |
540
|
|
|
return $this->canModify(); |
541
|
|
|
} |
542
|
|
|
|
543
|
|
|
|
544
|
|
|
|
545
|
|
|
|
546
|
|
|
|
547
|
|
|
/** |
548
|
|
|
* Process specific code when the request is rejected |
549
|
|
|
* |
550
|
|
|
*/ |
551
|
|
|
abstract protected function onReject(); |
552
|
|
|
|
553
|
|
|
/** |
554
|
|
|
* Process specific code when the request is confirmed |
555
|
|
|
*/ |
556
|
|
|
abstract protected function onConfirm(); |
557
|
|
|
|
558
|
|
|
/** |
559
|
|
|
* request title |
560
|
|
|
* @return string |
561
|
|
|
*/ |
562
|
|
|
abstract public function getTitle(); |
563
|
|
|
|
564
|
|
|
|
565
|
|
|
|
566
|
|
|
/** |
567
|
|
|
* Get a list of field to display in the notifications for this request |
568
|
|
|
* @return array |
569
|
|
|
*/ |
570
|
|
|
abstract public function getNotifyFields(); |
571
|
|
|
|
572
|
|
|
|
573
|
|
|
/** |
574
|
|
|
* annee de la demande |
575
|
|
|
* @return int |
576
|
|
|
*/ |
577
|
|
|
abstract public function getYear(); |
578
|
|
|
|
579
|
|
|
|
580
|
|
|
/** |
581
|
|
|
* annee de la demande, pour l'archivage par annee, tiens compte du parametrage du mois de debut de periode. |
582
|
|
|
* Utilise dans l'archivage par annee |
583
|
|
|
* @return int |
584
|
|
|
*/ |
585
|
|
|
abstract public function getArchiveYear(); |
586
|
|
|
|
587
|
|
|
|
588
|
|
|
abstract public function archive(); |
589
|
|
|
|
590
|
|
|
|
591
|
|
|
/** |
592
|
|
|
* approver has been notified |
593
|
|
|
*/ |
594
|
|
|
abstract public function setNotified(); |
595
|
|
|
|
596
|
|
|
|
597
|
|
|
/** |
598
|
|
|
* Url to edit request as a manager |
599
|
|
|
*/ |
600
|
|
|
abstract public function getManagerEditUrl(); |
601
|
|
|
|
602
|
|
|
/** |
603
|
|
|
* Url to delete request as a manager |
604
|
|
|
*/ |
605
|
|
|
abstract public function getManagerDeleteUrl(); |
606
|
|
|
|
607
|
|
|
|
608
|
|
|
/** |
609
|
|
|
* Notify request next approvers |
610
|
|
|
*/ |
611
|
|
|
public function notifyApprovers() |
612
|
|
|
{ |
613
|
|
|
$defer = (bool) absences_getVacationOption('approb_email_defer'); |
614
|
|
|
if (!$defer) |
615
|
|
|
{ |
616
|
|
|
require_once dirname(__FILE__).'/request.notify.php'; |
617
|
|
|
absences_notifyRequestApprovers(); |
618
|
|
|
} |
619
|
|
|
} |
620
|
|
|
|
621
|
|
|
|
622
|
|
|
/** |
623
|
|
|
* Notify request owner about the approval or reject of the request |
624
|
|
|
*/ |
625
|
|
|
public function notifyOwner() |
626
|
|
|
{ |
627
|
|
|
$appliquant_email = (bool) absences_getVacationOption('appliquant_email'); |
628
|
|
|
|
629
|
|
|
if (!$appliquant_email) |
630
|
|
|
{ |
631
|
|
|
return; |
632
|
|
|
} |
633
|
|
|
|
634
|
|
|
require_once dirname(__FILE__).'/request.notify.php'; |
635
|
|
|
|
636
|
|
|
|
637
|
|
|
|
638
|
|
|
switch($this->status) |
639
|
|
|
{ |
640
|
|
|
case 'N': |
641
|
|
|
$subject = sprintf(absences_translate("Your %s has been refused"), $this->getTitle()); |
642
|
|
|
break; |
643
|
|
|
|
644
|
|
|
case 'Y': |
645
|
|
|
$subject = sprintf(absences_translate("Your %s has been accepted"), $this->getTitle()); |
646
|
|
|
break; |
647
|
|
|
|
648
|
|
|
default: // next approver |
649
|
|
|
return; |
650
|
|
|
} |
651
|
|
|
|
652
|
|
|
absences_notifyRequestAuthor(array($this), $subject, $subject, $this->id_user); |
653
|
|
|
} |
654
|
|
|
|
655
|
|
|
|
656
|
|
|
/** |
657
|
|
|
* Get request card frame to display in requests list |
658
|
|
|
* @param bool $display_username Affiche le nom du demandeur dans la card frame ou non, utile pour les listes contenant plusieurs demandeurs possibles |
659
|
|
|
* @param int $rfrom si les demandes de la liste sont modifiee par un gestionnaire ou gestionnaire delegue |
660
|
|
|
* @param int $ide id entite de l'organigramme >0 si gestionnaire delegue seulement |
661
|
|
|
* @return Widget_Frame |
662
|
|
|
*/ |
663
|
|
|
abstract public function getCardFrame($display_username, $rfrom, $ide); |
664
|
|
|
|
665
|
|
|
|
666
|
|
|
/** |
667
|
|
|
* Get request frame to display in manager lists |
668
|
|
|
* @return Widget_Frame |
669
|
|
|
*/ |
670
|
|
|
abstract public function getManagerFrame(); |
671
|
|
|
|
672
|
|
|
|
673
|
|
|
|
674
|
|
|
/** |
675
|
|
|
* Delete request |
676
|
|
|
*/ |
677
|
|
|
public function delete() |
678
|
|
|
{ |
679
|
|
|
if ($this->idfai > 0) |
680
|
|
|
{ |
681
|
|
|
bab_WFDeleteInstance($this->idfai); |
682
|
|
|
} |
683
|
|
|
|
684
|
|
|
global $babDB; |
685
|
|
|
$babDB->db_query("UPDATE absences_movement SET id_request='0' WHERE request_class=".$babDB->quote(get_class($this))." AND id_request=".$babDB->quote($this->id)); |
686
|
4 |
|
} |
687
|
|
|
|
688
|
4 |
|
|
689
|
|
|
|
690
|
4 |
|
/** |
691
|
4 |
|
* @return absences_MovementIterator |
692
|
4 |
|
*/ |
693
|
4 |
|
public function getMovementIterator() |
694
|
4 |
|
{ |
695
|
4 |
|
require_once dirname(__FILE__).'/movement.class.php'; |
696
|
4 |
|
|
697
|
4 |
|
$I = new absences_MovementIterator; |
698
|
|
|
$I->setRequest($this); |
699
|
|
|
|
700
|
|
|
return $I; |
701
|
|
|
} |
702
|
|
|
|
703
|
|
|
|
704
|
|
|
|
705
|
|
|
/** |
706
|
|
|
* |
707
|
|
|
* @param string $message Generated message |
708
|
|
|
* @param string $comment Author comment |
709
|
|
|
*/ |
710
|
|
View Code Duplication |
public function addMovement($message, $comment = '', $createdOn = null) |
|
|
|
|
711
|
|
|
{ |
712
|
|
|
require_once dirname(__FILE__).'/movement.class.php'; |
713
|
|
|
|
714
|
|
|
$movement = new absences_Movement(); |
715
|
|
|
$movement->message = $message; |
716
|
|
|
$movement->comment = $comment; |
717
|
|
|
$movement->setRequest($this); |
718
|
|
|
$movement->setAgent($this->getAgent()); |
719
|
|
|
$movement->createdOn = $createdOn; |
720
|
|
|
$movement->save(); |
721
|
|
|
} |
722
|
|
|
|
723
|
|
|
|
724
|
|
|
|
725
|
|
|
/** |
726
|
|
|
* @return absences_Movement |
727
|
|
|
*/ |
728
|
|
|
public function getLastMovement() |
729
|
|
|
{ |
730
|
|
|
if (!isset($this->lastMovement)) |
731
|
|
|
{ |
732
|
|
|
$this->lastMovement = false; |
|
|
|
|
733
|
|
|
$I = $this->getMovementIterator(); |
734
|
|
|
foreach($I as $movement) |
735
|
|
|
{ |
736
|
|
|
$this->lastMovement = $movement; |
737
|
|
|
break; |
738
|
|
|
} |
739
|
|
|
} |
740
|
|
|
|
741
|
|
|
return $this->lastMovement; |
742
|
|
|
} |
743
|
|
|
|
744
|
|
|
|
745
|
|
|
/** |
746
|
|
|
* Faut-il allerter l'approbateur que le delai d'approbation est depasse |
747
|
|
|
* @return bool |
748
|
|
|
*/ |
749
|
|
|
public function approbAlert() |
750
|
|
|
{ |
751
|
|
|
$last = $this->getLastMovement(); |
752
|
|
|
|
753
|
|
|
if (!$last) |
754
|
|
|
{ |
755
|
|
|
return false; |
756
|
|
|
} |
757
|
|
|
|
758
|
|
|
$s = (time() - bab_mktime($last->createdOn)); |
759
|
|
|
$d = ($s / 86400); |
760
|
|
|
|
761
|
|
|
$approb_alert = (int) absences_getVacationOption('approb_alert'); |
762
|
|
|
|
763
|
|
|
if ($approb_alert > $d) |
764
|
|
|
{ |
765
|
|
|
return false; |
766
|
|
|
} |
767
|
|
|
|
768
|
|
|
return true; |
769
|
|
|
} |
770
|
|
|
} |
771
|
|
|
|
772
|
|
|
|
773
|
|
|
|
774
|
|
|
|
775
|
|
|
|
776
|
|
|
|
777
|
|
|
|
778
|
|
|
|
779
|
|
|
|
780
|
|
|
/** |
781
|
|
|
* Get the list of request from the users, requests are : |
782
|
|
|
* |
783
|
|
|
* - vacations requests |
784
|
|
|
* - workday entiling recovery |
785
|
|
|
* - time saving account deposits |
786
|
|
|
* |
787
|
|
|
* Sorted by the most recent in first |
788
|
|
|
*/ |
789
|
|
|
class absences_RequestIterator implements SeekableIterator, Countable |
790
|
|
|
{ |
791
|
|
|
|
792
|
|
|
/** |
793
|
|
|
* |
794
|
|
|
* @var array |
795
|
|
|
*/ |
796
|
|
|
public $users; |
797
|
|
|
|
798
|
|
|
/** |
799
|
|
|
* Filter by organization |
800
|
|
|
* @var int |
801
|
|
|
*/ |
802
|
|
|
public $organization; |
803
|
|
|
|
804
|
|
|
/** |
805
|
|
|
* |
806
|
|
|
* @var array |
807
|
|
|
*/ |
808
|
|
|
private $data; |
809
|
|
|
|
810
|
|
|
/** |
811
|
|
|
* |
812
|
|
|
* @var int |
813
|
|
|
*/ |
814
|
|
|
private $pos; |
815
|
|
|
|
816
|
|
|
|
817
|
|
|
/** |
818
|
|
|
* Return only one entry per folder |
819
|
|
|
* @var bool |
820
|
|
|
*/ |
821
|
|
|
public $one_per_folder = false; |
822
|
|
|
|
823
|
|
|
|
824
|
|
|
/** |
825
|
|
|
* Filtrer les demandes necessitant ou pas un email aux approbateurs |
826
|
|
|
* @var int |
827
|
|
|
*/ |
828
|
|
|
public $appr_notified; |
829
|
|
|
|
830
|
|
|
/** |
831
|
|
|
* Filtrer les demandes avec unes instance d'approbation |
832
|
|
|
* @var bool |
833
|
|
|
*/ |
834
|
|
|
public $idfai_set; |
835
|
|
|
|
836
|
|
|
/** |
837
|
|
|
* Filtrer les demandes par status |
838
|
|
|
* @var string |
839
|
|
|
*/ |
840
|
|
|
public $status; |
841
|
|
|
|
842
|
|
|
|
843
|
|
|
/** |
844
|
|
|
* Search all request created before this date |
845
|
|
|
* @var string |
846
|
|
|
*/ |
847
|
|
|
public $createdOn; |
848
|
|
|
|
849
|
|
|
|
850
|
|
|
/** |
851
|
|
|
* Search all request modified before this date |
852
|
|
|
* @var string |
853
|
|
|
*/ |
854
|
|
|
public $modifiedOn; |
855
|
|
|
|
856
|
|
|
/** |
857
|
|
|
* Filtrer les demandes par annee |
858
|
|
|
* @var int |
859
|
|
|
*/ |
860
|
|
|
public $year; |
861
|
|
|
|
862
|
|
|
/** |
863
|
|
|
* Filtrer les demandes par date de debut superieur |
864
|
|
|
* @var string |
865
|
|
|
*/ |
866
|
|
|
public $startFrom; |
867
|
|
|
|
868
|
|
|
/** |
869
|
|
|
* Filtrer les demandes par date de debut inferieur |
870
|
|
|
* @var string |
871
|
|
|
*/ |
872
|
|
|
public $startTo; |
873
|
|
|
|
874
|
|
|
/** |
875
|
|
|
* Filtrer les demandes par statut d'archivage |
876
|
|
|
* @var int |
877
|
|
|
*/ |
878
|
|
|
public $archived = 0; |
879
|
|
|
|
880
|
|
|
|
881
|
|
|
public function __construct($users = null) |
882
|
|
|
{ |
883
|
|
|
$this->users = $users; |
884
|
|
|
} |
885
|
|
|
|
886
|
|
|
/** |
887
|
|
|
* Get all requests in one array (not sorted) |
888
|
|
|
* @return array |
889
|
|
|
*/ |
890
|
|
|
public function getArray() |
891
|
|
|
{ |
892
|
|
|
require_once dirname(__FILE__).'/entry.class.php'; |
893
|
|
|
require_once dirname(__FILE__).'/workperiod_recover_request.class.php'; |
894
|
|
|
require_once dirname(__FILE__).'/cet_deposit_request.class.php'; |
895
|
|
|
|
896
|
|
|
|
897
|
|
|
$return = array(); |
898
|
|
|
|
899
|
|
|
$entries = new absences_EntryIterator; |
900
|
|
|
$entries->users = $this->users; |
901
|
|
|
$entries->organization = $this->organization; |
902
|
|
|
$entries->appr_notified = $this->appr_notified; |
903
|
|
|
$entries->idfai_set = $this->idfai_set; |
904
|
|
|
$entries->status = $this->status; |
905
|
|
|
$entries->createdOn = $this->createdOn; |
906
|
|
|
$entries->modifiedOn = $this->modifiedOn; |
907
|
|
|
$entries->year = $this->year; |
908
|
|
|
$entries->archived = $this->archived; |
909
|
|
|
$entries->startFrom = $this->startFrom; |
910
|
|
|
$entries->startTo = $this->startTo; |
911
|
|
|
|
912
|
|
|
$folders = array(); |
913
|
|
|
|
914
|
|
|
foreach($entries as $entry) |
915
|
|
|
{ |
916
|
|
|
if ($this->one_per_folder && isset($entry->folder) && $entry->folder > 0) |
917
|
|
|
{ |
918
|
|
|
if (isset($folders[$entry->folder])) |
919
|
|
|
{ |
920
|
|
|
continue; |
921
|
|
|
} |
922
|
|
|
|
923
|
|
|
$folders[$entry->folder] = 1; |
924
|
|
|
} |
925
|
|
|
|
926
|
|
|
$return[] = $entry; |
927
|
|
|
} |
928
|
|
|
|
929
|
|
|
|
930
|
|
|
$cetdeposits = new absences_CetDepositRequestIterator; |
931
|
|
|
$cetdeposits->users = $this->users; |
932
|
|
|
$cetdeposits->organization = $this->organization; |
933
|
|
|
$cetdeposits->appr_notified = $this->appr_notified; |
934
|
|
|
$cetdeposits->idfai_set = $this->idfai_set; |
935
|
|
|
$cetdeposits->status = $this->status; |
936
|
|
|
$cetdeposits->createdOn = $this->createdOn; |
937
|
|
|
$cetdeposits->modifiedOn = $this->modifiedOn; |
938
|
|
|
$cetdeposits->year = $this->year; |
939
|
|
|
$cetdeposits->archived = $this->archived; |
940
|
|
|
$cetdeposits->startFrom = $this->startFrom; |
941
|
|
|
$cetdeposits->startTo = $this->startTo; |
942
|
|
|
|
943
|
|
|
foreach($cetdeposits as $deposit) |
944
|
|
|
{ |
945
|
|
|
$return[] = $deposit; |
946
|
|
|
} |
947
|
|
|
|
948
|
|
|
$workperiods = new absences_WorkperiodRecoverRequestIterator; |
949
|
|
|
$workperiods->users = $this->users; |
950
|
|
|
$workperiods->organization = $this->organization; |
951
|
|
|
$workperiods->appr_notified = $this->appr_notified; |
952
|
|
|
$workperiods->idfai_set = $this->idfai_set; |
953
|
|
|
$workperiods->status = $this->status; |
954
|
|
|
$workperiods->createdOn = $this->createdOn; |
955
|
|
|
$workperiods->modifiedOn = $this->modifiedOn; |
956
|
|
|
$workperiods->year = $this->year; |
957
|
|
|
$workperiods->archived = $this->archived; |
958
|
|
|
$workperiods->startFrom = $this->startFrom; |
|
|
|
|
959
|
|
|
$workperiods->startTo = $this->startTo; |
|
|
|
|
960
|
|
|
|
961
|
|
|
foreach($workperiods as $recovery) |
962
|
|
|
{ |
963
|
|
|
$return[] = $recovery; |
964
|
|
|
} |
965
|
|
|
|
966
|
|
|
return $return; |
967
|
|
|
} |
968
|
|
|
|
969
|
|
|
/** |
970
|
|
|
* Get all requests in one array |
971
|
|
|
* @return array |
972
|
|
|
*/ |
973
|
|
|
public function getSortedArray() |
974
|
|
|
{ |
975
|
|
|
$arr = $this->getArray(); |
976
|
|
|
bab_Sort::sortObjects($arr, 'createdOn', bab_Sort::CASE_INSENSITIVE); |
977
|
|
|
|
978
|
|
|
$arr = array_reverse($arr); |
979
|
|
|
|
980
|
|
|
return array_values($arr); |
981
|
|
|
} |
982
|
|
|
|
983
|
|
|
|
984
|
|
|
/** |
985
|
|
|
* |
986
|
|
|
* @return multitype:absences_Request |
|
|
|
|
987
|
|
|
*/ |
988
|
|
|
private function getData() |
989
|
|
|
{ |
990
|
|
|
if (!isset($this->data)) |
991
|
|
|
{ |
992
|
|
|
$this->data = $this->getSortedArray(); |
993
|
|
|
} |
994
|
|
|
|
995
|
|
|
return $this->data; |
996
|
|
|
} |
997
|
|
|
|
998
|
|
|
|
999
|
|
|
public function seek($position) { |
1000
|
|
|
$this->pos = $position; |
1001
|
|
|
} |
1002
|
|
|
|
1003
|
|
|
/** |
1004
|
|
|
* (non-PHPdoc) |
1005
|
|
|
* @see SeekableIterator::current() |
1006
|
|
|
* |
1007
|
|
|
* @return absences_Request |
1008
|
|
|
*/ |
1009
|
|
|
public function current() { |
1010
|
|
|
$data = $this->getData(); |
1011
|
|
|
return $data[$this->pos]; |
1012
|
|
|
} |
1013
|
|
|
|
1014
|
|
|
public function next() { |
1015
|
|
|
$this->pos++; |
1016
|
|
|
} |
1017
|
|
|
|
1018
|
|
|
public function key() { |
1019
|
|
|
return $this->pos; |
1020
|
|
|
} |
1021
|
|
|
|
1022
|
|
|
public function valid() { |
1023
|
|
|
$data = $this->getData(); |
1024
|
|
|
return isset($data[$this->pos]); |
1025
|
|
|
} |
1026
|
|
|
|
1027
|
|
|
public function rewind() { |
1028
|
|
|
$this->pos = 0; |
1029
|
|
|
} |
1030
|
|
|
|
1031
|
|
|
/** |
1032
|
|
|
* (non-PHPdoc) |
1033
|
|
|
* @see Countable::count() |
1034
|
|
|
* |
1035
|
|
|
* @return int |
1036
|
|
|
*/ |
1037
|
|
|
public function count() { |
1038
|
|
|
return count($this->getData()); |
1039
|
|
|
} |
1040
|
|
|
} |
1041
|
|
|
|
1042
|
|
|
|
1043
|
|
|
|
1044
|
|
|
|
1045
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.