absences_AgentRight::setRight()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 5
rs 9.4285
ccs 3
cts 3
cp 1
crap 1
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
					inperiod_start='.$babDB->quote($this->inperiod_start).',
302 8
					inperiod_end='.$babDB->quote($this->inperiod_end).',
303
					validoverlap='.$babDB->quote($this->validoverlap).',
304 3
					saving_begin='.$babDB->quote($this->saving_begin).',
305
					saving_end='.$babDB->quote($this->saving_end).' 
306
				WHERE
307 8
					id='.$babDB->quote($this->id));
308
		}
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
	{
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
		$I->archived = null;
676 21
		
677 7 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...
678 7
		    $I->status = $status;
679 15
		} else {
680
		    $I->createdOn = $date.' 23:59:59';
681
		}
682 21
		
683 21
		$I->users = array($this->id_user);
684
		$I->id_right = $this->id_right;
685 21
		
686
		$total = 0.0;
687
		
688 21
689
		foreach ($I as $entry) {
690
		    
691
		    /* @var $entry absences_Entry */
692 6
693
	        $dateStatus = $entry->getDateStatus($date);
694
	        
695
	        
696 6
	        
697 1
	        if ($dateStatus !== $status) {
698
	            continue;
699
	        }
700
701
		    
702 5
		    /*@var $entry absences_Entry */
703
		    $element = $entry->getElement($this->id_right);
704 5
		    
705
		    if (!isset($element)) {
706
		        continue;
707
		    }
708
709 5
		    
710 21
		    $total += (float) $element->quantity;
711
		}
712
713 21
		
714
		return $total;
715
	}
716
	
717
	/**
718
	 * Get sum of CET deposits filtered by status
719
	 * @param string $status
720
	 * @param string $date     YYYY-MM-DD  Up to date
721
	 * @return number
722 21
	 */
723
	private function getCetDepositSum($status, $date = null)
724 21
	{
725 21
	    require_once dirname(__FILE__).'/cet_deposit_request.class.php';
726
	    $I = new absences_CetDepositRequestIterator();
727 21
	    
728 7 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...
729 7
	        $I->status = $status;
730 15
	    } else {
731
	        $I->createdOn = $date.' 23:59:59';
732
	    }
733 21
	    
734 21
	    $I->archived = null;
735 21
	    $I->users = array($this->id_user);
736
	    $I->id_agent_right_source = $this->id;
737
	    
738 21
	    
739
	    $total = 0.0;
740 21
	    
741
	    foreach ($I as $cetDeposit) {
742
	        
743
	        
744
745
	        /* @var $cetDeposit absences_CetDepositRequest */
746 4
	    
747
            $dateStatus = $cetDeposit->getDateStatus($date);
748 4
            
749 2
            if ($dateStatus !== $status) {
750
                continue;
751
            }
752 3
	    
753 21
	        $total += (float) $cetDeposit->quantity;
754
	    }
755 21
	    
756
	    return $total;
757
	    
758
	}
759
	
760
	
761
	
762
	
763
	/**
764
	 * Get consumed confirmed quantity
765
	 * should work if user not associated to right
766
	 * @param string $date
767
	 * @return float	in days or in hours
768 21
	 */
769
	public function getConfirmedQuantity($date = null)
770 21
	{
771
	    if (isset($date) && '0000-00-00' !== $date) {
772 15
	        // do not cache
773
	        return $this->getEntryElemSum('Y', $date) + $this->getCetDepositSum('Y', $date);
774
	    }
775 7
	    
776 7
		if (!isset($this->confirmed_quantity))
777 7
		{
778 7
			$this->confirmed_quantity = $this->getEntryElemSum('Y');
779 7
			$this->confirmed_quantity += $this->getCetDepositSum('Y');
780
		}
781 7
782
		return $this->confirmed_quantity;
783
	}
784
	
785
	
786
	
787
	
788
	/**
789
	 * Get consumed waiting quantity
790
	 *
791
	 * @return float	in days or in hours
792
	 */
793
	public function getWaitingQuantity()
794
	{
795
		if (!isset($this->waiting_quantity))
796
		{
797
			$this->waiting_quantity = $this->getEntryElemSum('');
798
			$this->waiting_quantity += $this->getCetDepositSum('');
799
		}
800
		return $this->waiting_quantity;
801
	}
802
	
