Completed
Push — master ( 50fc26...8a9369 )
by Paul
04:36
created

absences_AgentRight::getInitialQuantity()   C

Complexity

Conditions 8
Paths 16

Size

Total Lines 38
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 8.4423
Metric Value
dl 0
loc 38
ccs 17
cts 21
cp 0.8095
rs 5.3846
cc 8
eloc 17
nc 16
nop 1
crap 8.4423
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
	/**
835
	 * quantite disponible (colone solde de l'export)
836
	 * @return float
837
	 */
838
	public function getBalance()
839
	{
840
	    $available = ($this->getAvailableQuantity()- $this->getWaitingQuantity());
841
	    return $available;
842
	}
843
	
844
	/**
845
	 * Quantite disponible epargnable
846
	 * @return float
847
	 */
848
	public function getCetAvailableQuantity()
849
	{
850
		return $this->getBalance();
851
	}
852
	
853
	
854
	public function getCetMaxQuantity()
855
	{
856
		$cet_quantity = (float) $this->getRight()->cet_quantity;
857
		
858
		return $cet_quantity;
859
	}
860
	
861
	
862
	
863
	/**
864
	 * Tester si le droit est dans le regime de l'agent
865
	 * @return bool
866
	 */
867
	public function isRightInAgentCollection()
868
	{
869
		global $babDB;
870
		
871
		$agent = $this->getAgent();
872
		
873
		$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));
874
		
875
		return ($babDB->db_num_rows($res) > 0);
876
	}
877
	
878
	
879
	/**
880
	 * Liste des messages d'erreur produit par ce lien droit/utilisateur
881
	 * cette methode droit renvoyer des messages si le droit ne fonctionnera pas ou mal
882
	 * @return array
883
	 */
884
	public function getErrors()
885
	{
886
		$errors = array();
887
		$right = $this->getRight();
888
		$agent = $this->getAgent();
889
		
890 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...
891
		{
892
			$errors[] = absences_translate('The right contain a criterion based on an earlier date in the directory entry but the date is invalid');
893
		}
894
		
895 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...
896
		{
897
			$errors[] = absences_translate('The right contain a criterion based on a later date in the directory entry but the date is invalid');
898
		}
899
		
900
		
901
		return $errors;
902
	}
903
	
904
	
905
	
906
	/**
907
	 * Create report on right for the agent if possible
908
	 * @return bool
909
	 */
910
	public function createReport()
911
	{
912
		// faire le report des droit si le droit n'est plus valide et si il reste un solde non consome
913
		
914
		$report_quantity = ($this->getAvailableQuantity() - $this->getWaitingQuantity());
915
		$available = (int) round(100 * $report_quantity);
916
		if ($available === 0)
917
		{
918
			return false;
919
		}
920
		
921
		if ($this->getDateEndValid() == '0000-00-00')
922
		{
923
			// le droit est toujours valide dans le temps, on ne cree pas de report
924
			return false;
925
		}
926
		
927
		if (bab_mktime($this->getDateEndValid()." 23:59:59") > mktime())
928
		{
929
			// le droit est encore valide
930
			return false;
931
		}
932
		
933
		$report = $this->getRight()->getOrCreateReport();
934
		
935
		if (!($report instanceof absences_Right))
936
		{
937
			// le droit de report ne peut pas etre cree
938
			return false;
939
		}
940
		
941
		$agent = $this->getAgent();
942
		
943
		
944
		
945
		$agent_report = new absences_AgentRight();
946
		$agent_report->setAgent($agent);
947
		$agent_report->setRight($report);
948
		
949
		if (!$agent_report->getRow()) {
950
		    
951
			// le report n'existe pas pour cet utilisateur
952
			$agent_report->quantity = $report_quantity;	
953
			$agent_report->save();
954
			return true;
955
		} 
956
			
957
		// le report existe deja
958
	    
959
		$current_value = (int) round(100 *$agent_report->getQuantity());
960
		
961
		if ($current_value == (int) round(100 *$report_quantity)) {
962
		    
963
			return false;
964
		} 
965
966
		// exiting report need to be updated?
967
		// NO: T9487
968
		// $agent_report->quantity = $report_quantity;
969
		// $agent_report->save();
970
		return true;
971
		
972
	}
973
	
974
	
975
	/**
976
	 * @return float in days
977
	 */
978
	public function getQuantityAlertConsumed()
979
	{
980
		// trouver la consomation de l'agent pour les droits de type $quantity_alert_types sur la periode
981
		
982
		global $babDB;
983
		$right = $this->getRight();
984
		
985
		$query = '
986
		
987
		SELECT
988
		
989
		SUM(ee.quantity) quantity,
990
		r.quantity_unit
991
		FROM
992
		absences_entries e,
993
		absences_entries_elem ee,
994
		absences_rights r
995
		
996
		WHERE
997
		e.id_user='.$babDB->quote($this->getAgent()->getIdUser()).'
998
		AND r.id_type IN('.$babDB->quote(explode(',',$right->quantity_alert_types)).')
999
		AND r.id=ee.id_right
1000
		AND e.id=ee.id_entry
1001
		AND e.date_begin>='.$babDB->quote($right->quantity_alert_begin).'
1002
		AND e.date_end<='.$babDB->quote($right->quantity_alert_end).'
1003
		
1004
		GROUP BY r.quantity_unit
1005
		';
1006
		
1007
		
1008
		$res = $babDB->db_query($query);
1009
		
1010
		
1011
		$qte = 0.0;
1012
		
1013
		while ($arr = $babDB->db_fetch_assoc($res))
1014
		{
1015
			$quantity = (float) $arr['quantity'];
1016
		
1017
			if ($arr['quantity_unit'] == 'H')
1018
			{
1019
				$qte += ($quantity / 8);
1020
			} else {
1021
				$qte += $quantity;
1022
			}
1023
		}
1024
		
1025
		return $qte;
1026
	}
1027
	
1028
	
1029
	
1030
	/**
1031
	 * Retourne le message d'alerte sur la quantite consomme
1032
	 * ou null si l'alerte n'est pas ateinte
1033
	 * Le test est effectue sur la periode configuree
1034
	 * @return string | null
1035
	 */
