Completed
Push — master ( 9ee0eb...9d7b4a )
by Paul
04:30
created

absences_AgentRight::isAccessibleOnDelay()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 21
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12
Metric Value
dl 0
loc 21
ccs 0
cts 13
cp 0
rs 9.3142
cc 3
eloc 11
nc 3
nop 1
crap 12
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
27
require_once dirname(__FILE__).'/../define.php';
28
require_once dirname(__FILE__).'/record.class.php';
29
require_once dirname(__FILE__).'/right.class.php';
30
require_once dirname(__FILE__).'/agent.class.php';
31
32
require_once $GLOBALS['babInstallPath'].'utilit/iterator/iterator.php';
33
34
/**
35
 * A vacation right linked to agent
36
 * 
37
 * 
38
 * 
39
 * @property int	$id_user
40
 * @property int	$id_right
41
 * @property string	$quantity
42
 * @property string	$date_begin_valid
43
 * @property string $date_end_valid
44
 * @property string $inperiod_start
45
 * @property string $inperiod_end
46
 * @property int	$validoverlap
47
 * @property string	$saving_begin
48
 * @property string	$saving_end 
49
 */
50
class absences_AgentRight extends absences_Record 
51
{
52
53
	
54
	/**
55
	 * Contain default values for vacation right
56
	 * @var absences_Right
57
	 */
58
	private $right;
59
	
60
	/**
61
	 * Contain the user vacation parameters
62
	 * @var absences_Agent
63
	 */
64
	private $agent;
65
	
66
	
67
	/**
68
	 * Cache for consumed confirmed quantity computed value
69
	 * @var float
70
	 */
71
	private $confirmed_quantity;
72
	
73
	/**
74
	 * Cache for consumed waiting quantity computed value
75
	 * @var float
76
	 */
77
	private $waiting_quantity;
78
	
79
	
80
	/**
81
	 * Cache for consumed previsional quantity computed value
82
	 * @var float
83
	 */
84
	private $previsional_quantity;
85
	
86
	
87
88
	/**
89
	 * Create absences_AgentRight object using the absences_users_rights table id
90
	 * @param int $id
91
	 * @return absences_AgentRight
92
	 */
93 33
	public static function getById($id)
94
	{
95 33
		$agentRight = new absences_AgentRight;
96 33
		$agentRight->id = $id;
97
		
98 33
		return $agentRight;
99
	}
100
	
101
102
	
103
	/**
104
	 * 
105
	 * @return array
106
	 */
107 43 View Code Duplication
	public function getRow()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
108
	{
109 43
		if (null === $this->row)
110 43
		{
111 33
			global $babDB;
112
			
113 33
			if (isset($this->id))
114 33
			{
115 33
				$res = $babDB->db_query('SELECT * FROM absences_users_rights WHERE id='.$babDB->quote($this->id));
116 33
				$this->setRow($babDB->db_fetch_assoc($res));
117
				
118 33
			} else if (isset($this->agent) && isset($this->right))
119
			{
120
				$res = $babDB->db_query('SELECT * FROM absences_users_rights WHERE id_user='.$babDB->quote($this->agent->getIdUser()).' AND id_right='.$babDB->quote($this->right->id));
121
				$this->setRow($babDB->db_fetch_assoc($res));
122
			}
123 33
		}
124
		
125 43
		return $this->row;
126
	}
127
	
128
	/**
129
	 * 
130
	 * @param absences_Agent $agent
131
	 * @return absences_AgentRight
132
	 */
133 10
	public function setAgent(absences_Agent $agent)
134
	{
135 10
		$this->agent = $agent;
136 10
		return $this;
137 4
	}
138
	
139
	/**
140
	 * 
141
	 * @param absences_Right $right
142
	 * @return absences_AgentRight
143
	 */
144 25
	public function setRight(absences_Right $right)
145
	{
146 25
		$this->right = $right;
147 18
		return $this;
148
	}
149
	
150
	
151
	/**
152
	 * @return absences_Right
153
	 */
154 42
	public function getRight()
155 4
	{
156 42
		if (!isset($this->right))
157 42
		{
158 32
			$row = $this->getRow();
159
			
160 32
			if (!$row['id_right'])
161 32
			{
162
				return null;
163
			}
164
			
165 32
			require_once dirname(__FILE__).'/right.class.php';
166 32
			$this->right = new absences_Right($row['id_right']);
167 32
		}
168
		
169 42
		return $this->right;
170
	}
171
	
172
	/**
173
	 * @return absences_Agent
174
	 */
175 8 View Code Duplication
	public function getAgent()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
176
	{
177 8
		if (!isset($this->agent))
178 8
		{
179 8
			$row = $this->getRow();
180 8
			$this->agent = absences_Agent::getFromIdUser($row['id_user']);
181 8
		}
182
		
183 8
		return $this->agent;
184
	}
185
	
186
	
187
	/**
188
	 * Delete agentRight
189
	 * 
190
	 */
191
	public function delete()
192
	{
193
		$res = $this->getDynamicRightIterator();
194
		foreach($res as $dynright)
195
		{
196
			/*@var $dynright absences_DynamicRight */
197
			$dynright->quantity = 0;
198
			$dynright->save();
199
		}	
200
			
201
		global $babDB;
202
		$babDB->db_query('DELETE FROM absences_users_rights WHERE id='.$babDB->quote($this->id).'');
203
		
204
		return true;
205
	}
206
	
207 8
	public function save()
208
	{
209
		global $babDB;
210
		
211
		
212
		if (!isset($this->date_begin_valid) || empty($this->date_begin_valid))
213
		{
214
			$this->date_begin_valid = '0000-00-00';
215
		}
216
		
217
		if (!isset($this->date_end_valid) || empty($this->date_end_valid))
218
		{
219
			$this->date_end_valid = '0000-00-00';
220
		}
221
		
222
		
223
		if (!isset($this->inperiod_start) || empty($this->inperiod_start))
224
		{
225
			$this->inperiod_start = '0000-00-00';
226
		}
227
		
228
		if (!isset($this->inperiod_end) || empty($this->inperiod_end))
229
		{
230
			$this->inperiod_end = '0000-00-00';
231
		}
232
		
233
		if (!isset($this->saving_begin) || empty($this->saving_begin))
234 8
		{
235
			$this->saving_begin = '0000-00-00';
236
		}
237
		
238
		if (!isset($this->saving_end) || empty($this->saving_begin))
239 8
		{
240
			$this->saving_end = '0000-00-00';
241
		}
242
		
243
		if (!isset($this->validoverlap))
244 8
		{
245
			$this->validoverlap = 0;
246
		}
247
		
248
		
249
		
250
		$exists = 0;
251
		$quantity = '';
252
		
253
		if (empty($this->id))
254
		{
255
256
		    
257
			$babDB->db_query('
258
				INSERT INTO absences_users_rights (
259 8
					id_user, 
260
					id_right, 
261
					quantity, 
262
					date_begin_valid, 
263
					date_end_valid, 
264
					inperiod_start, 
265
					inperiod_end, 
266
					validoverlap, 
267
					saving_begin, 
268 8
					saving_end
269
				) VALUES (
270
					'.$babDB->quote($this->getIdUser()).',
271
					'.$babDB->quote($this->getIdRight()).',
272
					'.$babDB->quote($this->quantity).',
273
					'.$babDB->quote($this->date_begin_valid).',
274 8
					'.$babDB->quote($this->date_end_valid).',
275
					'.$babDB->quote($this->inperiod_start).',
276
					'.$babDB->quote($this->inperiod_end).',
277
					'.$babDB->quote($this->validoverlap).',
278
					'.$babDB->quote($this->saving_begin).',
279
					'.$babDB->quote($this->saving_end).' 
280 8
				)	
281
			');
282
			
283
			
284
			$this->id = $babDB->db_insert_id();
285
			
286 8
		} else {
287
		    
288
		    $res = $babDB->db_query('SELECT quantity FROM absences_users_rights WHERE id='.$babDB->quote($this->id));
289
		    $arr = $babDB->db_fetch_assoc($res);
290
		     
291 8
		    if ($arr) {
292
		        $exists = 1;
293 8
		        $quantity = $arr['quantity'];
294
		    }
295
296
			$babDB->db_query('UPDATE absences_users_rights
297
				SET 
298
					quantity='.$babDB->quote($this->quantity).',
299
					date_begin_valid='.$babDB->quote($this->date_begin_valid).',
300
					date_end_valid='.$babDB->quote($this->date_end_valid).',
301 8
					inperiod_start='.$babDB->quote($this->inperiod_start).',
302
					inperiod_end='.$babDB->quote($this->inperiod_end).',
303 3
					validoverlap='.$babDB->quote($this->validoverlap).',
304
					saving_begin='.$babDB->quote($this->saving_begin).',
305
					saving_end='.$babDB->quote($this->saving_end).' 
306 8
				WHERE
307
					id='.$babDB->quote($this->id));
308 8
		}
309
		
310
		
311
		$this->saveHistory($exists, $quantity);
312
	}
313
	
314
	
315
	
316
	
317
	
318
	public function saveHistory($exists, $quantity)
319
	{
320
	    global $babDB;
321
	    
322
	    $babDB->db_query('INSERT INTO absences_users_rights_history (id_user_right, linkexists, quantity, date_end) 
323
	        VALUES (
324
	           '.$babDB->quote($this->id).', 
325
	           '.$babDB->quote($exists).', 
326
	           '.$babDB->quote($quantity).', 
327
	           '.$babDB->quote(date('Y-m-d H:i:s')).'
328
	        )
329
	    ');
330
	}
331
	
332
	
333
	
334
	
335
	
336
	
337
	/**
338
	 * @deprecated replace by save()
339
	 */
340 8
	public function saveRightModifications()
341 8
	{
342 8
		$this->save();
343 8
	}
344
	
345
	
346
	/**
347
	 * Get quantity value using the history
348
	 * 
349
	 * @param string $date         YYYY-MM-DD
350
	 * 
351
	 * return values:
352
	 *   null          - unknow value at that date, use the main value
353
	 *   empty string  - used right value at that date
354
	 *   string        - used this value at that date
355
	 *   false         - the user was not linked to right at that date
356
	 * 
357
	 * @return mixed
358
	 */
359 30
	protected function getQuantityValueOnDate($date)
360
	{
361 30
	    if (!isset($date) || '0000-00-00' === $date) {
362
	        // no history because no date
363 16
	        return null;
364
	    }
365
	    
366 15
	    if (!$this->id) {
367
	        // no history because not saved
368
	        return null;
369
	    }
370
	    
371 15
	    global $babDB;
372
	    
373 15
	    $res = $babDB->db_query('SELECT linkexists, quantity 
374 15
	        FROM absences_users_rights_history WHERE id_user_right='.$babDB->quote($this->id).' 
375 15
	        AND date_end >= '.$babDB->quote($date.' 23:59:59').'
376 15
	        ORDER BY date_end DESC');
377
	    
378 15
	    $arr = $babDB->db_fetch_assoc($res);
379
	    
380 15
	    if (!$arr) {
381
	        // no history
382 15
	        return null;
383
	    }
384
	    
385 1
	    if ('0' === $arr['linkexists']) {
386
	        return false;
387
	    }
388
	    
389 1
	    return $arr['quantity'];
390
	}
391
	
392
	
393
	
394
	/**
395
	 * Initial quantity
396
	 * @param string $date     YYYY-MM-DD
397
	 * @return float
398
	 */
399 30
	public function getInitialQuantity($date = null)
400
	{
401 30
	    $ur_quantity = $this->getQuantityValueOnDate($date);
402
	    
403 30
	    if (null === $ur_quantity) {
404
	        // this approximation is used for installations older than 
405
	        // the creation of the absences_users_rights_history table
406 30
	        $ur_quantity = $this->quantity;
407 30
	    }
408
	    
409 30
	    if (false === $ur_quantity) {
410
	        $ur_quantity = '0';
411
	    }
412
413
	    
414 30
	    if ('' === $ur_quantity) // char(5)
415 30
	    {
416 24
	        $right = $this->getRight();
417
	        	
418 24
	        if (!$right || !$right->getRow())
419 24
	        {
420
	            bab_debug('agent right linked to invalid right '.$this->id_right);
421
	            return null;
422
	        }
423
	        
424
	        // ignore quantity if right not created
425 24
	        if (isset($date) && $date.' 23:59:59' < $right->createdOn) {
426 1
	            return null;
427
	        }
428
	        
429 23
	        $quantity = (float) $this->getRight()->quantity; // decimal(4,2)
430 23
	    } else {
431
	    
432 11
	        $quantity = (float) $ur_quantity;
433
	    }
434
	    
435 29
	    return $quantity;
436
	}
437
	
438
	
439
440
	
441
	
442
	/**
443
	 * Get total quantity for an agent
444
	 * Il s'agit de la quantite visible pour l'utilisateur final et qui n'inclu par la quantitee consommee
445
	 * @param string $date     YYYY-MM-DD
446
	 * @return float	in days or in hours
447
	 */
448 30
	public function getQuantity($date = null)
449
	{
450
		
451 30
	    $quantity = $this->getInitialQuantity($date);
452
	    
453 30
	    if (null === $quantity) {
454
	        // invalid or does not exists on date
455 1
	        return 0;
456
	    }
457
	    
458 29
	    $quantity += $this->getIncrementQuantity($date);
459 29
		$quantity += $this->getDynamicQuantity($date);
460
		
461
		
462 29
		return $quantity;
463
	}
464
	
465
	
466
467
    /**
468
     * Get quantity for the agent if no specific initial quantity
469
     * Il s'agit de la quantite visible pour l'utilisateur final et qui n'inclu par la quantitee consommee.
470
     * Sans tenir compte d'une eventuelle quantite initiale specifique pour l'utilisateur
471
     * @param string $date     YYYY-MM-DD
472
     * @return float	in days or in hours
473
     */
474
	public function getRightQuantity($date = null)
475
	{
476
	    $right = $this->getRight();
477
	    $quantity = (float) $right->quantity;
478
	    $quantity += $right->getIncrementQuantity($date);
479
	    $quantity += $this->getDynamicQuantity($date);
480
	    
481
	    return $quantity;
482
	}
483
	
484
	
485
	
486
	/**
487
	 * Get dynamic quantity
488
	 * quantite ajoutee ou retiree dynamiquement (ex diminution des RTT en fonction des arrets maladie)
489
	 * avant la date specifiee en parametre
490
	 * 
491
	 * @param string $date     YYYY-MM-DD
492
	 * @return float
493
	 */
494 39
	public function getDynamicQuantity($date = null)
495
	{
496 39
		$quantity = 0.0;
497
		
498 39
		$I = $this->getDynamicRightIterator();
499 39
		if (isset($date)) {
500 14
		    $I->createdOn = $date.' 23:59:59';
501 14
		}
502
		
503 39
		foreach($I as $dr)
504
		{
505
			/*@var $dr absences_DynamicRight */
506 2
			$quantity += $dr->getQuantity();
507 39
		}
508
		
509 39
		return $quantity;
510
	}
511
	
512
	
513
	/**
514
	 * Reset the user agent to default right quantity
515
	 */
516
	public function setDefaultQuantity()
517
	{
518
		$agent = $this->getAgent();
519
		$right = $this->getRight();
520
		$u = $right->quantity_unit;
521
		
522
		$old_quantity = absences_quantity($this->quantity, $u);
523
		$new_quantity = absences_quantity($right->quantity, $u);
524
		
525
		$this->quantity = '';
526
		$this->save();
527
		
528
		
529
		
530
		$this->addMovement(sprintf(absences_translate('The quantity for user %s on right %s has been changed from %s to %s'), 
531
				$agent->getName(), $right->description, $old_quantity, $new_quantity));
532
	}
533
	
534
	
535
	
536
	
537
	/**
538
	 * Get the agentRight quantity to save in table
539
	 * the agentRight quantity will be set to default empty string
540
	 * if the input value is an empty string or the same value as the right quantity
541
	 * 
542
	 * return null if the value do not need any modification
543
	 *
544
	 * @param string $inputStr    The user input string from a form
545
     *
546
	 * @return string
547
	 */
548 10
	public function getQuantityFromInput($inputStr)
549
	{
550 10
	    $right = $this->getRight();
551 10
	    $posted = (float) str_replace(',', '.', $inputStr);
552 10
	    $posted = round($posted, 2);
553
	     
554
	    // les chiffres sont compares a 2 chiffre apres la virgule pour eviter les modifiaction dues a des arrondis
555
	    // si le gestionnaire clique plusieures fois sur enregistrer
556
557 10
	    $right_quantity = round(((float) $right->quantity) + $this->getDynamicQuantity() + $right->getIncrementQuantity(), 2);
558 10
	    $agentright_quantity = round(((float) $this->quantity) + $this->getDynamicQuantity() + $this->getAgentIncrementQuantity(), 2);
559
560
	    
561 10
	    if (absences_cq($posted, $right_quantity) || '' === $inputStr)
562 10
	    {
563 5
	        if ('' === $this->quantity) {
564
	            // already use the default
565 1
	            return null;
566
	        }
567
568 4
	        return '';
569
	    }
570
	    
571
	    
572 5
	    if (absences_cq($posted, 0) && '' === $this->quantity) {
573
	         
574
	        // agentRight does use the default, but modification was set to 0
575
	        // ->quantity must be set to the posted value
576
	        
577 1
	        return (string) (-1 * ($this->getDynamicQuantity() + $this->getAgentIncrementQuantity()));
578
	    }
579
	    
580
	    
581 4
	    if (absences_cq($posted, $agentright_quantity)) {
582
	        // agentRight quantity not modified
583 2
	        return null;
584
	    }
585
	    
586
	    
587 2
	    return (string) ($posted - ($this->getDynamicQuantity() + $this->getAgentIncrementQuantity()));
588
	}
589
	
590
	
591
	
592
	
593
	/**
594
	 * Disponibilite en fonction de la date de saisie de la demande de conges
595
	 * @return string
596
	 */
597
	public function getDateBeginValid()
598
	{
599
		if ('0000-00-00' === $this->date_begin_valid)
600
		{
601
			return $this->getRight()->date_begin_valid;
602
		}
603
		
604
		return $this->date_begin_valid;
605
	}
606
	
607
	/**
608
	 * Disponibilite en fonction de la date de saisie de la demande de conges
609
	 * @return string
610
	 */
611
	public function getDateEndValid()
612
	{
613
		if ('0000-00-00' === $this->date_end_valid)
614
		{
615
			return $this->getRight()->date_end_valid;
616
		}
617
	
618
		return $this->date_end_valid;
619
	}
620
	
621
	
622
	
623
	
624
	
625
	/**
626
	 * Get id user from row or from agent
627
	 * @return int
628
	 */
629
	private function getIdUser()
630
	{
631
		if (isset($this->id_user))
632
		{
633
			return $this->id_user;
634
		}
635
		
636
		if (isset($this->agent))
637
		{
638
			return $this->agent->getIdUser();
639
		}
640
		
641
		return null;
642
	}
643
	
644
	/**
645
	 * @return int
646
	 */
647
	private function getIdRight()
648
	{
649
		if (isset($this->id_right))
650
		{
651
			return $this->id_right;
652
		}
653
		
654
		if (isset($this->right))
655
		{
656
			return $this->right->id;
657
		}
658
		
659
		return null;
660
	}
661
	
662
	
663
	
664
	/**
665
	 * Get sum of entry element filtered by status
666
	 * @param string $status
667
	 * @param string $date     YYYY-MM-DD  Up to date
668
	 * @return float
669
	 */
670 21
	private function getEntryElemSum($status, $date = null)
671
	{
672
	    
673 21
	    require_once dirname(__FILE__).'/entry.class.php';
674 21
		$I = new absences_EntryIterator();
675
		
676 21 View Code Duplication
		if (!isset($date) || '0000-00-00' === $date) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
677 7
		    $I->status = $status;
678 7
		} else {
679 15
		    $I->createdOn = $date.' 23:59:59';
680
		}
681
		
682 21
		$I->users = array($this->id_user);
683 21
		$I->id_right = $this->id_right;
684
		
685 21
		$total = 0.0;
686
		
687
688 21
		foreach ($I as $entry) {
689
		    
690
		    /* @var $entry absences_Entry */
691
692 6
	        $dateStatus = $entry->getDateStatus($date);
693
	        
694
	        
695
	        
696 6
	        if ($dateStatus !== $status) {
697 1
	            continue;
698
	        }
699
700
		    
701
		    /*@var $entry absences_Entry */
702 5
		    $element = $entry->getElement($this->id_right);
703
		    
704 5
		    if (!isset($element)) {
705
		        continue;
706
		    }
707
708
		    
709 5
		    $total += (float) $element->quantity;
710 21
		}
711
712
		
713 21
		return $total;
714
	}
715
	
716
	/**
717
	 * Get sum of CET deposits filtered by status
718
	 * @param string $status
719
	 * @param string $date     YYYY-MM-DD  Up to date
720
	 * @return number
721
	 */
722 21
	private function getCetDepositSum($status, $date = null)
723
	{
724 21
	    require_once dirname(__FILE__).'/cet_deposit_request.class.php';
725 21
	    $I = new absences_CetDepositRequestIterator();
726
	    
727 21 View Code Duplication
	    if (!isset($date) || '0000-00-00' === $date) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
728 7
	        $I->status = $status;
729 7
	    } else {
730 15
	        $I->createdOn = $date.' 23:59:59';
731
	    }
732
	    
733 21
	    $I->archived = null;
734 21
	    $I->users = array($this->id_user);
735 21
	    $I->id_agent_right_source = $this->id;
736
	    
737
	    
738 21
	    $total = 0.0;
739
	    
740 21
	    foreach ($I as $cetDeposit) {
741
	        
742
	        
743
744
	        /* @var $cetDeposit absences_CetDepositRequest */
745
	    
746 4
            $dateStatus = $cetDeposit->getDateStatus($date);
747
            
748 4
            if ($dateStatus !== $status) {
749 2
                continue;
750
            }
751
	    
752 3
	        $total += (float) $cetDeposit->quantity;
753 21
	    }
754
	    
755 21
	    return $total;
756
	    
757
	}
758
	
759
	
760
	
761
	
762
	/**
763
	 * Get consumed confirmed quantity
764
	 * should work if user not associated to right
765
	 * param string $date
766
	 * @return float	in days or in hours
767
	 */
768 21
	public function getConfirmedQuantity($date = null)
769
	{
770 21
	    if (isset($date) && '0000-00-00' !== $date) {
771
	        // do not cache
772 15
	        return $this->getEntryElemSum('Y', $date) + $this->getCetDepositSum('Y', $date);
773
	    }
774
	    
775 7
		if (!isset($this->confirmed_quantity))
776 7
		{
777 7
			$this->confirmed_quantity = $this->getEntryElemSum('Y');
778 7
			$this->confirmed_quantity += $this->getCetDepositSum('Y');
779 7
		}
780
781 7
		return $this->confirmed_quantity;
782
	}
783
	
784
	
785
	
786
	
787
	/**
788
	 * Get consumed waiting quantity
789
	 *
790
	 * @return float	in days or in hours
791
	 */
792
	public function getWaitingQuantity()
793
	{
794
		if (!isset($this->waiting_quantity))
795
		{
796
			$this->waiting_quantity = $this->getEntryElemSum('');
797
			$this->waiting_quantity += $this->getCetDepositSum('');
798
		}
799
		return $this->waiting_quantity;
800
	}
801
	
802
	
803
	/**
804
	 * Get previsional quantity
805
	 *
806
	 * @return float	in days or in hours
807
	 */
808
	public function getPrevisionalQuantity()
809
	{
810
	    if (!isset($this->previsional_quantity)) {
811
	        $this->previsional_quantity = $this->getEntryElemSum('P');
812
	    }
813
	    
814
	    return $this->previsional_quantity;
815
	}
816
	
817
	
818
	
819
	
820
	/**
821
	 * Get available quantity 
822
	 * les demandes en attente de validation ne sont pas comptabilises comme des jours consommes
823
	 * @param string $date
824
	 * @return float	in days or in hours
825
	 */
826 21
	public function getAvailableQuantity($date = null)
827
	{
828 21
		$available = ($this->getQuantity($date) - $this->getConfirmedQuantity($date));
829
830 21
		return round($available, 2);
831
	}
832
	
833
	/**
834
	 * Quantite disponible epargnable
835
	 * @return float
836
	 */
837
	public function getCetAvailableQuantity()
838
	{
839
		
840
		$available = ($this->getAvailableQuantity()- $this->getWaitingQuantity());
841
		
842
		return $available;
843
	}
844
	
845
	
846
	public function getCetMaxQuantity()
847
	{
848
		$cet_quantity = (float) $this->getRight()->cet_quantity;
849
		
850
		return $cet_quantity;
851
	}
852
	
853
	
854
	
855
	/**
856
	 * Tester si le droit est dans le regime de l'agent
857
	 * @return bool
858
	 */
859
	public function isRightInAgentCollection()
860
	{
861
		global $babDB;
862
		
863
		$agent = $this->getAgent();
864
		
865
		$res = $babDB->db_query('SELECT id FROM absences_coll_rights WHERE id_coll='.$babDB->quote($agent->id_coll).' AND id_right='.$babDB->quote($this->id_right));
866
		
867
		return ($babDB->db_num_rows($res) > 0);
868
	}
869
	
870
	
871
	/**
872
	 * Liste des messages d'erreur produit par ce lien droit/utilisateur
873
	 * cette methode droit renvoyer des messages si le droit ne fonctionnera pas ou mal
874
	 * @return array
875
	 */
876
	public function getErrors()
877
	{
878
		$errors = array();
879
		$right = $this->getRight();
880
		$agent = $this->getAgent();
881
		
882 View Code Duplication
		if ($right->earlier && null === $agent->getDirEntryDate($right->earlier))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
883
		{
884
			$errors[] = absences_translate('The right contain a criterion based on an earlier date in the directory entry but the date is invalid');
885
		}
886
		
887 View Code Duplication
		if ($right->later && null === $agent->getDirEntryDate($right->later))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
888
		{
889
			$errors[] = absences_translate('The right contain a criterion based on a later date in the directory entry but the date is invalid');
890
		}
891
		
892
		
893
		return $errors;
894
	}
895
	
896
	
897
	
898
	/**
899
	 * Create report on right for the agent if possible
900
	 * @return bool
901
	 */
902
	public function createReport()
903
	{
904
		// faire le report des droit si le droit n'est plus valide et si il reste un solde non consome
905
		
906
		$report_quantity = ($this->getAvailableQuantity() - $this->getWaitingQuantity());
907
		$available = (int) round(100 * $report_quantity);
908
		if ($available === 0)
909
		{
910
			return false;
911
		}
912
		
913
		if ($this->getDateEndValid() == '0000-00-00')
914
		{
915
			// le droit est toujours valide dans le temps, on ne cree pas de report
916
			return false;
917
		}
918
		
919
		if (bab_mktime($this->getDateEndValid()." 23:59:59") > mktime())
920
		{
921
			// le droit est encore valide
922
			return false;
923
		}
924
		
925
		$report = $this->getRight()->getOrCreateReport();
926
		
927
		if (!($report instanceof absences_Right))
928
		{
929
			// le droit de report ne peut pas etre cree
930
			return false;
931
		}
932
		
933
		$agent = $this->getAgent();
934
		
935
		
936
		
937
		$agent_report = new absences_AgentRight();
938
		$agent_report->setAgent($agent);
939
		$agent_report->setRight($report);
940
		
941
		if (!$agent_report->getRow()) {
942
		    
943
			// le report n'existe pas pour cet utilisateur
944
			$agent_report->quantity = $report_quantity;	
945
			$agent_report->save();
946
			return true;
947
		} 
948
			
949
		// le report existe deja
950
	    
951
		$current_value = (int) round(100 *$agent_report->getQuantity());
952
		
953
		if ($current_value == (int) round(100 *$report_quantity)) {
954
		    
955
			return false;
956
		} 
957
958
		// exiting report need to be updated?
959
		// NO: T9487
960
		// $agent_report->quantity = $report_quantity;
961
		// $agent_report->save();
962
		return true;
963
		
964
	}
965
	
966
	
967
	/**
968
	 * @return float in days
969
	 */
970
	public function getQuantityAlertConsumed()
971
	{
972
		// trouver la consomation de l'agent pour les droits de type $quantity_alert_types sur la periode
973
		
974
		global $babDB;
975
		$right = $this->getRight();
976
		
977
		$query = '
978
		
979
		SELECT
980
		
981
		SUM(ee.quantity) quantity,
982
		r.quantity_unit
983
		FROM
984
		absences_entries e,
985
		absences_entries_elem ee,
986
		absences_rights r
987
		
988
		WHERE
989
		e.id_user='.$babDB->quote($this->getAgent()->getIdUser()).'
990
		AND r.id_type IN('.$babDB->quote(explode(',',$right->quantity_alert_types)).')
991
		AND r.id=ee.id_right
992
		AND e.id=ee.id_entry
993
		AND e.date_begin>='.$babDB->quote($right->quantity_alert_begin).'
994
		AND e.date_end<='.$babDB->quote($right->quantity_alert_end).'
995
		
996
		GROUP BY r.quantity_unit
997
		';
998
		
999
		
1000
		$res = $babDB->db_query($query);
1001
		
1002
		
1003
		$qte = 0.0;
1004
		
1005
		while ($arr = $babDB->db_fetch_assoc($res))
1006
		{
1007
			$quantity = (float) $arr['quantity'];
1008
		
1009
			if ($arr['quantity_unit'] == 'H')
1010
			{
1011
				$qte += ($quantity / 8);
1012
			} else {
1013
				$qte += $quantity;
1014
			}
1015
		}
1016
		
1017
		return $qte;
1018
	}
1019
	
1020
	
1021
	
1022
	/**
1023
	 * Retourne le message d'alerte sur la quantite consomme
1024
	 * ou null si l'alerte n'est pas ateinte
1025
	 * Le test est effectue sur la periode configuree
1026
	 * @return string | null
1027
	 */
1028
	public function getQuantityAlert()
1029
	{
1030
		require_once $GLOBALS['babInstallPath'].'utilit/dateTime.php';
1031
		
1032
		$right = $this->getRight();
1033
		$quantity_alert_days = (float) $right->quantity_alert_days;
1034
		if (0 === (int) round(100 * $quantity_alert_days))
1035
		{
1036
			return null;
1037
		}
1038
1039
		
1040
		if ('0000-00-00' === $right->quantity_alert_begin || '0000-00-00' === $right->quantity_alert_end)
1041
		{
1042
			bab_debug('Alert failed because of missing test period');
1043
			return null;
1044
		}
1045
		
1046
		
1047
		$qte = $this->getQuantityAlertConsumed();
1048
1049
		if ($qte > $quantity_alert_days)
1050
		{
1051
			return sprintf(
1052
				absences_translate('%s has consumed %s of %s beetween the %s and the %s'), 
1053
				$this->getAgent()->getName(), 
1054
				absences_quantity(round($qte,2), 'D'), 
1055
				$right->getQuantityAlertTypes(), 
1056
				bab_shortDate(bab_mktime($right->quantity_alert_begin), false),
1057
				bab_shortDate(bab_mktime($right->quantity_alert_end), false)
1058
			);
1059
		}
1060
1061
		return null;
1062
	}
1063
	
1064
	
1065
	
1066
	
1067
	
1068
	/**
1069
	 * Attribution du droit en fonction des jours demandes et valides
1070
	 * @return bool
1071
	 */
1072
	public function isAccessibleAccordingToRequests()
1073
	{
1074
		return $this->getRight()
1075
				->getRightRule()
1076
				->isAccessibleAccordingToRequests($this->getAgent()->getIdUser());
1077
	}
1078
	
1079
	
1080
	/**
1081
	 * Tester si le droit est accessible en fonction de la periode de validite du droit
1082
	 * @return bool
1083
	 */
1084
	public function isAccessibleByValidityPeriod()
1085
	{
1086
		$access= true;
1087
		
1088
		if( $this->getDateBeginValid() != '0000-00-00' && (bab_mktime($this->getDateBeginValid()." 00:00:00") > mktime())){
1089
			$access= false;
1090
		}
1091
		
1092 View Code Duplication
		if( $this->getDateEndValid() != '0000-00-00' && (bab_mktime($this->getDateEndValid()." 23:59:59") < mktime())){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
1093
			$access= false;
1094
		}
1095
		
1096
		return $access;
1097
	}
1098
	
1099
	
1100
	
1101
	
1102
	/**
1103
	 * Tester si le droit est accessible en fonction de la fiche d'annuaire de l'agent
1104
	 * @return bool
1105
	 */
1106
	public function isAcessibleByDirectoryEntry()
1107
	{
1108
		$right = $this->getRight();
1109
		
1110
		if (!$right->earlier && !$right->later)
1111
		{
1112
			return true;
1113
		}
1114
		
1115
		$agent = $this->getAgent();
1116
		
1117 View Code Duplication
		if ($right->earlier)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
1118
		{
1119
			$date = $agent->getDirEntryDate($right->earlier);
1120
			if (!isset($date))
1121
			{
1122
				return false;
1123
			}
1124
			
1125
			$year = (int) date('Y', bab_mktime($date));
1126
			$age = (((int)date('Y')) - $year);
1127
			
1128
			bab_debug(sprintf("Filtre par date anterieure pour le droit %s | age=%d (intervale %d - %d)", $right->description,$age, $right->earlier_begin_valid, $right->earlier_end_valid));
1129
1130
			if ($right->earlier_begin_valid > $age || $right->earlier_end_valid < $age)
1131
			{
1132
				return false;
1133
			}
1134
		}
1135
		
1136
		
1137 View Code Duplication
		if ($right->later)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
1138
		{
1139
			$date = $agent->getDirEntryDate($right->later);
1140
			if (!isset($date))
1141
			{
1142
				return false;
1143
			}
1144
			
1145
			$year = (int) date('Y', bab_mktime($date));
1146
			$last = ($year - (int) date('Y'));
1147
			
1148
			bab_debug(sprintf("Filtre par date posterieure pour le droit %s | reste=%d (intervale %d - %d)", $right->description, $last, $right->earlier_begin_valid, $right->earlier_end_valid));
1149
		
1150
			if ($right->later_begin_valid < $last || $right->later_end_valid > $last)
1151
			{
1152
				return false;
1153
			}
1154
		}
1155
		
1156
		
1157
		
1158
		return true;
1159
	}
1160
	
1161
	
1162
	
1163
	
1164
	/**
1165
	 * Tester si le droit est disponible dans le mois en cours (en fonction de la periode de conges demandee)
1166
	 * si cette methode renvoi true, il n'y a pas de fin de validite dans le mois en cours sauf si validoperlap est actif
1167
	 * 
1168
	 * si on ce base sur cette methode pour determiner si un droit doit etre incremente dans le mois
1169
	 *  - le droit sera incremente si pas de fin de validite dans le mois
1170
	 *  - le droit sera incremente si le chevauchement est active et que la fin de validite est dans le mois
1171
	 * 
1172
	 * 
1173
	 * @return bool
1174
	 */
1175 8 View Code Duplication
	public function isAccessibleOnMonth()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
1176
	{
1177 8
		require_once $GLOBALS['babInstallPath'].'utilit/dateTime.php';
1178 8
		$begin = new BAB_DateTime(date('Y'), date('n'), 1);
1179 8
		$end = new BAB_DateTime(date('Y'), date('n'), date('t'), 23, 59, 59);
1180
		
1181 8
		return $this->isAccessibleOnPeriod($begin->getTimeStamp(), $end->getTimeStamp());
1182
	}
1183
	
1184
	
1185
	
1186 5 View Code Duplication
	protected function saveQuantityIncMonth($quantity)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
1187
	{
1188 5
	    require_once dirname(__FILE__).'/increment_agent_right.class.php';
1189
	    
1190 5
	    $increment = new absences_IncrementAgentRight();
1191 5
	    $increment->id_user_right = $this->id;
1192 5
	    $increment->quantity = $quantity;
1193 5
	    $increment->createdOn = date('Y-m-d H:i:s');
1194 5
	    $increment->monthkey = date('Ym');
1195
	    
1196 5
	    $increment->saveOrUpdate();
1197 5
	}
1198
	
1199
	
1200
	/**
1201
	 * Increment quantity for the month if not allready done
1202
	 * return true if quantity has been modified
1203
	 * Do not call directly because the quantity_inc_last field exists only on the right
1204
	 * 
1205
	 * @param LibTimer_eventHourly $event optional event if the action is done via a background task
1206
	 * 
1207
	 * @return bool
1208
	 */
1209 8
	public function monthlyQuantityUpdate(LibTimer_eventHourly $event = null)
1210
	{
1211 8
	    if ('' === $this->quantity) {
1212
	        return false;
1213
	    }
1214
	    
1215 8
	    if (!$this->isAccessibleOnMonth())
1216 8
	    {
1217
	        return false;   
1218
	    }
1219
	    
1220 8
        $right = $this->getRight();	
1221
        
1222 8
        $old_ur_quantity = $this->quantity;
1223
        
1224 8
        $ur_quantity = $this->getQuantity();
1225 8
        $quantity_inc_month = $right->getQuantityIncMonth($ur_quantity);
1226 8
        $ur_quantity += $quantity_inc_month;
1227
        
1228 8
        if (0 === (int) round(100 * $quantity_inc_month)) {
1229 3
            return false;
1230
        }
1231
        
1232 5
        $this->saveQuantityIncMonth($quantity_inc_month);
1233
        
1234
1235 5
        $message = sprintf(
1236 5
            absences_translate('The quantity of the right "%s" and for user "%s" has been modified from %s to %s by the monthly update'),
1237 5
            $right->description,
1238 5
            $this->getAgent()->getName(),
1239 5
            $old_ur_quantity,
1240
            $ur_quantity
1241 5
        );
1242
        
1243 5
        $this->addMovement($message, '', 0);
1244
        
1245 5
        if (isset($event)) {
1246
            $event->log('absences', $message);
1247
        }
1248
        
1249 5
        return true;
1250
	}
1251
	
1252
	
1253
	
1254
	
1255
	
1256
	/**
1257
	 * Disponibilite en fonction de la periode de conges demandee
1258
	 * le droit est accessible si on ne test pas de demande (premiere page de la demande, ne pas appeller cette methode dans ce cas)
1259
	 *
1260
	 * @param int $beginp	Timestamp, debut de la periode demandee
1261
	 * @param int $endp		Timestamp, fin de la periode demandee
1262
	 * 
1263
	 * @return bool
1264
	 */
1265 8
	public function isAccessibleOnPeriod($beginp, $endp)
1266
	{
1267 8
		$rightRule = $this->getRight()->getRightRule();
1268
		
1269 8
		if (!$rightRule->getRow()) {
1270 8
		    return true;
1271
		}
1272
		
1273
		if ('0000-00-00' === $this->inperiod_start || '0000-00-00' === $this->inperiod_end)
1274
		{
1275
			// Use default
1276
			return $rightRule->isAccessibleOnPeriod($beginp, $endp);
1277
		}
1278
		
1279
		$access_include = 0;
1280
		$access_exclude = 1;
1281
	
1282
		$rightRule->addPeriodTest(
1283
				$access_include, // reference
1284
				$access_exclude, // reference
1285
				$beginp,
1286
				$endp,
1287
				1, // toujours dans l'intervalle car il y en a qu'un configure
1288
				$this->validoverlap,
1289
				$this->inperiod_start,
1290
				$this->inperiod_end
1291
		);
1292
	
1293
		
1294
	
1295
		$debug_include = $access_include ? 'TRUE' : 'FALSE';
1296
		$debug_exclude = $access_exclude ? 'TRUE' : 'FALSE';
1297
	
1298
		bab_debug(sprintf("id = %d \ntests de periodes d'inclusion %s \ntests de periodes d'exclusion %s\n",$this->id_right, $debug_include, $debug_exclude));
1299
	
1300
		return ($access_include && $access_exclude);
1301
	
1302
	}
1303
	
1304
	
1305
	
1306
	/**
1307
	 * Disponibilite en fonction de l'intervale entre date de debut de la periode de conges demandee et de la date courrante
1308
	 * le droit est accessible si on ne test pas de demande (premiere page de la demande, ne pas appeller cette methode dans ce cas)
1309
	 *
1310
	 * @param int $beginp	Timestamp, debut de la periode demandee
1311
	 * 
1312
	 * @return bool
1313
	 */
1314
	public function isAccessibleOnDelay($beginp)
1315
	{
1316
		$right = $this->getRight();
1317
		$delay_before = (int) $right->delay_before;
1318
		
1319
		if ($delay_before > 0)
1320
		{
1321
		
1322
			$now = BAB_DateTime::now();
1323
			$now->add($delay_before, BAB_DATETIME_DAY);
1324
			$nowTS = $now->getTimeStamp();
1325
		
1326
			bab_debug(sprintf("%s / Debut de periode : %s, Date de delais minimum : %s", $right->description, bab_shortDate($beginp), bab_shortDate($nowTS)));
1327
			
1328
			if($beginp <= $nowTS) {
1329
				return false;
1330
			}
1331
		}
1332
1333
		return true;
1334
	}
1335
	
1336
	
1337
	
1338
	
1339
	
1340
	
1341
	/**
1342
	 *
1343
	 * @param string $message	generated message
1344
	 * @param string $comment	Author comment
1345
	 */
1346 18
	public function addMovement($message, $comment = '', $id_author = null)
1347
	{
1348 8
		require_once dirname(__FILE__).'/movement.class.php';
1349
	
1350 8
		$movement = new absences_Movement();
1351 8
		$movement->message = $message;
1352 8
		$movement->comment = $comment;
1353
		
1354 8
		if (isset($id_author))
1355 18
		{
1356 5
			$movement->id_author = $id_author;
1357 5
		}
1358
		
1359 8
		$movement->setAgent($this->getAgent());
1360 8
		$movement->setRight($this->getRight());
0 ignored issues
show
Bug introduced by
It seems like $this->getRight() can be null; however, setRight() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
1361 8
		$movement->save();
1362 8
	}
1363
	
1364
	
1365
	/**
1366
	 * Enregistre un mouvement suite a la modification d'un droit pour un agent
1367
	 * a partir de la liste des droit ou dans la modification d'un seul droit pour l'agent
1368
	 * 
1369
	 * @param absences_Agent   $agent
1370
	 * @param absences_Changes $changes
1371
	 * @param string           $comment
1372
	 */
1373
	public function addAgentMovement(absences_Agent $agent, absences_Changes $changes, $comment)
1374
	{
1375
	    $changesStr = $changes->__toString();
1376
	    
1377
	    if (empty($changesStr)) {
1378
	        return;
1379
	    }
1380
	    
1381
	    $right = $this->getRight();
1382
	    
1383
	    $this->addMovement(
1384
	        sprintf(
1385
	            absences_translate('Update right "%s" parameters for user "%s", details : %s'),
1386
	            $right->description,
1387
	            $agent->getName(),
1388
	            $changesStr
1389
	        ),
1390
	        $comment
1391
	    );
1392
	}
1393
	
1394
	
1395
	/**
1396
	 * @return absences_IncrementAgentRightIterator
1397
	 */
1398 20
	protected function getIncrementAgentRightIterator()
1399
	{
1400 20
	    require_once dirname(__FILE__).'/increment_agent_right.class.php';
1401 20
	    $I = new absences_IncrementAgentRightIterator;
1402 20
	    $I->setAgentRight($this);
1403 20
	    return $I;
1404
	}
1405
	
1406
	
1407
	/**
1408
	 * @return absences_IncrementRecord[]
1409
	 */
1410 29
	public function getIncrementIterator()
1411
	{
1412 29
	    if ('' === $this->quantity) {
1413 23
	        return $this->getRight()->getIncrementIterator();
1414
	    }
1415
	    
1416 10
	    return $this->getIncrementAgentRightIterator();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->getIncrementAgentRightIterator(); (absences_IncrementAgentRightIterator) is incompatible with the return type documented by absences_AgentRight::getIncrementIterator of type absences_IncrementRecord[].

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
1417
	}
1418
	
1419
	
1420
	/**
1421
	 * Somme des quantitees produites par l'incrementation mensuelle du solde, valeur specifique de l'agent
1422
	 *
1423
	 * @return float
1424
	 */
1425 10 View Code Duplication
	public function getAgentIncrementQuantity($date = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
1426
	{
1427 10
	    $n = 0.0;
1428 10
	    $I = $this->getIncrementAgentRightIterator();
1429 10
	    $I->upto = $date;
1430
	    
1431 10
	    foreach($I as $d)
1432
	    {
1433
	        $n += (float) $d->quantity;
1434 10
	    }
1435
	    
1436 10
	    return $n;
1437
	}
1438
	
1439
	
1440
	
1441
	/**
1442
	 * Somme des quantitees produites par l'incrementation mensuelle du solde
1443
	 * @param string $date YYYY-MM-DD
1444
	 * @return float
1445
	 */
1446 29 View Code Duplication
	public function getIncrementQuantity($date = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
1447
	{
1448
	    
1449 29
	    $n = 0.0;
1450 29
	    $I = $this->getIncrementIterator();
1451
	    
1452 29
	    if (isset($date) && '0000-00-00' !== $date) {
1453 14
	         $I->upto = $date;
1454 14
	    }
1455
	    
1456 29
	    foreach($I as $d)
1457
	    {
1458 10
	        $n += (float) $d->quantity;
1459 29
	    }
1460
	
1461 29
	    return $n;
1462
	}
1463
	
1464
	
1465
	
1466
	/**
1467
	 * @return absences_DynamicRightIterator
1468
	 */
1469 39
	public function getDynamicRightIterator()
1470
	{
1471 39
		require_once dirname(__FILE__).'/dynamic_right.class.php';
1472 39
		$I = new absences_DynamicRightIterator;
1473 39
		$I->setAgentRight($this);
1474 39
		return $I;
1475
	}
1476
	
1477
	
1478
	/**
1479
	 * Somme des quantitees deja prises dans l'intervale de date specifie dans la configuration dynamique et sur les types specifies
1480
	 * peut contenir 2 lignes par demande, une en jours et une en heures
1481
	 * @return float
1482
	 */
1483
	protected function getDynamicConfirmedRes()
1484
	{
1485
		global $babDB;
1486
		
1487
		$right = $this->getRight();
1488
		
1489
		if ($right->dynconf_types != '' && $right->dynconf_end > $right->dynconf_begin)
1490
		{
1491
			$res = $babDB->db_query("
1492
				SELECT 
1493
					e.id id_entry, 
1494
					r.quantity_unit, 
1495
					SUM(ee.quantity) as quantity 
1496
				FROM
1497
					absences_entries_elem ee,
1498
					absences_entries e,
1499
					absences_rights r 
1500
				WHERE
1501
					e.id_user = ".$babDB->quote($this->getIdUser())."
1502
					AND e.status=".$babDB->quote('Y')." 
1503
					AND ee.id_entry = e.id 
1504
					AND e.date_begin<=".$babDB->quote($right->dynconf_end.' 23:59:59')." 
1505
					AND e.date_end>".$babDB->quote($right->dynconf_begin.' 00:00:00')." 
1506
					AND ee.id_right=r.id 
1507
					AND r.id_type IN(".$right->dynconf_types.") 
1508
					
1509
				GROUP BY r.quantity_unit, e.id 
1510
				ORDER BY e.createdOn
1511
			");
1512
			
1513
			
1514
			return $res;
1515
		}
1516
	
1517
		return null;
1518
	}
1519
	
1520
	
1521
	/**
1522
	 * Somme des quantitees deja prises dans l'intervale de date specifie dans la configuration dynamique et sur les types specifies
1523
	 * Une seule ligne par demande, en jours
1524
	 * 
1525
	 * @return array		associative array with id entry as key, number of days as value
1526
	 */
1527
	public function getDynamicConfirmedDays()
1528
	{
1529
		$res = $this->getDynamicConfirmedRes();
1530
		
1531
		if (!isset($res))
1532
		{
1533
			return array();
1534
		}
1535
		
1536
		global $babDB;
1537
		
1538
		$r = array();
1539
		while ($arr = $babDB->db_fetch_assoc($res))
1540
		{
1541
			
1542
			$id_entry = (int) $arr['id_entry'];
1543
			$quantity = (float) $arr['quantity'];
1544
			
1545
			if (!isset($r[$id_entry]))
1546
			{
1547
				$r[$id_entry] = 0.0;
1548
			}
1549
			
1550
			switch($arr['quantity_unit'])
1551
			{
1552
				case 'H':
1553
					$r[$id_entry] += $quantity/8;
1554
					break;
1555
				case 'D':
1556
					$r[$id_entry] += $quantity;
1557
					break;
1558
			}
1559
		}
1560
		
1561
		return $r;
1562
	}
1563
	
1564
	
1565
	/**
1566
	 * Somme des quantitees deja prises dans l'intervale de date specifie dans la configuration dynamique et sur les types specifies
1567
	 *
1568
	 * @return float
1569
	 */
1570
	public function getDynamicTotalConfirmedDays()
1571
	{
1572
		$n = 0.0;
1573
		$arr = $this->getDynamicConfirmedDays();
1574
		foreach($arr as $d)
1575
		{
1576
			$n += $d;
1577
		}
1578
		
1579
		return $n;
1580
	}
1581
	
1582
	
1583
	
1584
	
1585
	/**
1586
	 * Liste dynamique des modification du solde
1587
	 * Calculee a partir de la configuration de absences_dynamic_configuration
1588
	 * indexe par id_user_right/id_entry
1589
	 * @return array
1590
	 */
1591
	public function getDynamicMovements()
1592
	{
1593
		// parcourir les demandes effectuees sur ce droit, dans l'ordre de creation
1594
		// ajouter les quantitees dynamiques a chaque fois quand necessaire
1595
		
1596
		require_once dirname(__FILE__).'/dynamic_configuration.class.php';
1597
		require_once dirname(__FILE__).'/dynamic_right.class.php';
1598
		
1599
		
1600
		$min = 0.0;
1601
		$total = 0.0;
1602
		$movements = array();
1603
		
1604
		foreach ($this->getDynamicConfirmedDays() as  $id_entry => $quantity)
1605
		{
1606
		    // $id_entry : demande qui provoque une augmentation ou une diminution du solde
1607
		    // $quantity : total des jours confirmes qui provoquent une augmentation ou une diminution du solde
1608
		    
1609
		    
1610
			$I = new absences_DynamicConfigurationIterator();
1611
			$I->setRight($this->getRight());
0 ignored issues
show
Bug introduced by
It seems like $this->getRight() can be null; however, setRight() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
1612
			$I->min_test_quantity = $min;
1613
			
1614
			$total += $quantity;
1615
			$I->max_test_quantity = $total;
1616
			
1617
			
1618
			if ($I->count() > 0)
1619
			{
1620
				$min = $I->max_test_quantity;
1621
1622
				foreach($I as $configuration)
1623
				{
1624
					// lignes de configuration corespondantes au supplements de quantites induite par la demande
1625
					
1626
					$dynamic_right = new absences_DynamicRight();
1627
					$dynamic_right->id_entry = $id_entry;
1628
					$dynamic_right->createdOn = date('Y-m-d H:i:s');
1629
					$dynamic_right->id_user_right = $this->id;
1630
					$dynamic_right->quantity = $configuration->quantity; // negatif ou positif, dans la meme unite que le droit associe associe a $this
1631
					
1632
					if (isset($movements[$this->id.'/'.$id_entry])) {
1633
					    $movements[$this->id.'/'.$id_entry]->quantity += $configuration->quantity;
1634
					} else {
1635
					   $movements[$this->id.'/'.$id_entry] = $dynamic_right;
1636
					}
1637
					
1638
					if ($this->id_user == 190) {
1639
					    bab_debug($this->id.'/'.$id_entry.' '.$configuration->quantity.' min:'.$I->min_test_quantity.' max:'.$I->max_test_quantity);
1640
					}
1641
				}
1642
			
1643
			}
1644
		}
1645
		
1646
		
1647
		
1648
		return $movements;
1649
	}
1650
	
1651
	/**
1652
	 * Liste des movements de solde dynamiques enregistres en base de donnes, indexes par id_user_right/id_entry
1653
	 */
1654
	public function getDynamicRights()
1655
	{
1656
		$movements = array();
1657
		$res = $this->getDynamicRightIterator();
1658
		foreach($res as $dynamic_right)
1659
		{
1660
			$movements[$dynamic_right->id_user_right.'/'.$dynamic_right->id_entry] = $dynamic_right;
1661
		}
1662
		
1663
		return $movements;
1664
	}
1665
	
1666
	
1667
	/**
1668
	 * Update the dynamic rights
1669
	 * creer les lignes corespondantes a la configuration dans la table absences_dynamic_rights
1670
	 * retirer les lignes qui ne sont plus valides
1671
	 */
1672
	public function applyDynamicRight()
1673
	{
1674
		$saved_list = $this->getDynamicRights();
1675
		$update_list = $this->getDynamicMovements();
1676
		
1677
		foreach($saved_list as $key => $dynamic_right)
1678
		{
1679
			/*@var $dynamic_right absences_DynamicRight */
1680
			
1681
			if (!isset($update_list[$key]))
1682
			{
1683
				$dynamic_right->quantity = 0; // delete
1684
				$dynamic_right->save();
1685
			} else {
1686
				
1687
				$update = (int) round(100 * $update_list[$key]->quantity);
1688
				$existing = (int) round(100 * $dynamic_right->quantity);
1689
				
1690
				if ($update !== $existing)
1691
				{
1692
					$dynamic_right->quantity = $update_list[$key]->quantity;
1693
					$dynamic_right->save();
1694
				}
1695
			}
1696
		}
1697
		
1698
		
1699
		foreach($update_list as $key => $dynamic_right)
1700
		{
1701
			/*@var $dynamic_right absences_DynamicRight */
1702
			
1703
			if (!isset($saved_list[$key]))
1704
			{
1705
				$dynamic_right->save();
1706
			}
1707
		}
1708
	}
1709
	
1710
	
1711
	/**
1712
	 * Movements related to the agentRight
1713
	 * @return absences_MovementIterator
1714
	 */
1715
	public function getMovementIterator()
1716
	{
1717
	    require_once dirname(__FILE__).'/movement.class.php';
1718
	
1719
	    $I = new absences_MovementIterator();
1720
	    $I->setRight($this->getRight());
0 ignored issues
show
Bug introduced by
It seems like $this->getRight() can be null; however, setRight() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
1721
	    $I->setAgent($this->getAgent());
1722
	
1723
	    return $I;
1724
	}
1725
}
1726
1727
1728
1729
1730
class absences_AgentRightIterator extends absences_Iterator
1731
{
1732
	protected $agent;
1733
1734
	
1735
	
1736
	public function setAgent(absences_Agent $agent)
1737
	{
1738
		$this->agent = $agent;
1739
	}
1740
	
1741
	
1742
	public function getObject($data)
1743
	{
1744
		$agentRight = absences_AgentRight::getById($data['agentright__id']);
1745
		$agentRight->setRow($this->getRowByPrefix($data, 'agentright'));
1746
		
1747
		if ($right_row = $this->getRowByPrefix($data, 'right'))
1748
		{
1749
			$right = new absences_Right($right_row['id']);
1750
			$right->setRow($right_row);
1751
			$agentRight->setRight($right);
1752
			
1753
			if ($type_row = $this->getRowByPrefix($data, 'type'))
1754
			{
1755
				$type = new absences_Type($type_row['id']);
1756
				$type->setRow($type_row);
1757
				$right->setType($type);
1758
			}
1759
			
1760
			if ($right_rule = $this->getRowByPrefix($data, 'rule'))
1761
			{
1762
				require_once dirname(__FILE__).'/right_rule.class.php';
1763
				$rightrule = absences_RightRule::getFromId($right_rule['id']);
1764
				$rightrule->setRow($right_rule);
1765
				$right->setRightRule($rightrule);
1766
				$rightrule->setRight($right);
1767
			}
1768
			
1769
			$rgroup_row = $this->getRowByPrefix($data, 'rgroup');
1770
			if (isset($rgroup_row['id']))
1771
			{
1772
				$rgroup = new absences_Rgroup($rgroup_row['id']);
1773
				$rgroup->setRow($rgroup_row);
1774
				$right->setRgroup($rgroup);
1775
			}
1776
		}
1777
	
1778
1779
	
1780
		if (isset($this->agent))
1781
		{
1782
			$agentRight->setAgent($this->agent);
1783
		}
1784
	
1785
		return $agentRight;
1786
	}
1787
	
1788
	
1789
	
1790
}
1791
1792
1793
/**
1794
 * Iterateur des utilisations d'un droit
1795
 *
1796
 */
1797
class absences_AgentRightStatIterator extends absences_Iterator
1798
{
1799
	/**
1800
	 * @var absences_Right
1801
	 */
1802
	protected $right;
1803
1804
	/**
1805
	 * 
1806
	 * @var bool
1807
	 */
1808
	public $modified_quantity;
1809
1810
1811 10
	public function setRight(absences_Right $right)
1812
	{
1813 10
		$this->right = $right;
1814 10
	}
1815
	
1816
	
1817 10
	public function executeQuery()
1818
	{
1819 10
		if(is_null($this->_oResult))
1820 10
		{
1821 10
			global $babDB;
1822
			$req = "SELECT
1823
1824
				ur.* 
1825
				
1826
			FROM
1827 10
				".ABSENCES_USERS_RIGHTS_TBL." ur 
1828 10
			WHERE ur.id_right=".$babDB->quote($this->right->id)."
1829 10
			";
1830
			
1831 10
			if (isset($this->modified_quantity))
1832 10
			{
1833 10
				$req .= " AND ur.quantity<>''";
1834 10
			}
1835
	
1836
	
1837 10
			$this->setMySqlResult($this->getDataBaseAdapter()->db_query($req));
1838 10
		}
1839 10
	}
1840
	
1841
	
1842 8
	public function getObject($data)
1843
	{
1844 8
		$agentRight = absences_AgentRight::getById($data['id']);
1845 8
		$agentRight->setRow($data);
1846 8
		$agentRight->setRight($this->right);
1847
		
1848 8
		return $agentRight;
1849
	}
1850
	
1851
}
1852
1853
1854
1855
1856
/**
1857
 * iterateur des droits d'un agent, vue utilisateur
1858
 * droit ouverts, ordonnes alphabetiquement
1859
 */
1860
class absences_AgentRightUserIterator extends absences_AgentRightIterator
1861
{
1862
	/**
1863
	 * Show inactive rights or not
1864
	 * @var bool
1865
	 */
1866
	private $show_inactive = false;
1867
	
1868
	/**
1869
	 * Timestamp
1870
	 * @var int
1871
	 */
1872
	private $begin = null;
1873
	
1874
	/**
1875
	 * Timestamp
1876
	 * @var int
1877
	 */
1878
	private $end = null;
1879
	
1880
	/**
1881
	 * 
1882
	 * @var int
1883
	 */
1884
	private $kind = null;
1885
	
1886
	/**
1887
	 * 
1888
	 * @var bool
1889
	 */
1890
	private $use_in_cet = null;
1891
	
1892
	/**
1893
	 * 
1894
	 * @var string
1895
	 */
1896
	private $quantity_unit = null;
1897
	
1898
	
1899
	/**
1900
	 * si un gestionnaire depose une demande a la place d'un agent, il peut utiliser des droits inactifs
1901
	 * 
1902
	 * @param bool $status
1903
	 * @return absences_AgentRightUserIterator
1904
	 */
1905
	public function showInactive($status = true)
1906
	{
1907
		$this->show_inactive = $status;
1908
		return $this;
1909
	}
1910
	
1911
	/**
1912
	 * Definir la periode de la demande
1913
	 * si la periode de la demande n'est pas renseignee, les droits qui s'affichent en fonction de la periode de la demande serons toujours retournes par l'iterateur
1914
	 * 
1915
	 * @param int $begin
1916
	 * @param int $end
1917
	 * 
1918
	 * @return absences_AgentRightUserIterator
1919
	 */
1920
	public function setRequestPeriod($begin, $end)
1921
	{
1922
		$this->begin = $begin;
1923
		$this->end = $end;
1924
		return $this;
1925
	}
1926
	
1927
	/**
1928
	 * Filter results by kind
1929
	 * @param	int	$kind
1930
	 * 
1931
	 * @return absences_AgentRightUserIterator
1932
	 */
1933
	public function setKind($kind)
1934
	{
1935
		$this->kind = $kind;
1936
		return $this;
1937
	}
1938
	
1939
	
1940
	
1941
	/**
1942
	 * Filter results by use in CET
1943
	 * @param	bool	$pickup
1944
	 * @return absences_AgentRightUserIterator
1945
	 */
1946
	public function setUseInCet($pickup = true)
1947
	{
1948
		$this->use_in_cet = $pickup;
1949
		return $this;
1950
	}
1951
	
1952
	
1953
	/**
1954
	 * Filter by quantity_unit
1955
	 * @param	string	$unit		D | H
1956
	 * @return absences_AgentRightUserIterator
1957
	 */
1958
	public function setQuantityUnit($unit)
1959
	{
1960
		$this->quantity_unit = $unit;
1961
		return $this;
1962
	}
1963
	
1964
	
1965
	
1966
	public function executeQuery()
1967
	{
1968
		if(is_null($this->_oResult))
1969
		{
1970
			global $babDB;
1971
			$req = "SELECT
1972
			
1973
				r.id				right__id,
1974
				r.kind				right__kind,
1975
				r.id_creditor		right__id_creditor,
1976
			    r.createdOn		    right__createdOn,
1977
				r.date_entry		right__date_entry,
1978
				r.date_begin 		right__date_begin,
1979
				r.date_end 			right__date_end,
1980
				r.quantity			right__quantity,
1981
				r.quantity_unit 	right__quantity_unit,
1982
				r.id_type			right__id_type,
1983
				r.description		right__description,
1984
				r.active			right__active,
1985
				r.cbalance			right__cbalance,
1986
				r.date_begin_valid	right__date_begin_valid,
1987
				r.date_end_valid	right__date_end_valid,
1988
				r.date_end_fixed	right__date_end_fixed,
1989
				r.date_begin_fixed	right__date_begin_fixed,
1990
				r.no_distribution	right__no_distribution,
1991
				r.id_rgroup			right__id_rgroup,
1992
				r.earlier					right__earlier,
1993
	 			r.earlier_begin_valid		right__earlier_begin_valid,
1994
	  			r.earlier_end_valid			right__earlier_end_valid,
1995
	  			r.later						right__later,
1996
	  			r.later_begin_valid			right__later_begin_valid,
1997
	  			r.later_end_valid			right__later_end_valid,
1998
	  			r.sortkey					right__sortkey, 
1999
	  			r.require_approval			right__require_approval,
2000
				r.delay_before				right__delay_before, 
2001
				
2002
				
2003
				rules.id					rule__id,
2004
				rules.id_right				rule__id_right,
2005
				rules.validoverlap			rule__validoverlap,
2006
				rules.trigger_nbdays_min 	rule__trigger_nbdays_min,
2007
				rules.trigger_nbdays_max	rule__trigger_nbdays_max,
2008
				rules.trigger_type			rule__trigger_type,
2009
				rules.trigger_p1_begin		rule__trigger_p1_begin,
2010
				rules.trigger_p1_end		rule__trigger_p1_end,
2011
				rules.trigger_p2_begin		rule__trigger_p2_begin,
2012
				rules.trigger_p2_end		rule__trigger_p2_end,
2013
				rules.trigger_overlap		rule__trigger_overlap,
2014
				
2015
				rg.id 				rgroup__id,
2016
				rg.name 			rgroup__name,
2017
				rg.quantity_unit	rgroup__quantity_unit,
2018
				rg.recover			rgroup__recover,
2019
				rg.sortkey			rgroup__sortkey,
2020
				
2021
				ur.id				agentright__id,
2022
				ur.id_user			agentright__id_user,
2023
				ur.id_right			agentright__id_right,
2024
				ur.quantity 		agentright__quantity,
2025
				ur.date_begin_valid	agentright__date_begin_valid,
2026
				ur.date_end_valid	agentright__date_end_valid, 
2027
				
2028
				ur.inperiod_start	agentright__inperiod_start,
2029
				ur.inperiod_end		agentright__inperiod_end,
2030
				ur.validoverlap		agentright__validoverlap,
2031
				ur.saving_begin		agentright__saving_begin,
2032
				ur.saving_end		agentright__saving_end   
2033
				
2034
				
2035
			FROM
2036
				".ABSENCES_TYPES_TBL." t,
2037
				".ABSENCES_USERS_RIGHTS_TBL." ur,
2038
				".ABSENCES_RIGHTS_TBL." r
2039
				LEFT JOIN
2040
					".ABSENCES_RIGHTS_RULES_TBL." rules ON rules.id_right = r.id
2041
				LEFT JOIN
2042
					".ABSENCES_RGROUPS_TBL." rg ON rg.id = r.id_rgroup
2043
			WHERE 
2044
				ur.id_user=".$babDB->quote($this->agent->getIdUser())." AND ur.id_right=r.id AND r.id_type=t.id 	
2045
			";
2046
			
2047
			/*
2048
			$query .= "
2049
				AND t.id = c.id_type
2050
				AND c.id_coll=p.id_coll
2051
				AND p.id_user=".$babDB->quote($this->agent->getIdUser())."
2052
			";
2053
			*/
2054
			
2055
			if( !$this->show_inactive )
2056
			{
2057
				$req .= " AND r.active='Y'";
2058
			}
2059
			
2060
			if (isset($this->kind))
2061
			{
2062
				$req .= " AND r.kind=".$babDB->quote($this->kind);
2063
			}
2064
			
2065
			if (isset($this->use_in_cet))
2066
			{
2067
				$req .= " AND r.use_in_cet=".$babDB->quote((int) $this->use_in_cet);
2068
			}
2069
			
2070
			if (isset($this->quantity_unit))
2071
			{
2072
				$req .= " AND r.quantity_unit=".$babDB->quote($this->quantity_unit);
2073
			}
2074
			
2075
			$req .= " 
2076
			
2077
				GROUP BY r.id 
2078
				ORDER BY r.sortkey, r.description";
2079
			
2080
			
2081
			$this->setMySqlResult($this->getDataBaseAdapter()->db_query($req));
2082
		}
2083
	}
2084
	
2085
	
2086
	
2087
	/**
2088
	 * (non-PHPdoc)
2089
	 * @see absences_AgentRightIterator::getObject()
2090
	 */
2091
	public function getObject($data)
2092
	{
2093
		$agentRight = parent::getObject($data);
2094
		
2095
		
2096
		$right = $agentRight->getRight();
2097
		
2098
		if (!$agentRight->isAccessibleByValidityPeriod() || !$right->isAccessibleIfFixed())
2099
		{
2100
			return null;
2101
		}
2102
		
2103
		if (!$agentRight->isAcessibleByDirectoryEntry())
2104
		{
2105
			return null;
2106
		}
2107
		
2108
		if (isset($this->begin) && isset($this->end)) { // le doit est accessible si on ne test pas de periode de la demande (premiere page de la demande)
2109
			if (!$agentRight->isAccessibleOnPeriod($this->begin, $this->end))
2110
			{
2111
				return null;
2112
			}
2113
			
2114
			if (!$agentRight->isAccessibleOnDelay($this->begin))
2115
			{
2116
				return null;
2117
			}
2118
		}
2119
		
2120
		$rightRule = $agentRight->getRight()->getRightRule();
2121
	
2122
		// Attribution du droit en fonction des jours demandes et valides
2123
		if ($rightRule->getRow() && !$rightRule->isAccessibleAccordingToRequests($this->agent->getIdUser()) ) {
2124
			return null;
2125
		}
2126
		
2127
		
2128
		return $agentRight;
2129
		
2130
	}
2131
	
2132
	
2133
	
2134
	/**
2135
	 * 
2136
	 *
2137
	 * @return mixed
2138
	 */
2139
	public function next()
2140
	{
2141
		$this->executeQuery();
2142
		
2143
		do {
2144
			$agentRight = false;
2145
			if ($aDatas = $this->getDataBaseAdapter()->db_fetch_assoc($this->_oResult))
2146
			{
2147
				$agentRight = $this->getObject($aDatas);
2148
			}
2149
		} while (!isset($agentRight));
2150
	
2151
		if(false !== $agentRight)
2152
		{
2153
			$this->_iKey++;
2154
			$this->_oObject = $agentRight;
2155
		}
2156
		else
2157
		{
2158
			$this->_oObject = null;
2159
			$this->_iKey = self::EOF;
2160
		}
2161
	
2162
		return $this->_oObject;
2163
	}
2164
	
2165
	
2166
	
2167
	/**
2168
	 * (non-PHPdoc)
2169
	 * @see BAB_MySqlResultIterator::count()
2170
	 */
2171
	public function count()
2172
	{
2173
		$i = 0;
2174
		foreach($this as $agentRight)
2175
		{
2176
			$i++;
2177
		}
2178
		
2179
		$this->rewind();
2180
		return $i;
2181
	}
2182
}
2183
2184
2185
2186
2187
2188
/**
2189
 * iterateur des droits d'un agent, vue gestionnaire
2190
 * tout les droits associes a l'agent, ordonnes par annees, puis alphabetiquement
2191
 */
2192
class absences_AgentRightManagerIterator extends absences_AgentRightIterator
2193
{
2194
	/**
2195
	 * Filter with an array of id type
2196
	 * @var array
2197
	 */
2198
	public $types = null;
2199
2200
	public function executeQuery()
2201
	{
2202
		if(is_null($this->_oResult))
2203
		{
2204
			global $babDB;
2205
	
2206
			$query = '
2207
			SELECT
2208
			u.id				agentright__id,
2209
			u.id_user			agentright__id_user,
2210
			u.id_right			agentright__id_right,
2211
			u.quantity			agentright__quantity,
2212
			u.date_begin_valid	agentright__date_begin_valid,
2213
			u.date_end_valid	agentright__date_end_valid,  
2214
			
2215
	
2216
			r.id				right__id,
2217
			r.kind				right__kind,
2218
			r.id_creditor		right__id_creditor,
2219
			r.createdOn  		right__createdOn,
2220
			r.date_entry		right__date_entry,
2221
			r.date_begin 		right__date_begin,
2222
			r.date_end 			right__date_end,
2223
			r.quantity			right__quantity,
2224
			r.quantity_unit 	right__quantity_unit,
2225
			r.id_type			right__id_type,
2226
			r.description		right__description,
2227
			r.active			right__active,
2228
			r.cbalance			right__cbalance,
2229
			r.date_begin_valid	right__date_begin_valid,
2230
			r.date_end_valid	right__date_end_valid,
2231
			r.date_end_fixed	right__date_end_fixed,
2232
			r.date_begin_fixed	right__date_begin_fixed,
2233
			r.no_distribution	right__no_distribution,
2234
			r.id_rgroup			right__id_rgroup,
2235
			r.earlier			right__earlier,
2236
 			r.earlier_begin_valid	right__earlier_begin_valid,
2237
  			r.earlier_end_valid		right__earlier_end_valid,
2238
  			r.later					right__later,
2239
  			r.later_begin_valid		right__later_begin_valid,
2240
  			r.later_end_valid		right__later_end_valid,
2241
  			r.id_report_type		right__id_report_type,
2242
  			r.date_end_report		right__date_end_report,
2243
  			r.description_report	right__description_report,
2244
  			r.id_reported_from		right__id_reported_from,
2245
  			r.quantity_alert_days	right__quantity_alert_days,
2246
  			r.quantity_alert_types	right__quantity_alert_types,
2247
  			r.quantity_alert_begin	right__quantity_alert_begin,
2248
  			r.quantity_alert_end	right__quantity_alert_end,
2249
  			r.dynconf_types			right__dynconf_types,
2250
  			r.dynconf_begin			right__dynconf_begin,
2251
  			r.dynconf_end			right__dynconf_end,
2252
  			r.require_approval		right__require_approval,
2253
			r.delay_before			right__delay_before, 
2254
			r.quantity_inc_month    right__quantity_inc_month,
2255
			r.quantity_inc_last     right__quantity_inc_last,
2256
			r.quantity_inc_max      right__quantity_inc_max, 
2257
  			
2258
	
2259
			t.id				type__id,
2260
			t.name 				type__name,
2261
			t.description		type__description,
2262
			t.quantity			type__quantity,
2263
			t.maxdays			type__maxdays,
2264
			t.mindays			type__mindays,
2265
			t.defaultdays		type__defaultdays,
2266
			t.color				type__color,
2267
			t.cbalance			type__cbalance,
2268
	
2269
			rg.id				rgroup__id,
2270
			rg.name 			rgroup__name,
2271
	
2272
			IFNULL(rg.name, r.description) label,
2273
	
2274
	
2275
			YEAR(r.date_begin) year
2276
			FROM
2277
				absences_users_rights u,
2278
				absences_rights r
2279
					LEFT JOIN absences_rgroup rg ON rg.id = r.id_rgroup,
2280
			absences_types t
2281
	
2282
			WHERE 
2283
				id_user='.$babDB->quote($this->agent->getIdUser()).'
2284
				AND r.id = u.id_right
2285
				AND t.id = r.id_type
2286
			ORDER BY year DESC, label ASC';
2287
	
2288
	
2289
			$this->setMySqlResult($this->getDataBaseAdapter()->db_query($query));
2290
		}
2291
	}
2292
	
2293
}
2294