803
	
804
	/**
805
	 * Get previsional quantity
806
	 *
807
	 * @return float	in days or in hours
808
	 */
809
	public function getPrevisionalQuantity()
810
	{
811
	    if (!isset($this->previsional_quantity)) {
812
	        $this->previsional_quantity = $this->getEntryElemSum('P');
813
	    }
814
	    
815
	    return $this->previsional_quantity;
816
	}
817
	
818
	
819
	
820
	
821
	/**
822
	 * Get available quantity 
823
	 * les demandes en attente de validation ne sont pas comptabilises comme des jours consommes
824
	 * @param string $date
825
	 * @return float	in days or in hours
826 21
	 */
827
	public function getAvailableQuantity($date = null)
828 21
	{
829
		$available = ($this->getQuantity($date) - $this->getConfirmedQuantity($date));
830 21
831
		return round($available, 2);
832
	}
833
	
834
	
835
	/**
836
	 * quantite disponible (colone solde de l'export)
837
	 * @return float
838
	 */
839
	public function getBalance()
840
	{
841
	    $available = ($this->getAvailableQuantity()- $this->getWaitingQuantity());
842
	    return $available;
843
	}
844
	
845
	/**
846
	 * Quantite disponible epargnable
847
	 * @return float
848
	 */
849
	public function getCetAvailableQuantity()
850
	{
851
		return $this->getBalance();
852
	}
853
	
854
	
855
	public function getCetMaxQuantity()
856
	{
857
		$cet_quantity = (float) $this->getRight()->cet_quantity;
858
		
859
		return $cet_quantity;
860
	}
861
	
862
	
863
	
864
	/**
865
	 * Tester si le droit est dans le regime de l'agent
866
	 * @return bool
867
	 */
868
	public function isRightInAgentCollection()
869
	{
870
		global $babDB;
871
		
872
		$agent = $this->getAgent();
873
		
874
		$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));
875
		
876
		return ($babDB->db_num_rows($res) > 0);
877
	}
878
	
879
	
880
	/**
881
	 * Liste des messages d'erreur produit par ce lien droit/utilisateur
882
	 * cette methode droit renvoyer des messages si le droit ne fonctionnera pas ou mal
883
	 * @return array
884
	 */
885
	public function getErrors()
886
	{
887
		$errors = array();
888
		$right = $this->getRight();
889
		$agent = $this->getAgent();
890
		
891 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...
892
		{
893
			$errors[] = absences_translate('The right contain a criterion based on an earlier date in the directory entry but the date is invalid');
894
		}
895
		
896 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...
897
		{
898
			$errors[] = absences_translate('The right contain a criterion based on a later date in the directory entry but the date is invalid');
899
		}
900
		
901
		
902
		return $errors;
903
	}
904
	
905
	
906
	
907
	/**
908
	 * Create report on right for the agent if possible
909
	 * @return bool
910
	 */
911
	public function createReport()
912
	{
913
		// faire le report des droit si le droit n'est plus valide et si il reste un solde non consome
914
		
915
		$report_quantity = ($this->getAvailableQuantity() - $this->getWaitingQuantity());
916
		$available = (int) round(100 * $report_quantity);
917
		if ($available === 0)
918
		{
919
			return false;
920
		}
921
		
922
		if ($this->getDateEndValid() == '0000-00-00')
923
		{
924
			// le droit est toujours valide dans le temps, on ne cree pas de report
925
			return false;
926
		}
927
		
928
		if (bab_mktime($this->getDateEndValid()." 23:59:59") > mktime())
929
		{
930
			// le droit est encore valide
931
			return false;
932
		}
933
		
934
		$report = $this->getRight()->getOrCreateReport();
935
		
936
		if (!($report instanceof absences_Right))
937
		{
938
			// le droit de report ne peut pas etre cree
939
			return false;
940
		}
941
		
942
		$agent = $this->getAgent();
943
		
944
		
945
		
946
		$agent_report = new absences_AgentRight();
947
		$agent_report->setAgent($agent);
948
		$agent_report->setRight($report);
949
		
950
		if (!$agent_report->getRow()) {
951
		    
952
			// le report n'existe pas pour cet utilisateur
953
			$agent_report->quantity = $report_quantity;	
954
			$agent_report->save();
955
			return true;
956
		} 
957
			
958
		// le report existe deja
959
	    
960
		$current_value = (int) round(100 *$agent_report->getQuantity());
961
		
962
		if ($current_value == (int) round(100 *$report_quantity)) {
963
		    
964
			return false;
965
		} 
966
967
		// exiting report need to be updated?
968
		// NO: T9487
969
		// $agent_report->quantity = $report_quantity;
970
		// $agent_report->save();
971
		return true;
972
		
973
	}