1036
	public function getQuantityAlert()
1037
	{
1038
		require_once $GLOBALS['babInstallPath'].'utilit/dateTime.php';
1039
		
1040
		$right = $this->getRight();
1041
		$quantity_alert_days = (float) $right->quantity_alert_days;
1042
		if (0 === (int) round(100 * $quantity_alert_days))
1043
		{
1044
			return null;
1045
		}
1046
1047
		
1048
		if ('0000-00-00' === $right->quantity_alert_begin || '0000-00-00' === $right->quantity_alert_end)
1049
		{
1050
			bab_debug('Alert failed because of missing test period');
1051
			return null;
1052
		}
1053
		
1054
		
1055
		$qte = $this->getQuantityAlertConsumed();
1056
1057
		if ($qte > $quantity_alert_days)
1058
		{
1059
			return sprintf(
1060
				absences_translate('%s has consumed %s of %s beetween the %s and the %s'), 
1061
				$this->getAgent()->getName(), 
1062
				absences_quantity(round($qte,2), 'D'), 
1063
				$right->getQuantityAlertTypes(), 
1064
				bab_shortDate(bab_mktime($right->quantity_alert_begin), false),
1065
				bab_shortDate(bab_mktime($right->quantity_alert_end), false)
1066
			);
1067
		}
1068
1069
		return null;
1070
	}
1071
	
1072
	
1073
	
1074
	
1075
	
1076
	/**
1077
	 * Attribution du droit en fonction des jours demandes et valides
1078
	 * @return bool
1079
	 */
1080
	public function isAccessibleAccordingToRequests()
1081
	{
1082
		return $this->getRight()
1083
				->getRightRule()
1084
				->isAccessibleAccordingToRequests($this->getAgent()->getIdUser());
1085
	}
1086
	
1087
	
1088
	/**
1089
	 * Tester si le droit est accessible en fonction de la periode de validite du droit
1090
	 * @return bool
1091
	 */
1092
	public function isAccessibleByValidityPeriod()
1093
	{
1094
		$access= true;
1095
		
1096
		if( $this->getDateBeginValid() != '0000-00-00' && (bab_mktime($this->getDateBeginValid()." 00:00:00") > mktime())){
1097
			$access= false;
1098
		}
1099
		
1100 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...
1101
			$access= false;
1102
		}
1103
		
1104
		return $access;
1105
	}
1106
	
1107
	
1108
	
1109
	
1110
	/**
1111
	 * Tester si le droit est accessible en fonction de la fiche d'annuaire de l'agent
1112
	 * @return bool
1113
	 */
1114
	public function isAcessibleByDirectoryEntry()
1115
	{
1116
		$right = $this->getRight();
1117
		
1118
		if (!$right->earlier && !$right->later)
1119
		{
1120
			return true;
1121
		}
1122
		
1123
		$agent = $this->getAgent();
1124
		
1125 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...
1126
		{
1127
			$date = $agent->getDirEntryDate($right->earlier);
1128
			if (!isset($date))
1129
			{
1130
				return false;
1131
			}
1132
			
1133
			$year = (int) date('Y', bab_mktime($date));
1134
			$age = (((int)date('Y')) - $year);
1135
			
1136
			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));
1137
1138
			if ($right->earlier_begin_valid > $age || $right->earlier_end_valid < $age)
1139
			{
1140
				return false;
1141
			}
1142
		}
1143
		
1144
		
1145 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...
1146
		{
1147
			$date = $agent->getDirEntryDate($right->later);
1148
			if (!isset($date))
1149
			{
1150
				return false;
1151
			}
1152
			
1153
			$year = (int) date('Y', bab_mktime($date));
1154
			$last = ($year - (int) date('Y'));
1155
			
1156
			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));
1157
		
1158
			if ($right->later_begin_valid < $last || $right->later_end_valid > $last)
1159
			{
1160
				return false;
1161
			}
1162
		}
1163
		
1164
		
1165
		
1166
		return true;
1167
	}
1168
	
1169
	
1170
	
1171
	
1172
	/**
1173
	 * Tester si le droit est disponible dans le mois en cours (en fonction de la periode de conges demandee)
1174
	 * si cette methode renvoi true, il n'y a pas de fin de validite dans le mois en cours sauf si validoperlap est actif
1175
	 * 
1176
	 * si on ce base sur cette methode pour determiner si un droit doit etre incremente dans le mois
1177
	 *  - le droit sera incremente si pas de fin de validite dans le mois
1178
	 *  - le droit sera incremente si le chevauchement est active et que la fin de validite est dans le mois
1179
	 * 
1180
	 * 
1181
	 * @return bool
1182
	 */
1183 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...
1184
	{
1185 8
		require_once $GLOBALS['babInstallPath'].'utilit/dateTime.php';
1186 8
		$begin = new BAB_DateTime(date('Y'), date('n'), 1);
1187 8
		$end = new BAB_DateTime(date('Y'), date('n'), date('t'), 23, 59, 59);
1188
		
1189 8
		return $this->isAccessibleOnPeriod($begin->getTimeStamp(), $end->getTimeStamp());
1190
	}
1191
	
1192
	
1193
	
1194 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...
1195
	{
1196 5
	    require_once dirname(__FILE__).'/increment_agent_right.class.php';
1197
	    
1198 5
	    $increment = new absences_IncrementAgentRight();
1199 5
	    $increment->id_user_right = $this->id;
1200 5
	    $increment->quantity = $quantity;
1201 5
	    $increment->createdOn = date('Y-m-d H:i:s');
1202 5
	    $increment->monthkey = date('Ym');
1203
	    
1204 5
	    $increment->saveOrUpdate();
1205 5
	}
1206
	
1207
	
1208
	/**
1209
	 * Increment quantity for the month if not allready done
1210
	 * return true if quantity has been modified
1211
	 * Do not call directly because the quantity_inc_last field exists only on the right
1212
	 * 
1213
	 * @param LibTimer_eventHourly $event optional event if the action is done via a background task
1214
	 * 
1215
	 * @return bool
1216
	 */
1217 8
	public function monthlyQuantityUpdate(LibTimer_eventHourly $event = null)