974
	
975
	
976
	/**
977
	 * @return float in days
978
	 */
979
	public function getQuantityAlertConsumed()
980
	{
981
		// trouver la consomation de l'agent pour les droits de type $quantity_alert_types sur la periode
982
		
983
		global $babDB;
984
		$right = $this->getRight();
985
		
986
		$query = '
987
		
988
		SELECT
989
		
990
		SUM(ee.quantity) quantity,
991
		r.quantity_unit
992
		FROM
993
		absences_entries e,
994
		absences_entries_elem ee,
995
		absences_rights r
996
		
997
		WHERE
998
		e.id_user='.$babDB->quote($this->getAgent()->getIdUser()).'
999
		AND r.id_type IN('.$babDB->quote(explode(',',$right->quantity_alert_types)).')
1000
		AND r.id=ee.id_right
1001
		AND e.id=ee.id_entry
1002
		AND e.date_begin>='.$babDB->quote($right->quantity_alert_begin).'
1003
		AND e.date_end<='.$babDB->quote($right->quantity_alert_end).'
1004
		
1005
		GROUP BY r.quantity_unit
1006
		';
1007
		
1008
		
1009
		$res = $babDB->db_query($query);
1010
		
1011
		
1012
		$qte = 0.0;
1013
		
1014
		while ($arr = $babDB->db_fetch_assoc($res))
1015
		{
1016
			$quantity = (float) $arr['quantity'];
1017
		
1018
			if ($arr['quantity_unit'] == 'H')
1019
			{
1020
				$qte += ($quantity / 8);
1021
			} else {
1022
				$qte += $quantity;
1023
			}
1024
		}
1025
		
1026
		return $qte;
1027
	}
1028
	
1029
	
1030
	
1031
	/**
1032
	 * Retourne le message d'alerte sur la quantite consomme
1033
	 * ou null si l'alerte n'est pas ateinte
1034
	 * Le test est effectue sur la periode configuree
1035
	 * @return string | null
1036
	 */
1037
	public function getQuantityAlert()
1038
	{
1039
		require_once $GLOBALS['babInstallPath'].'utilit/dateTime.php';
1040
		
1041
		$right = $this->getRight();
1042
		$quantity_alert_days = (float) $right->quantity_alert_days;
1043
		if (0 === (int) round(100 * $quantity_alert_days))
1044
		{
1045
			return null;
1046
		}
1047
1048
		
1049
		if ('0000-00-00' === $right->quantity_alert_begin || '0000-00-00' === $right->quantity_alert_end)
1050
		{
1051
			bab_debug('Alert failed because of missing test period');
1052
			return null;
1053
		}
1054
		
1055
		
1056
		$qte = $this->getQuantityAlertConsumed();
1057
1058
		if ($qte > $quantity_alert_days)
1059
		{
1060
			return sprintf(
1061
				absences_translate('%s has consumed %s of %s beetween the %s and the %s'), 
1062
				$this->getAgent()->getName(), 
1063
				absences_quantity(round($qte,2), 'D'), 
1064
				$right->getQuantityAlertTypes(), 
1065
				bab_shortDate(bab_mktime($right->quantity_alert_begin), false),
1066
				bab_shortDate(bab_mktime($right->quantity_alert_end), false)
1067
			);
1068
		}
1069
1070
		return null;
1071
	}
1072
	
1073
	
1074
	
1075
	
1076
	
1077
	/**
1078
	 * Attribution du droit en fonction des jours demandes et valides
1079
	 * @return bool
1080
	 */
1081
	public function isAccessibleAccordingToRequests()
1082
	{
1083
		return $this->getRight()
1084
				->getRightRule()
1085
				->isAccessibleAccordingToRequests($this->getAgent()->getIdUser());
1086
	}
1087
	
1088
	
1089
	/**
1090
	 * Tester si le droit est accessible en fonction de la periode de validite du droit
1091
	 * @return bool
1092
	 */
1093
	public function isAccessibleByValidityPeriod()
1094
	{
1095
		$access= true;
1096
		
1097
		if( $this->getDateBeginValid() != '0000-00-00' && (bab_mktime($this->getDateBeginValid()." 00:00:00") > mktime())){
1098
			$access= false;
1099
		}
1100
		
1101 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...
1102
			$access= false;
1103
		}
1104
		
1105
		return $access;
1106
	}
1107
	
1108
	
1109
	
1110
	
1111
	/**
1112
	 * Tester si le droit est accessible en fonction de la fiche d'annuaire de l'agent
1113
	 * @return bool
1114
	 */
1115
	public function isAcessibleByDirectoryEntry()
1116
	{
1117
		$right = $this->getRight();
1118
		
1119
		if (!$right->earlier && !$right->later)
1120
		{
1121
			return true;
1122
		}
1123
		
1124
		$agent = $this->getAgent();
1125
		
1126 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...
1127
		{
1128
			$date = $agent->getDirEntryDate($right->earlier);
1129
			if (!isset($date))
1130
			{
1131
				return false;
1132
			}
1133
			
1134
			$year = (int) date('Y', bab_mktime($date));
1135
			$age = (((int)date('Y')) - $year);
1136
			
1137
			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));
1138
1139
			if ($right->earlier_begin_valid > $age || $right->earlier_end_valid < $age)
1140
			{
1141
				return false;
1142
			}
1143
		}
1144
		
1145
		
1146 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...
1147
		{
1148
			$date = $agent->getDirEntryDate($right->later);
1149
			if (!isset($date))
1150
			{
1151
				return false;
1152
			}
1153
			
1154
			$year = (int) date('Y', bab_mktime($date));
1155
			$last = ($year - (int) date('Y'));
1156
			
1157
			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));
1158
		
1159
			if ($right->later_begin_valid < $last || $right->later_end_valid > $last)
1160
			{
1161
				return false;
1162
			}
1163
		}
1164
		
1165
		
1166
		
1167
		return true;
1168
	}
1169
	
1170
	
1171
	
1172
	
1173
	/**
1174
	 * Tester si le droit est disponible dans le mois en cours (en fonction de la periode de conges demandee)
1175
	 * si cette methode renvoi true, il n'y a pas de fin de validite dans le mois en cours sauf si validoperlap est actif
1176
	 * 
1177
	 * si on ce base sur cette methode pour determiner si un droit doit etre incremente dans le mois
1178
	 *  - le droit sera incremente si pas de fin de validite dans le mois
1179
	 *  - le droit sera incremente si le chevauchement est active et que la fin de validite est dans le mois
1180
	 * 
1181
	 * 
1182
	 * @return bool
1183 8
	 */
1184 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...
1185 8
	{
1186 8
		require_once $GLOBALS['babInstallPath'].'utilit/dateTime.php';
1187 8
		$begin = new BAB_DateTime(date('Y'), date('n'), 1);
1188
		$end = new BAB_DateTime(date('Y'), date('n'), date('t'), 23, 59, 59);
1189 8
		
1190
		return $this->isAccessibleOnPeriod($begin->getTimeStamp(), $end->getTimeStamp());
1191
	}
1192
	
1193
	
1194 5
	
1195 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...
1196 5
	{
1197
	    require_once dirname(__FILE__).'/increment_agent_right.class.php';
1198 5
	    
1199 5
	    $increment = new absences_IncrementAgentRight();
1200 5
	    $increment->id_user_right = $this->id;
1201 5
	    $increment->quantity = $quantity;
1202 5
	    $increment->createdOn = date('Y-m-d H:i:s');
1203
	    $increment->monthkey = date('Ym');
1204 5
	    
1205 5
	    $increment->saveOrUpdate();
1206
	}
1207
	
1208
	
1209
	/**
1210
	 * Increment quantity for the month if not allready done
1211
	 * return true if quantity has been modified
1212
	 * Do not call directly because the quantity_inc_last field exists only on the right
1213
	 * 
1214
	 * @param LibTimer_eventHourly $event optional event if the action is done via a background task
1215
	 * 
1216
	 * @return bool
1217 8
	 */
1218
	public function monthlyQuantityUpdate(LibTimer_eventHourly $event = null)