1218
	{
1219 8
	    if ('' === $this->quantity) {
1220
	        return false;
1221
	    }
1222
	    
1223 8
	    if (!$this->isAccessibleOnMonth())
1224 8
	    {
1225
	        return false;   
1226
	    }
1227
	    
1228 8
        $right = $this->getRight();	
1229
        
1230 8
        $old_ur_quantity = $this->quantity;
1231
        
1232 8
        $ur_quantity = $this->getQuantity();
1233 8
        $quantity_inc_month = $right->getQuantityIncMonth($ur_quantity);
1234 8
        $ur_quantity += $quantity_inc_month;
1235
        
1236 8
        if (0 === (int) round(100 * $quantity_inc_month)) {
1237 3
            return false;
1238
        }
1239
        
1240 5
        $this->saveQuantityIncMonth($quantity_inc_month);
1241
        
1242
1243 5
        $message = sprintf(
1244 5
            absences_translate('The quantity of the right "%s" and for user "%s" has been modified from %s to %s by the monthly update'),
1245 5
            $right->description,
1246 5
            $this->getAgent()->getName(),
1247 5
            $old_ur_quantity,
1248
            $ur_quantity
1249 5
        );
1250
        
1251 5
        $this->addMovement($message, '', 0);
1252
        
1253 5
        if (isset($event)) {
1254
            $event->log('absences', $message);
1255
        }
1256
        
1257 5
        return true;
1258
	}
1259
	
1260
	
1261
	
1262
	
1263
	
1264
	/**
1265
	 * Disponibilite en fonction de la periode de conges demandee
1266
	 * le droit est accessible si on ne test pas de demande (premiere page de la demande, ne pas appeller cette methode dans ce cas)
1267
	 *
1268
	 * @param int $beginp	Timestamp, debut de la periode demandee
1269
	 * @param int $endp		Timestamp, fin de la periode demandee
1270
	 * 
1271
	 * @return bool
1272
	 */
1273 8
	public function isAccessibleOnPeriod($beginp, $endp)
1274
	{
1275 8
		$rightRule = $this->getRight()->getRightRule();
1276
		
1277 8
		if (!$rightRule->getRow()) {
1278 8
		    return true;
1279
		}
1280
		
1281
		if ('0000-00-00' === $this->inperiod_start || '0000-00-00' === $this->inperiod_end)
1282
		{
1283
			// Use default
1284
			return $rightRule->isAccessibleOnPeriod($beginp, $endp);
1285
		}
1286
		
1287
		$access_include = 0;
1288
		$access_exclude = 1;
1289
	
1290
		$rightRule->addPeriodTest(
1291
				$access_include, // reference
1292
				$access_exclude, // reference
1293
				$beginp,
1294
				$endp,
1295
				1, // toujours dans l'intervalle car il y en a qu'un configure
1296
				$this->validoverlap,
1297
				$this->inperiod_start,
1298
				$this->inperiod_end
1299
		);
1300
	
1301
		
1302
	
1303
		$debug_include = $access_include ? 'TRUE' : 'FALSE';
1304
		$debug_exclude = $access_exclude ? 'TRUE' : 'FALSE';
1305
	
1306
		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));
1307
	
1308
		return ($access_include && $access_exclude);
1309
	
1310
	}
1311
	
1312
	
1313
	
1314
	/**
1315
	 * Disponibilite en fonction de l'intervale entre date de debut de la periode de conges demandee et de la date courrante
1316
	 * le droit est accessible si on ne test pas de demande (premiere page de la demande, ne pas appeller cette methode dans ce cas)
1317
	 *
1318
	 * @param int $beginp	Timestamp, debut de la periode demandee
1319
	 * 
1320
	 * @return bool
1321
	 */
1322
	public function isAccessibleOnDelay($beginp)
1323
	{
1324
		$right = $this->getRight();
1325
		$delay_before = (int) $right->delay_before;
1326
		
1327
		if ($delay_before > 0)
1328
		{
1329
		
1330
			$now = BAB_DateTime::now();
1331
			$now->add($delay_before, BAB_DATETIME_DAY);
1332
			$nowTS = $now->getTimeStamp();
1333
		
1334
			bab_debug(sprintf("%s / Debut de periode : %s, Date de delais minimum : %s", $right->description, bab_shortDate($beginp), bab_shortDate($nowTS)));
1335
			
1336
			if($beginp <= $nowTS) {
1337
				return false;
1338
			}
1339
		}
1340
1341
		return true;
1342
	}
1343
1344
	
1345
	
1346
	/**
1347
	 *
1348
	 * @param string $message	generated message
1349
	 * @param string $comment	Author comment
1350
	 */
1351 8
	public function addMovement($message, $comment = '', $id_author = null)
1352
	{
1353 8
		require_once dirname(__FILE__).'/movement.class.php';
1354
	
1355 8
		$movement = new absences_Movement();
1356 8
		$movement->message = $message;
1357 8
		$movement->comment = $comment;
1358
		
1359 8
		if (isset($id_author))
1360 8
		{
1361 5
			$movement->id_author = $id_author;
1362 5
		}
1363
		
1364 8
		$movement->setAgent($this->getAgent());
1365 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...
1366 8
		$movement->save();
1367 8
	}
1368
	
1369
	
1370
	/**
1371
	 * Enregistre un mouvement suite a la modification d'un droit pour un agent
1372
	 * a partir de la liste des droit ou dans la modification d'un seul droit pour l'agent
1373
	 * 
1374
	 * @param absences_Agent   $agent
1375
	 * @param absences_Changes $changes
1376
	 * @param string           $comment
1377
	 */
1378
	public function addAgentMovement(absences_Agent $agent, absences_Changes $changes, $comment)
1379
	{
1380
	    $changesStr = $changes->__toString();
1381
	    
1382
	    if (empty($changesStr)) {
1383
	        return;
1384
	    }
1385
	    
1386
	    $right = $this->getRight();
1387
	    
1388
	    $this->addMovement(
1389
	        sprintf(
1390
	            absences_translate('Update right "%s" parameters for user "%s", details : %s'),
1391
	            $right->description,
1392
	            $agent->getName(),
1393
	            $changesStr
1394
	        ),
1395
	        $comment
1396
	    );
1397
	}
1398
	
1399
	
1400
	/**
1401
	 * @return absences_IncrementAgentRightIterator
1402
	 */
1403 20
	protected function getIncrementAgentRightIterator()
1404
	{
1405 20
	    require_once dirname(__FILE__).'/increment_agent_right.class.php';
1406 20
	    $I = new absences_IncrementAgentRightIterator;
1407 20
	    $I->setAgentRight($this);
1408 20
	    return $I;
1409 8
	}
1410
	
1411
	
1412
	/**
1413
	 * @return absences_IncrementRecord[]
1414
	 */
1415 29
	public function getIncrementIterator()
1416
	{
1417 29
	    if ('' === $this->quantity) {
1418 23
	        return $this->getRight()->getIncrementIterator();
1419
	    }
1420
	    
1421 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...
1422
	}
1423
	
1424
	
1425
	/**
1426
	 * Somme des quantitees produites par l'incrementation mensuelle du solde, valeur specifique de l'agent
1427
	 *
1428
	 * @return float
1429
	 */
1430 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...
1431
	{
1432 10
	    $n = 0.0;
1433 10
	    $I = $this->getIncrementAgentRightIterator();
1434 10
	    $I->upto = $date;
1435
	    
1436 10
	    foreach($I as $d)
1437
	    {
1438
	        $n += (float) $d->quantity;
1439 10
	    }
1440
	    
1441 10
	    return $n;
1442
	}
1443
	
1444
	
1445
	
1446
	/**
1447
	 * Somme des quantitees produites par l'incrementation mensuelle du solde
1448
	 * @param string $date YYYY-MM-DD
1449
	 * @return float
1450
	 */
1451 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...
1452
	{
1453
	    
1454 29
	    $n = 0.0;
1455 29
	    $I = $this->getIncrementIterator();
1456
	    
1457 29
	    if (isset($date) && '0000-00-00' !== $date) {
1458 14
	         $I->upto = $date;
1459 14
	    }
1460
	    
1461 29
	    foreach($I as $d)
1462
	    {
1463 10
	        $n += (float) $d->quantity;
1464 29
	    }
1465
	
1466 29
	    return $n;
1467
	}
1468
	
1469
	
1470
	
1471
	/**
1472
	 * @return absences_DynamicRightIterator
1473
	 */
1474 39
	public function getDynamicRightIterator()
1475
	{
1476 39
		require_once dirname(__FILE__).'/dynamic_right.class.php';
1477 39
		$I = new absences_DynamicRightIterator;
1478 39
		$I->setAgentRight($this);
1479 39
		return $I;
1480
	}
1481
	
1482
	
1483
	/**
1484
	 * Somme des quantitees deja prises dans l'intervale de date specifie dans la configuration dynamique et sur les types specifies
1485
	 * peut contenir 2 lignes par demande, une en jours et une en heures
1486
	 * @return float
1487
	 */
1488
	protected function getDynamicConfirmedRes()