1219 8
	{
1220
	    if ('' === $this->quantity) {
1221
	        return false;
1222
	    }
1223 8
	    
1224 8
	    if (!$this->isAccessibleOnMonth())
1225
	    {
1226
	        return false;   
1227
	    }
1228 8
	    
1229
        $right = $this->getRight();	
1230 8
        
1231 8
        $ur_quantity = $this->getQuantity();
1232 8
        $old_ur_quantity = $ur_quantity;
1233 8
        $quantity_inc_month = $right->getQuantityIncMonth($ur_quantity);
1234
        $ur_quantity += $quantity_inc_month;
1235 8
        
1236 3
        if (0 === (int) round(100 * $quantity_inc_month)) {
1237
            return false;
1238
        }
1239 5
        
1240
        $this->saveQuantityIncMonth($quantity_inc_month);
1241
        
1242 5
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
            $old_ur_quantity,
1248 5
            $ur_quantity
1249
        );
1250 5
        
1251
        $this->addMovement($message, '', 0);
1252 5
        
1253
        if (isset($event)) {
1254
            $event->log('absences', $message);
1255
        }
1256 5
        
1257
        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 8
	 */
1273
	public function isAccessibleOnPeriod($beginp, $endp)
1274 8
	{
1275
		$rightRule = $this->getRight()->getRightRule();
1276 8
		
1277 8
		if (!$rightRule->getRow()) {
1278
		    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 15
	 */
1351
	public function addMovement($message, $comment = '', $id_author = null)
1352 8
	{
1353
		require_once dirname(__FILE__).'/movement.class.php';
1354 8
	
1355 8
		$movement = new absences_Movement();
1356 8
		$movement->message = $message;
1357
		$movement->comment = $comment;
1358 8
		
1359 8
		if (isset($id_author))
1360 15
		{
1361 5
			$movement->id_author = $id_author;
1362
		}
1363 8
		
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
	}
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 20
	 */
1403
	protected function getIncrementAgentRightIterator()
1404 20
	{
1405 20
	    require_once dirname(__FILE__).'/increment_agent_right.class.php';
1406 20
	    $I = new absences_IncrementAgentRightIterator;
1407 20
	    $I->setAgentRight($this);
1408
	    return $I;
1409
	}
1410
	
1411
	
1412
	/**
1413
	 * @return absences_IncrementRecord[]
1414 29
	 */
1415
	public function getIncrementIterator()
1416 29
	{
1417 23
	    if ('' === $this->quantity) {
1418
	        return $this->getRight()->getIncrementIterator();
1419
	    }
1420 10
	    
1421
	    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 10
	 */
1430 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 10
	{
1432 10
	    $n = 0.0;
1433 10
	    $I = $this->getIncrementAgentRightIterator();
1434
	    $I->upto = $date;
1435 10
	    
1436
	    foreach($I as $d)
1437
	    {
1438 10
	        $n += (float) $d->quantity;
1439
	    }
1440 10
	    
1441
	    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 29
	 */
1451 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 29
	    
1454 29
	    $n = 0.0;
1455
	    $I = $this->getIncrementIterator();
1456 29
	    
1457 14
	    if (isset($date) && '0000-00-00' !== $date) {
1458 14
	         $I->upto = $date;
1459
	    }
1460 29
	    
1461
	    foreach($I as $d)
1462 10
	    {
1463 29
	        $n += (float) $d->quantity;
1464
	    }
1465 29
	
1466
	    return $n;
1467
	}
1468
	
1469
	
1470
	
1471
	/**
1472
	 * @return absences_DynamicRightIterator
1473 39
	 */
1474
	public function getDynamicRightIterator()
1475 39
	{
1476 39
		require_once dirname(__FILE__).'/dynamic_right.class.php';
1477 39
		$I = new absences_DynamicRightIterator;
1478 39
		$I->setAgentRight($this);
1479
		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 10
1816
	public function setRight(absences_Right $right)
1817 10
	{
1818 10
		$this->right = $right;
1819
	}
1820
	
1821 10
	
1822
	public function executeQuery()
1823 10
	{
1824 10
		if(is_null($this->_oResult))
1825 10
		{
1826
			global $babDB;
1827
			$req = "SELECT
1828
1829
				ur.* 
1830
				
1831 10
			FROM
1832 10
				".ABSENCES_USERS_RIGHTS_TBL." ur 
1833 10
			WHERE ur.id_right=".$babDB->quote($this->right->id)."
1834
			";
1835 10
			
1836 10
			if (isset($this->modified_quantity))
1837 10
			{
1838 10
				$req .= " AND ur.quantity<>''";
1839
			}
1840
	
1841 10
	
1842 10
			$this->setMySqlResult($this->getDataBaseAdapter()->db_query($req));
1843 10
		}
1844
	}
1845
	
1846 8
	
1847
	public function getObject($data)
1848 8
	{
1849 8
		$agentRight = absences_AgentRight::getById($data['id']);
1850 8
		$agentRight->setRow($data);
1851
		$agentRight->setRight($this->right);
1852 8
		
1853
		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.hide_empty        right__hide_empty,
1996
				r.no_distribution	right__no_distribution,
1997
				r.id_rgroup			right__id_rgroup,
1998
				r.earlier					right__earlier,
1999
	 			r.earlier_begin_valid		right__earlier_begin_valid,
2000
	  			r.earlier_end_valid			right__earlier_end_valid,
2001
	  			r.later						right__later,
2002
	  			r.later_begin_valid			right__later_begin_valid,
2003
	  			r.later_end_valid			right__later_end_valid,
2004
	  			r.sortkey					right__sortkey, 
2005
	  			r.require_approval			right__require_approval,
2006
				r.delay_before				right__delay_before, 
2007
				
2008
				
2009
				rules.id					rule__id,
2010
				rules.id_right				rule__id_right,
2011
				rules.validoverlap			rule__validoverlap,
2012
				rules.trigger_nbdays_min 	rule__trigger_nbdays_min,
2013
				rules.trigger_nbdays_max	rule__trigger_nbdays_max,
2014
				rules.trigger_type			rule__trigger_type,
2015
				rules.trigger_p1_begin		rule__trigger_p1_begin,
2016
				rules.trigger_p1_end		rule__trigger_p1_end,
2017
				rules.trigger_p2_begin		rule__trigger_p2_begin,
2018
				rules.trigger_p2_end		rule__trigger_p2_end,
2019
				rules.trigger_overlap		rule__trigger_overlap,
2020
				
2021
				rg.id 				rgroup__id,
2022
				rg.name 			rgroup__name,
2023
				rg.quantity_unit	rgroup__quantity_unit,
2024
				rg.recover			rgroup__recover,
2025
				rg.sortkey			rgroup__sortkey,
2026
				
2027
				ur.id				agentright__id,
2028
				ur.id_user			agentright__id_user,
2029
				ur.id_right			agentright__id_right,
2030
				ur.quantity 		agentright__quantity,
2031
				ur.date_begin_valid	agentright__date_begin_valid,
2032
				ur.date_end_valid	agentright__date_end_valid, 
2033
				
2034
				ur.inperiod_start	agentright__inperiod_start,
2035
				ur.inperiod_end		agentright__inperiod_end,
2036
				ur.validoverlap		agentright__validoverlap,
2037
				ur.saving_begin		agentright__saving_begin,
2038
				ur.saving_end		agentright__saving_end   
2039
				
2040
				
2041
			FROM
2042
				".ABSENCES_TYPES_TBL." t,
2043
				".ABSENCES_USERS_RIGHTS_TBL." ur,
2044
				".ABSENCES_RIGHTS_TBL." r
2045
				LEFT JOIN
2046
					".ABSENCES_RIGHTS_RULES_TBL." rules ON rules.id_right = r.id
2047
				LEFT JOIN
2048
					".ABSENCES_RGROUPS_TBL." rg ON rg.id = r.id_rgroup
2049
			WHERE 
2050
				ur.id_user=".$babDB->quote($this->agent->getIdUser())." AND ur.id_right=r.id AND r.id_type=t.id 	
2051
			";
2052
			
2053
			/*
2054
			$query .= "
2055
				AND t.id = c.id_type
2056
				AND c.id_coll=p.id_coll
2057
				AND p.id_user=".$babDB->quote($this->agent->getIdUser())."
2058
			";
2059
			*/
2060
			
2061
			if( !$this->show_inactive )
2062
			{
2063
				$req .= " AND r.active='Y'";
2064
			}
2065
			
2066
			if (isset($this->kind))
2067
			{
2068
				$req .= " AND r.kind=".$babDB->quote($this->kind);
2069
			}
2070
			
2071
			if (isset($this->use_in_cet))
2072
			{
2073
				$req .= " AND r.use_in_cet=".$babDB->quote((int) $this->use_in_cet);
2074
			}
2075
			
2076
			if (isset($this->quantity_unit))
2077
			{
2078
				$req .= " AND r.quantity_unit=".$babDB->quote($this->quantity_unit);
2079
			}
2080
			
2081
			$req .= " 
2082
			
2083
				GROUP BY r.id 
2084
				ORDER BY r.sortkey, r.description";
2085
			
2086
			
2087
			$this->setMySqlResult($this->getDataBaseAdapter()->db_query($req));
2088
		}
2089
	}
2090
	
2091
	
2092
	
2093
	/**
2094
	 * (non-PHPdoc)
2095
	 * @see absences_AgentRightIterator::getObject()
2096
	 */
2097
	public function getObject($data)
2098
	{
2099
		$agentRight = parent::getObject($data);
2100
		
2101
		
2102
		$right = $agentRight->getRight();
2103
2104
		if (!$agentRight->isAccessibleByValidityPeriod() || !$right->isAccessibleIfFixed())
2105
		{
2106
			return null;
2107
		}
2108
		
2109
		if (!$agentRight->isAcessibleByDirectoryEntry())
2110
		{
2111
			return null;
2112
		}
2113
		
2114
		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)
2115
			if (!$agentRight->isAccessibleOnPeriod($this->begin, $this->end))
2116
			{
2117
				return null;
2118
			}
2119
			
2120
			if (!$agentRight->isAccessibleOnDelay($this->begin))
2121
			{
2122
				return null;
2123
			}
2124
		}
2125
		
2126
		$rightRule = $agentRight->getRight()->getRightRule();
2127
	
2128
		// Attribution du droit en fonction des jours demandes et valides
2129
		if ($rightRule->getRow() && !$rightRule->isAccessibleAccordingToRequests($this->agent->getIdUser()) ) {
2130
			return null;
2131
		}
2132
		
2133
2134
		if ($right->hide_empty && $agentRight->getAvailableQuantity() <= 0) {
2135
		    return null;
2136
		}
2137
		
2138
		
2139
		return $agentRight;
2140
		
2141
	}
2142
	
2143
	
2144
	
2145
	/**
2146
	 * 
2147
	 *
2148
	 * @return mixed
2149
	 */
2150
	public function next()
2151
	{
2152
		$this->executeQuery();
2153
		
2154
		do {
2155
			$agentRight = false;
2156
			if ($aDatas = $this->getDataBaseAdapter()->db_fetch_assoc($this->_oResult))
2157
			{
2158
				$agentRight = $this->getObject($aDatas);
2159
			}
2160
		} while (!isset($agentRight));
2161
	
2162
		if(false !== $agentRight)
2163
		{
2164
			$this->_iKey++;
2165
			$this->_oObject = $agentRight;
2166
		}
2167
		else
2168
		{
2169
			$this->_oObject = null;
2170
			$this->_iKey = self::EOF;
2171
		}
2172
	
2173
		return $this->_oObject;
2174
	}
2175
	
2176
	
2177
	
2178
	/**
2179
	 * (non-PHPdoc)
2180
	 * @see BAB_MySqlResultIterator::count()
2181
	 */
2182
	public function count()
2183
	{
2184
		$i = 0;
2185
		foreach($this as $agentRight)
2186
		{
2187
			$i++;
2188
		}
2189
		
2190
		$this->rewind();
2191
		return $i;
2192
	}
2193
}
2194
2195
2196
2197
2198
2199
/**
2200
 * iterateur des droits d'un agent, vue gestionnaire
2201
 * tout les droits associes a l'agent, ordonnes par annees, puis alphabetiquement
2202
 */