1489
	{
1490
		global $babDB;
1491
		
1492
		$right = $this->getRight();
1493
		
1494
		if ($right->dynconf_types != '' && $right->dynconf_end > $right->dynconf_begin)
1495
		{
1496
			$res = $babDB->db_query("
1497
				SELECT 
1498
					e.id id_entry, 
1499
					r.quantity_unit, 
1500
					SUM(ee.quantity) as quantity 
1501
				FROM
1502
					absences_entries_elem ee,
1503
					absences_entries e,
1504
					absences_rights r 
1505
				WHERE
1506
					e.id_user = ".$babDB->quote($this->getIdUser())."
1507
					AND e.status=".$babDB->quote('Y')." 
1508
					AND ee.id_entry = e.id 
1509
					AND e.date_begin<=".$babDB->quote($right->dynconf_end.' 23:59:59')." 
1510
					AND e.date_end>".$babDB->quote($right->dynconf_begin.' 00:00:00')." 
1511
					AND ee.id_right=r.id 
1512
					AND r.id_type IN(".$right->dynconf_types.") 
1513
					
1514
				GROUP BY r.quantity_unit, e.id 
1515
				ORDER BY e.createdOn
1516
			");
1517
			
1518
			
1519
			return $res;
1520
		}
1521
	
1522
		return null;
1523
	}
1524
	
1525
	
1526
	/**
1527
	 * Somme des quantitees deja prises dans l'intervale de date specifie dans la configuration dynamique et sur les types specifies
1528
	 * Une seule ligne par demande, en jours
1529
	 * 
1530
	 * @return array		associative array with id entry as key, number of days as value
1531
	 */
1532
	public function getDynamicConfirmedDays()
1533
	{
1534
		$res = $this->getDynamicConfirmedRes();
1535
		
1536
		if (!isset($res))
1537
		{
1538
			return array();
1539
		}
1540
		
1541
		global $babDB;
1542
		
1543
		$r = array();
1544
		while ($arr = $babDB->db_fetch_assoc($res))
1545
		{
1546
			
1547
			$id_entry = (int) $arr['id_entry'];
1548
			$quantity = (float) $arr['quantity'];
1549
			
1550
			if (!isset($r[$id_entry]))
1551
			{
1552
				$r[$id_entry] = 0.0;
1553
			}
1554
			
1555
			switch($arr['quantity_unit'])
1556
			{
1557
				case 'H':
1558
					$r[$id_entry] += $quantity/8;
1559
					break;
1560
				case 'D':
1561
					$r[$id_entry] += $quantity;
1562
					break;
1563
			}
1564
		}
1565
		
1566
		return $r;
1567
	}
1568
	
1569
	
1570
	/**
1571
	 * Somme des quantitees deja prises dans l'intervale de date specifie dans la configuration dynamique et sur les types specifies
1572
	 *
1573
	 * @return float
1574
	 */
1575
	public function getDynamicTotalConfirmedDays()
1576
	{
1577
		$n = 0.0;
1578
		$arr = $this->getDynamicConfirmedDays();
1579
		foreach($arr as $d)
1580
		{
1581
			$n += $d;
1582
		}
1583
		
1584
		return $n;
1585
	}
1586
	
1587
	
1588
	
1589
	
1590
	/**
1591
	 * Liste dynamique des modification du solde
1592
	 * Calculee a partir de la configuration de absences_dynamic_configuration
1593
	 * indexe par id_user_right/id_entry
1594
	 * @return array
1595
	 */
1596
	public function getDynamicMovements()
1597
	{
1598
		// parcourir les demandes effectuees sur ce droit, dans l'ordre de creation
1599
		// ajouter les quantitees dynamiques a chaque fois quand necessaire
1600
		
1601
		require_once dirname(__FILE__).'/dynamic_configuration.class.php';
1602
		require_once dirname(__FILE__).'/dynamic_right.class.php';
1603
		
1604
		
1605
		$min = 0.0;
1606
		$total = 0.0;
1607
		$movements = array();
1608
		
1609
		foreach ($this->getDynamicConfirmedDays() as  $id_entry => $quantity)
1610
		{
1611
		    // $id_entry : demande qui provoque une augmentation ou une diminution du solde
1612
		    // $quantity : total des jours confirmes qui provoquent une augmentation ou une diminution du solde
1613
		    
1614
		    
1615
			$I = new absences_DynamicConfigurationIterator();
1616
			$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...
1617
			$I->min_test_quantity = $min;
1618
			
1619
			$total += $quantity;
1620
			$I->max_test_quantity = $total;
1621
			
1622
			
1623
			if ($I->count() > 0)
1624
			{
1625
				$min = $I->max_test_quantity;
1626
1627
				foreach($I as $configuration)
1628
				{
1629
					// lignes de configuration corespondantes au supplements de quantites induite par la demande
1630
					
1631
					$dynamic_right = new absences_DynamicRight();
1632
					$dynamic_right->id_entry = $id_entry;
1633
					$dynamic_right->createdOn = date('Y-m-d H:i:s');
1634
					$dynamic_right->id_user_right = $this->id;
1635
					$dynamic_right->quantity = $configuration->quantity; // negatif ou positif, dans la meme unite que le droit associe associe a $this
1636
					
1637
					if (isset($movements[$this->id.'/'.$id_entry])) {
1638
					    $movements[$this->id.'/'.$id_entry]->quantity += $configuration->quantity;
1639
					} else {
1640
					   $movements[$this->id.'/'.$id_entry] = $dynamic_right;
1641
					}
1642
					
1643
					if ($this->id_user == 190) {
1644
					    bab_debug($this->id.'/'.$id_entry.' '.$configuration->quantity.' min:'.$I->min_test_quantity.' max:'.$I->max_test_quantity);
1645
					}
1646
				}
1647
			
1648
			}
1649
		}
1650
		
1651
		
1652
		
1653
		return $movements;
1654
	}
1655
	
1656
	/**
1657
	 * Liste des movements de solde dynamiques enregistres en base de donnes, indexes par id_user_right/id_entry
1658
	 */
1659
	public function getDynamicRights()
1660
	{
1661
		$movements = array();
1662
		$res = $this->getDynamicRightIterator();
1663
		foreach($res as $dynamic_right)
1664
		{
1665
			$movements[$dynamic_right->id_user_right.'/'.$dynamic_right->id_entry] = $dynamic_right;
1666
		}
1667
		
1668
		return $movements;
1669
	}
1670
	
1671
	
1672
	/**
1673
	 * Update the dynamic rights
1674
	 * creer les lignes corespondantes a la configuration dans la table absences_dynamic_rights
1675
	 * retirer les lignes qui ne sont plus valides
1676
	 */
1677
	public function applyDynamicRight()
1678
	{
1679
		$saved_list = $this->getDynamicRights();
1680
		$update_list = $this->getDynamicMovements();
1681
		
1682
		foreach($saved_list as $key => $dynamic_right)
1683
		{
1684
			/*@var $dynamic_right absences_DynamicRight */
1685
			
1686
			if (!isset($update_list[$key]))
1687
			{
1688
				$dynamic_right->quantity = 0; // delete
1689
				$dynamic_right->save();
1690
			} else {
1691
				
1692
				$update = (int) round(100 * $update_list[$key]->quantity);
1693
				$existing = (int) round(100 * $dynamic_right->quantity);
1694
				
1695
				if ($update !== $existing)
1696
				{
1697
					$dynamic_right->quantity = $update_list[$key]->quantity;
1698
					$dynamic_right->save();
1699
				}
1700
			}
1701
		}
1702
		
1703
		
1704
		foreach($update_list as $key => $dynamic_right)
1705
		{
1706
			/*@var $dynamic_right absences_DynamicRight */
1707
			
1708
			if (!isset($saved_list[$key]))
1709
			{
1710
				$dynamic_right->save();
1711
			}
1712
		}
1713
	}
1714
	
1715
	
1716
	/**
1717
	 * Movements related to the agentRight
1718
	 * @return absences_MovementIterator
1719
	 */
1720
	public function getMovementIterator()
1721
	{
1722
	    require_once dirname(__FILE__).'/movement.class.php';
1723
	
1724
	    $I = new absences_MovementIterator();
1725
	    $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...
1726
	    $I->setAgent($this->getAgent());
1727
	
1728
	    return $I;
1729
	}
1730
}
1731
1732
1733
1734
1735
class absences_AgentRightIterator extends absences_Iterator
1736
{
1737
	protected $agent;
1738
1739
	
1740
	
1741
	public function setAgent(absences_Agent $agent)
1742
	{
1743
		$this->agent = $agent;
1744
	}
1745
	
1746
	
1747
	public function getObject($data)
1748
	{
1749
		$agentRight = absences_AgentRight::getById($data['agentright__id']);
1750
		$agentRight->setRow($this->getRowByPrefix($data, 'agentright'));
1751
		
1752
		if ($right_row = $this->getRowByPrefix($data, 'right'))
1753
		{
1754
			$right = new absences_Right($right_row['id']);
1755
			$right->setRow($right_row);
1756
			$agentRight->setRight($right);
1757
			
1758
			if ($type_row = $this->getRowByPrefix($data, 'type'))
1759
			{
1760
				$type = new absences_Type($type_row['id']);
1761
				$type->setRow($type_row);
1762
				$right->setType($type);
1763
			}
1764
			
1765
			if ($right_rule = $this->getRowByPrefix($data, 'rule'))
1766
			{
1767
				require_once dirname(__FILE__).'/right_rule.class.php';
1768
				$rightrule = absences_RightRule::getFromId($right_rule['id']);
1769
				$rightrule->setRow($right_rule);
1770
				$right->setRightRule($rightrule);
1771
				$rightrule->setRight($right);
1772
			}
1773
			
1774
			$rgroup_row = $this->getRowByPrefix($data, 'rgroup');
1775
			if (isset($rgroup_row['id']))
1776
			{
1777
				$rgroup = new absences_Rgroup($rgroup_row['id']);
1778
				$rgroup->setRow($rgroup_row);
1779
				$right->setRgroup($rgroup);
1780
			}
1781
		}
1782
	
1783
1784
	
1785
		if (isset($this->agent))
1786
		{
1787
			$agentRight->setAgent($this->agent);
1788
		}
1789
	
1790
		return $agentRight;
1791
	}
1792
	
1793
	
1794
	
1795
}
1796
1797
1798
/**
1799
 * Iterateur des utilisations d'un droit
1800
 *
1801
 */
1802
class absences_AgentRightStatIterator extends absences_Iterator
1803
{
1804
	/**
1805
	 * @var absences_Right
1806
	 */
1807
	protected $right;
1808
1809
	/**
1810
	 * 
1811
	 * @var bool
1812
	 */
1813
	public $modified_quantity;
1814
1815
1816 10
	public function setRight(absences_Right $right)
1817
	{
1818 10
		$this->right = $right;
1819 10
	}
1820
	
1821
	
1822 10
	public function executeQuery()
1823
	{
1824 10
		if(is_null($this->_oResult))
1825 10
		{
1826 10
			global $babDB;
1827
			$req = "SELECT
1828
1829
				ur.* 
1830
				
1831
			FROM
1832 10
				".ABSENCES_USERS_RIGHTS_TBL." ur 
1833 10
			WHERE ur.id_right=".$babDB->quote($this->right->id)."
1834 10
			";
1835
			
1836 10
			if (isset($this->modified_quantity))
1837 10
			{
1838 10
				$req .= " AND ur.quantity<>''";
1839 10
			}
1840
	
1841
	
1842 10
			$this->setMySqlResult($this->getDataBaseAdapter()->db_query($req));
1843 10
		}
1844 10
	}
1845
	
1846
	
1847 8
	public function getObject($data)
1848
	{
1849 8
		$agentRight = absences_AgentRight::getById($data['id']);
1850 8
		$agentRight->setRow($data);
1851 8
		$agentRight->setRight($this->right);
1852
		
1853 8
		return $agentRight;
1854
	}
1855
	
1856
}
1857
1858
1859
1860
1861
/**
1862
 * iterateur des droits d'un agent, vue utilisateur
1863
 * droit ouverts, ordonnes alphabetiquement
1864
 */