2203
class absences_AgentRightManagerIterator extends absences_AgentRightIterator
2204
{
2205
	
2206
	/**
2207
	 * Filter rights by year
2208
	 * @var int
2209
	 */
2210
	public $year = null;
2211
	
2212
2213
	public function executeQuery()
2214
	{
2215
		if(is_null($this->_oResult))
2216
		{
2217
			global $babDB;
2218
	
2219
			$query = '
2220
			SELECT
2221
			u.id				agentright__id,
2222
			u.id_user			agentright__id_user,
2223
			u.id_right			agentright__id_right,
2224
			u.quantity			agentright__quantity,
2225
			u.date_begin_valid	agentright__date_begin_valid,
2226
			u.date_end_valid	agentright__date_end_valid, 
2227
			u.inperiod_start    agentright__inperiod_start,
2228
			u.inperiod_end      agentright__inperiod_end,
2229
			u.validoverlap      agentright__validoverlap,
2230
			u.saving_begin      agentright__saving_begin,
2231
			u.saving_end        agentright__saving_end,
2232
	
2233
			r.id				right__id,
2234
			r.kind				right__kind,
2235
			r.id_creditor		right__id_creditor,
2236
			r.createdOn  		right__createdOn,
2237
			r.date_entry		right__date_entry,
2238
			r.date_begin 		right__date_begin,
2239
			r.date_end 			right__date_end,
2240
			r.quantity			right__quantity,
2241
			r.quantity_unit 	right__quantity_unit,
2242
			r.id_type			right__id_type,
2243
			r.description		right__description,
2244
			r.active			right__active,
2245
			r.cbalance			right__cbalance,
2246
			r.date_begin_valid	right__date_begin_valid,
2247
			r.date_end_valid	right__date_end_valid,
2248
			r.date_end_fixed	right__date_end_fixed,
2249
			r.date_begin_fixed	right__date_begin_fixed,
2250
			r.hide_empty    	right__hide_empty,
2251
			r.no_distribution	right__no_distribution,
2252
			r.id_rgroup			right__id_rgroup,
2253
			r.earlier			right__earlier,
2254
 			r.earlier_begin_valid	right__earlier_begin_valid,
2255
  			r.earlier_end_valid		right__earlier_end_valid,
2256
  			r.later					right__later,
2257
  			r.later_begin_valid		right__later_begin_valid,
2258
  			r.later_end_valid		right__later_end_valid,
2259
  			r.id_report_type		right__id_report_type,
2260
  			r.date_end_report		right__date_end_report,
2261
  			r.description_report	right__description_report,
2262
  			r.id_reported_from		right__id_reported_from,
2263
  			r.quantity_alert_days	right__quantity_alert_days,
2264
  			r.quantity_alert_types	right__quantity_alert_types,
2265
  			r.quantity_alert_begin	right__quantity_alert_begin,
2266
  			r.quantity_alert_end	right__quantity_alert_end,
2267
  			r.dynconf_types			right__dynconf_types,
2268
  			r.dynconf_begin			right__dynconf_begin,
2269
  			r.dynconf_end			right__dynconf_end,
2270
  			r.require_approval		right__require_approval,
2271
			r.delay_before			right__delay_before, 
2272
			r.quantity_inc_month    right__quantity_inc_month,
2273
			r.quantity_inc_last     right__quantity_inc_last,
2274
			r.quantity_inc_max      right__quantity_inc_max, 
2275
  			
2276
	
2277
			t.id				type__id,
2278
			t.name 				type__name,
2279
			t.description		type__description,
2280
			t.quantity			type__quantity,
2281
			t.maxdays			type__maxdays,
2282
			t.mindays			type__mindays,
2283
			t.defaultdays		type__defaultdays,
2284
			t.color				type__color,
2285
			t.cbalance			type__cbalance,
2286
	
2287
			rg.id				rgroup__id,
2288
			rg.name 			rgroup__name,
2289
	
2290
			IFNULL(rg.name, r.description) label,
2291
	
2292
	
2293
			YEAR(r.date_begin) year
2294
			FROM
2295
				absences_users_rights u,
2296
				absences_rights r
2297
					LEFT JOIN absences_rgroup rg ON rg.id = r.id_rgroup,
2298
			absences_types t
2299
	
2300
			WHERE 
2301
				id_user='.$babDB->quote($this->agent->getIdUser()).'
2302
				AND r.id = u.id_right
2303
				AND t.id = r.id_type ';
2304
			
2305
			if (isset($this->year)) {
2306
			    $query .= 'AND YEAR(r.date_begin)='.$babDB->quote($this->year).' ';
2307
			}
2308
			
2309
			$query .= '
2310
			ORDER BY year DESC, label ASC';
2311
	
2312
	
2313
			$this->setMySqlResult($this->getDataBaseAdapter()->db_query($query));
2314
		}
2315
	}
2316
	
2317
}
2318