1865
class absences_AgentRightUserIterator extends absences_AgentRightIterator
1866
{
1867
	/**
1868
	 * Show inactive rights or not
1869
	 * @var bool
1870
	 */
1871
	private $show_inactive = false;
1872
	
1873
	/**
1874
	 * Timestamp
1875
	 * @var int
1876
	 */
1877
	private $begin = null;
1878
	
1879
	/**
1880
	 * Timestamp
1881
	 * @var int
1882
	 */
1883
	private $end = null;
1884
	
1885
	/**
1886
	 * 
1887
	 * @var int
1888
	 */
1889
	private $kind = null;
1890
	
1891
	/**
1892
	 * 
1893
	 * @var bool
1894
	 */
1895
	private $use_in_cet = null;
1896
	
1897
	/**
1898
	 * 
1899
	 * @var string
1900
	 */
1901
	private $quantity_unit = null;
1902
	
1903
	
1904
	/**
1905
	 * si un gestionnaire depose une demande a la place d'un agent, il peut utiliser des droits inactifs
1906
	 * 
1907
	 * @param bool $status
1908
	 * @return absences_AgentRightUserIterator
1909
	 */
1910
	public function showInactive($status = true)
1911
	{
1912
		$this->show_inactive = $status;
1913
		return $this;
1914
	}
1915
	
1916
	/**
1917
	 * Definir la periode de la demande
1918
	 * 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
1919
	 * 
1920
	 * @param int $begin
1921
	 * @param int $end
1922
	 * 
1923
	 * @return absences_AgentRightUserIterator
1924
	 */
1925
	public function setRequestPeriod($begin, $end)
1926
	{
1927
		$this->begin = $begin;
1928
		$this->end = $end;
1929
		return $this;
1930
	}
1931
	
1932
	/**
1933
	 * Filter results by kind
1934
	 * @param	int	$kind
1935
	 * 
1936
	 * @return absences_AgentRightUserIterator
1937
	 */
1938
	public function setKind($kind)
1939
	{
1940
		$this->kind = $kind;
1941
		return $this;
1942
	}
1943
	
1944
	
1945
	
1946
	/**
1947
	 * Filter results by use in CET
1948
	 * @param	bool	$pickup
1949
	 * @return absences_AgentRightUserIterator
1950
	 */
1951
	public function setUseInCet($pickup = true)
1952
	{
1953
		$this->use_in_cet = $pickup;
1954
		return $this;
1955
	}
1956
	
1957
	
1958
	/**
1959
	 * Filter by quantity_unit
1960
	 * @param	string	$unit		D | H
1961
	 * @return absences_AgentRightUserIterator
1962
	 */
1963
	public function setQuantityUnit($unit)
1964
	{
1965
		$this->quantity_unit = $unit;
1966
		return $this;
1967
	}
1968
	
1969
	
1970
	
1971
	public function executeQuery()
1972
	{
1973
		if(is_null($this->_oResult))
1974
		{
1975
			global $babDB;
1976
			$req = "SELECT
1977
			
1978
				r.id				right__id,
1979
				r.kind				right__kind,
1980
				r.id_creditor		right__id_creditor,
1981
			    r.createdOn		    right__createdOn,
1982
				r.date_entry		right__date_entry,
1983
				r.date_begin 		right__date_begin,
1984
				r.date_end 			right__date_end,
1985
				r.quantity			right__quantity,
1986
				r.quantity_unit 	right__quantity_unit,
1987
				r.id_type			right__id_type,
1988
				r.description		right__description,
1989
				r.active			right__active,
1990
				r.cbalance			right__cbalance,
1991
				r.date_begin_valid	right__date_begin_valid,
1992
				r.date_end_valid	right__date_end_valid,
1993
				r.date_end_fixed	right__date_end_fixed,
1994
				r.date_begin_fixed	right__date_begin_fixed,
1995
				r.no_distribution	right__no_distribution,
1996
				r.id_rgroup			right__id_rgroup,
1997
				r.earlier					right__earlier,
1998
	 			r.earlier_begin_valid		right__earlier_begin_valid,
1999
	  			r.earlier_end_valid			right__earlier_end_valid,
2000
	  			r.later						right__later,
2001
	  			r.later_begin_valid			right__later_begin_valid,
2002
	  			r.later_end_valid			right__later_end_valid,
2003
	  			r.sortkey					right__sortkey, 
2004
	  			r.require_approval			right__require_approval,
2005
				r.delay_before				right__delay_before, 
2006
				
2007
				
2008
				rules.id					rule__id,
2009
				rules.id_right				rule__id_right,
2010
				rules.validoverlap			rule__validoverlap,
2011
				rules.trigger_nbdays_min 	rule__trigger_nbdays_min,
2012
				rules.trigger_nbdays_max	rule__trigger_nbdays_max,
2013
				rules.trigger_type			rule__trigger_type,
2014
				rules.trigger_p1_begin		rule__trigger_p1_begin,
2015
				rules.trigger_p1_end		rule__trigger_p1_end,
2016
				rules.trigger_p2_begin		rule__trigger_p2_begin,
2017
				rules.trigger_p2_end		rule__trigger_p2_end,
2018
				rules.trigger_overlap		rule__trigger_overlap,
2019
				
2020
				rg.id 				rgroup__id,
2021
				rg.name 			rgroup__name,
2022
				rg.quantity_unit	rgroup__quantity_unit,
2023
				rg.recover			rgroup__recover,
2024
				rg.sortkey			rgroup__sortkey,
2025
				
2026
				ur.id				agentright__id,
2027
				ur.id_user			agentright__id_user,
2028
				ur.id_right			agentright__id_right,
2029
				ur.quantity 		agentright__quantity,
2030
				ur.date_begin_valid	agentright__date_begin_valid,
2031
				ur.date_end_valid	agentright__date_end_valid, 
2032
				
2033
				ur.inperiod_start	agentright__inperiod_start,
2034
				ur.inperiod_end		agentright__inperiod_end,
2035
				ur.validoverlap		agentright__validoverlap,
2036
				ur.saving_begin		agentright__saving_begin,
2037
				ur.saving_end		agentright__saving_end   
2038
				
2039
				
2040
			FROM
2041
				".ABSENCES_TYPES_TBL." t,
2042
				".ABSENCES_USERS_RIGHTS_TBL." ur,
2043
				".ABSENCES_RIGHTS_TBL." r
2044
				LEFT JOIN
2045
					".ABSENCES_RIGHTS_RULES_TBL." rules ON rules.id_right = r.id
2046
				LEFT JOIN
2047
					".ABSENCES_RGROUPS_TBL." rg ON rg.id = r.id_rgroup
2048
			WHERE 
2049
				ur.id_user=".$babDB->quote($this->agent->getIdUser())." AND ur.id_right=r.id AND r.id_type=t.id 	
2050
			";
2051
			
2052
			/*
2053
			$query .= "
2054
				AND t.id = c.id_type
2055
				AND c.id_coll=p.id_coll
2056
				AND p.id_user=".$babDB->quote($this->agent->getIdUser())."
2057
			";
2058
			*/
2059
			
2060
			if( !$this->show_inactive )
2061
			{
2062
				$req .= " AND r.active='Y'";
2063
			}
2064
			
2065
			if (isset($this->kind))
2066
			{
2067
				$req .= " AND r.kind=".$babDB->quote($this->kind);
2068
			}
2069
			
2070
			if (isset($this->use_in_cet))
2071
			{
2072
				$req .= " AND r.use_in_cet=".$babDB->quote((int) $this->use_in_cet);
2073
			}
2074
			
2075
			if (isset($this->quantity_unit))
2076
			{
2077
				$req .= " AND r.quantity_unit=".$babDB->quote($this->quantity_unit);
2078
			}
2079
			
2080
			$req .= " 
2081
			
2082
				GROUP BY r.id 
2083
				ORDER BY r.sortkey, r.description";
2084
			
2085
			
2086
			$this->setMySqlResult($this->getDataBaseAdapter()->db_query($req));
2087
		}
2088
	}
2089
	
2090
	
2091
	
2092
	/**
2093
	 * (non-PHPdoc)
2094
	 * @see absences_AgentRightIterator::getObject()
2095
	 */
2096
	public function getObject($data)
2097
	{
2098
		$agentRight = parent::getObject($data);
2099
		
2100
		
2101
		$right = $agentRight->getRight();
2102
		
2103
		if (!$agentRight->isAccessibleByValidityPeriod() || !$right->isAccessibleIfFixed())
2104
		{
2105
			return null;
2106
		}
2107
		
2108
		if (!$agentRight->isAcessibleByDirectoryEntry())
2109
		{
2110
			return null;
2111
		}
2112
		
2113
		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)
2114
			if (!$agentRight->isAccessibleOnPeriod($this->begin, $this->end))
2115
			{
2116
				return null;
2117
			}
2118
			
2119
			if (!$agentRight->isAccessibleOnDelay($this->begin))
2120
			{
2121
				return null;
2122
			}
2123
		}
2124
		
2125
		$rightRule = $agentRight->getRight()->getRightRule();
2126
	
2127
		// Attribution du droit en fonction des jours demandes et valides
2128
		if ($rightRule->getRow() && !$rightRule->isAccessibleAccordingToRequests($this->agent->getIdUser()) ) {
2129
			return null;
2130
		}
2131
		
2132
		
2133
		return $agentRight;
2134
		
2135
	}
2136
	
2137
	
2138
	
2139
	/**
2140
	 * 
2141
	 *
2142
	 * @return mixed
2143
	 */
2144
	public function next()
2145
	{
2146
		$this->executeQuery();
2147
		
2148
		do {
2149
			$agentRight = false;
2150
			if ($aDatas = $this->getDataBaseAdapter()->db_fetch_assoc($this->_oResult))
2151
			{
2152
				$agentRight = $this->getObject($aDatas);
2153
			}
2154
		} while (!isset($agentRight));
2155
	
2156
		if(false !== $agentRight)
2157
		{
2158
			$this->_iKey++;
2159
			$this->_oObject = $agentRight;
2160
		}
2161
		else
2162
		{
2163
			$this->_oObject = null;
2164
			$this->_iKey = self::EOF;
2165
		}
2166
	
2167
		return $this->_oObject;
2168
	}
2169
	
2170
	
2171
	
2172
	/**
2173
	 * (non-PHPdoc)
2174
	 * @see BAB_MySqlResultIterator::count()
2175
	 */
2176
	public function count()
2177
	{
2178
		$i = 0;
2179
		foreach($this as $agentRight)
2180
		{
2181
			$i++;
2182
		}
2183
		
2184
		$this->rewind();
2185
		return $i;
2186
	}
2187
}
2188
2189
2190
2191
2192
2193
/**
2194
 * iterateur des droits d'un agent, vue gestionnaire
2195
 * tout les droits associes a l'agent, ordonnes par annees, puis alphabetiquement
2196
 */
2197
class absences_AgentRightManagerIterator extends absences_AgentRightIterator
2198
{
2199
	/**
2200
	 * Filter with an array of id type
2201
	 * @var array
2202
	 */
2203
	public $types = null;
2204
2205
	public function executeQuery()
2206
	{
2207
		if(is_null($this->_oResult))
2208
		{
2209
			global $babDB;
2210
	
2211
			$query = '
2212
			SELECT
2213
			u.id				agentright__id,
2214
			u.id_user			agentright__id_user,
2215
			u.id_right			agentright__id_right,
2216
			u.quantity			agentright__quantity,
2217
			u.date_begin_valid	agentright__date_begin_valid,
2218
			u.date_end_valid	agentright__date_end_valid,  
2219
			
2220
	
2221
			r.id				right__id,
2222
			r.kind				right__kind,
2223
			r.id_creditor		right__id_creditor,
2224
			r.createdOn  		right__createdOn,
2225
			r.date_entry		right__date_entry,
2226
			r.date_begin 		right__date_begin,
2227
			r.date_end 			right__date_end,
2228
			r.quantity			right__quantity,
2229
			r.quantity_unit 	right__quantity_unit,
2230
			r.id_type			right__id_type,
2231
			r.description		right__description,
2232
			r.active			right__active,
2233
			r.cbalance			right__cbalance,
2234
			r.date_begin_valid	right__date_begin_valid,
2235
			r.date_end_valid	right__date_end_valid,
2236
			r.date_end_fixed	right__date_end_fixed,
2237
			r.date_begin_fixed	right__date_begin_fixed,
2238
			r.no_distribution	right__no_distribution,
2239
			r.id_rgroup			right__id_rgroup,
2240
			r.earlier			right__earlier,
2241
 			r.earlier_begin_valid	right__earlier_begin_valid,
2242
  			r.earlier_end_valid		right__earlier_end_valid,
2243
  			r.later					right__later,
2244
  			r.later_begin_valid		right__later_begin_valid,
2245
  			r.later_end_valid		right__later_end_valid,
2246
  			r.id_report_type		right__id_report_type,
2247
  			r.date_end_report		right__date_end_report,
2248
  			r.description_report	right__description_report,
2249
  			r.id_reported_from		right__id_reported_from,
2250
  			r.quantity_alert_days	right__quantity_alert_days,
2251
  			r.quantity_alert_types	right__quantity_alert_types,
2252
  			r.quantity_alert_begin	right__quantity_alert_begin,
2253
  			r.quantity_alert_end	right__quantity_alert_end,
2254
  			r.dynconf_types			right__dynconf_types,
2255
  			r.dynconf_begin			right__dynconf_begin,
2256
  			r.dynconf_end			right__dynconf_end,
2257
  			r.require_approval		right__require_approval,
2258
			r.delay_before			right__delay_before, 
2259
			r.quantity_inc_month    right__quantity_inc_month,
2260
			r.quantity_inc_last     right__quantity_inc_last,
2261
			r.quantity_inc_max      right__quantity_inc_max, 
2262
  			
2263
	
2264
			t.id				type__id,
2265
			t.name 				type__name,
2266
			t.description		type__description,
2267
			t.quantity			type__quantity,
2268
			t.maxdays			type__maxdays,
2269
			t.mindays			type__mindays,
2270
			t.defaultdays		type__defaultdays,
2271
			t.color				type__color,
2272
			t.cbalance			type__cbalance,
2273
	
2274
			rg.id				rgroup__id,
2275
			rg.name 			rgroup__name,
2276
	
2277
			IFNULL(rg.name, r.description) label,
2278
	
2279
	
2280
			YEAR(r.date_begin) year
2281
			FROM
2282
				absences_users_rights u,
2283
				absences_rights r
2284
					LEFT JOIN absences_rgroup rg ON rg.id = r.id_rgroup,
2285
			absences_types t
2286
	
2287
			WHERE 
2288
				id_user='.$babDB->quote($this->agent->getIdUser()).'
2289
				AND r.id = u.id_right
2290
				AND t.id = r.id_type
2291
			ORDER BY year DESC, label ASC';
2292
	
2293
	
2294
			$this->setMySqlResult($this->getDataBaseAdapter()->db_query($query));
2295
		}
2296
	}
2297
	
2298
}
2299