Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like absences_Entry often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use absences_Entry, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 52 | class absences_Entry extends absences_Request |
||
| 53 | { |
||
| 54 | |||
| 55 | const CREATION_USER = 0; |
||
| 56 | const CREATION_FIXED = 1; |
||
| 57 | |||
| 58 | |||
| 59 | |||
| 60 | |||
| 61 | /** |
||
| 62 | * Memory for saved or unsaved elements of a vacation request |
||
| 63 | * @var array |
||
| 64 | */ |
||
| 65 | private $elements = array(); |
||
| 66 | |||
| 67 | |||
| 68 | /** |
||
| 69 | * Memory for working periods of a vacation request |
||
| 70 | * they are the working periods saved with the entry at the creation of the request |
||
| 71 | * the periods will remain event after a workschedule modification for the user |
||
| 72 | * @var array |
||
| 73 | */ |
||
| 74 | private $plannedPeriods = array(); |
||
| 75 | |||
| 76 | /** |
||
| 77 | * @var float |
||
| 78 | */ |
||
| 79 | private $duration_days = null; |
||
| 80 | |||
| 81 | /** |
||
| 82 | * @var float |
||
| 83 | */ |
||
| 84 | private $duration_hours = null; |
||
| 85 | |||
| 86 | |||
| 87 | /** |
||
| 88 | * Cache for actual working periods from calendar |
||
| 89 | * @var bab_CalendarPeriod[] |
||
| 90 | */ |
||
| 91 | private $working_periods; |
||
| 92 | |||
| 93 | |||
| 94 | /** |
||
| 95 | * cache for total quantity |
||
| 96 | * @var float |
||
| 97 | */ |
||
| 98 | private $total_days = null; |
||
| 99 | |||
| 100 | /** |
||
| 101 | * cache for total quantity |
||
| 102 | * @var float |
||
| 103 | */ |
||
| 104 | private $total_hours = null; |
||
| 105 | |||
| 106 | |||
| 107 | /** |
||
| 108 | * cache for total quantity per type |
||
| 109 | * @var array |
||
| 110 | */ |
||
| 111 | private $total_type_days = null; |
||
| 112 | |||
| 113 | /** |
||
| 114 | * cache for total quantity per type |
||
| 115 | * @var float |
||
| 116 | */ |
||
| 117 | private $total_type_hours = null; |
||
| 118 | |||
| 119 | |||
| 120 | |||
| 121 | /** |
||
| 122 | * @var array |
||
| 123 | */ |
||
| 124 | private $workingPeriodIndex = null; |
||
| 125 | |||
| 126 | |||
| 127 | /** |
||
| 128 | * @see absences_EntryPeriod::getDurationDays |
||
| 129 | * @var array |
||
| 130 | */ |
||
| 131 | public $_getDurationDays_halfDays = array(); |
||
| 132 | |||
| 133 | |||
| 134 | |||
| 135 | /** |
||
| 136 | * @return absences_Entry |
||
| 137 | */ |
||
| 138 | public static function getById($id) |
||
| 139 | { |
||
| 140 | $request = new absences_Entry(); |
||
| 141 | $request->id = $id; |
||
| 142 | |||
| 143 | return $request; |
||
| 144 | } |
||
| 145 | |||
| 146 | |||
| 147 | /** |
||
| 148 | * (non-PHPdoc) |
||
| 149 | * @see absences_Record::getRow() |
||
| 150 | */ |
||
| 151 | 37 | public function getRow() |
|
| 152 | { |
||
| 153 | 37 | if (null === $this->row) |
|
| 154 | 37 | { |
|
| 155 | 11 | if (!isset($this->id)) |
|
| 156 | 11 | { |
|
| 157 | throw new Exception('Failed to load entry, missing entry id'); |
||
| 158 | } |
||
| 159 | |||
| 160 | 11 | global $babDB; |
|
| 161 | 11 | $res = $babDB->db_query('SELECT * FROM absences_entries WHERE id='.$babDB->quote($this->id)); |
|
| 162 | 11 | $this->setRow($babDB->db_fetch_assoc($res)); |
|
| 163 | 11 | } |
|
| 164 | |||
| 165 | 37 | return $this->row; |
|
| 166 | } |
||
| 167 | |||
| 168 | |||
| 169 | /** |
||
| 170 | * (non-PHPdoc) |
||
| 171 | * @see absences_Request::getRequestType() |
||
| 172 | * |
||
| 173 | * @return string |
||
| 174 | */ |
||
| 175 | public function getRequestType() |
||
| 176 | { |
||
| 177 | switch($this->creation_type) |
||
| 178 | { |
||
| 179 | case '1': |
||
| 180 | return absences_translate('Fixed vacation'); |
||
| 181 | |||
| 182 | default: |
||
| 183 | case '0': |
||
|
|
|||
| 184 | return absences_translate('Requested vacation'); |
||
| 185 | } |
||
| 186 | |||
| 187 | |||
| 188 | |||
| 189 | } |
||
| 190 | |||
| 191 | |||
| 192 | |||
| 193 | |||
| 194 | public function getApprobationId() |
||
| 195 | { |
||
| 196 | if ($agent = $this->getAgent()) |
||
| 197 | { |
||
| 198 | return $agent->getApprobationId(); |
||
| 199 | } |
||
| 200 | |||
| 201 | return null; |
||
| 202 | } |
||
| 203 | |||
| 204 | |||
| 205 | |||
| 206 | |||
| 207 | |||
| 208 | /** |
||
| 209 | * Get elements stored in database |
||
| 210 | * @return absences_EntryElemIterator |
||
| 211 | */ |
||
| 212 | public function getElementsIterator() |
||
| 213 | { |
||
| 214 | $I = new absences_EntryElemIterator; |
||
| 215 | $I->entry = $this; |
||
| 216 | |||
| 217 | return $I; |
||
| 218 | } |
||
| 219 | |||
| 220 | |||
| 221 | 11 | public function getPlannedPeriodsIterator() |
|
| 222 | { |
||
| 223 | 11 | $I = new absences_EntryPeriodIterator; |
|
| 224 | 11 | $I->entry = $this; |
|
| 225 | |||
| 226 | 11 | return $I; |
|
| 227 | } |
||
| 228 | |||
| 229 | |||
| 230 | |||
| 231 | /** |
||
| 232 | * Get entries within the same folder |
||
| 233 | * @return absences_EntryIterator |
||
| 234 | */ |
||
| 235 | View Code Duplication | public function getFolderEntriesIterator() |
|
| 236 | { |
||
| 237 | if (!$this->folder) |
||
| 238 | { |
||
| 239 | return null; |
||
| 240 | } |
||
| 241 | |||
| 242 | $I = new absences_EntryIterator; |
||
| 243 | $I->folder = $this->folder; |
||
| 244 | |||
| 245 | return $I; |
||
| 246 | } |
||
| 247 | |||
| 248 | |||
| 249 | |||
| 250 | |||
| 251 | |||
| 252 | |||
| 253 | |||
| 254 | /** |
||
| 255 | * |
||
| 256 | * @param string $message Generated message |
||
| 257 | * @param string $comment Author comment |
||
| 258 | */ |
||
| 259 | public function addElementsMovements($message, $comment = '') |
||
| 260 | { |
||
| 261 | foreach($this->elements as $elem) |
||
| 262 | { |
||
| 263 | /*@var $elem absences_EntryElem */ |
||
| 264 | $elem->addMovement($message, $comment); |
||
| 265 | } |
||
| 266 | } |
||
| 267 | |||
| 268 | |||
| 269 | |||
| 270 | |||
| 271 | /** |
||
| 272 | * Load elements from database |
||
| 273 | * @throws Exception |
||
| 274 | */ |
||
| 275 | public function loadElements() |
||
| 276 | { |
||
| 277 | if (!isset($this->id)) |
||
| 278 | { |
||
| 279 | throw new Exception('Failed to load entry elements, id missing'); |
||
| 280 | } |
||
| 281 | |||
| 282 | $this->elements = array(); |
||
| 283 | |||
| 284 | foreach($this->getElementsIterator() as $entryElem) |
||
| 285 | { |
||
| 286 | /*@var $entryElem absences_EntryElem */ |
||
| 287 | $this->addElement($entryElem); |
||
| 288 | } |
||
| 289 | } |
||
| 290 | |||
| 291 | /** |
||
| 292 | * Get the loaded elements |
||
| 293 | * @return array |
||
| 294 | */ |
||
| 295 | 14 | public function getElements() |
|
| 299 | |||
| 300 | /** |
||
| 301 | * Get element by right from the loaded elements |
||
| 302 | * @param int|absences_Right $right |
||
| 303 | * @return absences_EntryElem |
||
| 304 | */ |
||
| 305 | 19 | public function getElement($right) |
|
| 306 | { |
||
| 307 | 19 | $id_right = $right; |
|
| 308 | 19 | if ($right instanceof absences_Right) { |
|
| 309 | $id_right = $right->id; |
||
| 310 | } |
||
| 311 | |||
| 312 | |||
| 313 | 19 | if (empty($this->elements)) { |
|
| 314 | // not loaded |
||
| 315 | |||
| 316 | 5 | require_once dirname(__FILE__).'/entry_elem.class.php'; |
|
| 317 | |||
| 318 | 5 | global $babDB; |
|
| 319 | |||
| 320 | 5 | $res = $babDB->db_query('SELECT * |
|
| 321 | FROM absences_entries_elem |
||
| 322 | WHERE |
||
| 323 | 5 | id_entry='.$babDB->quote($this->id).' |
|
| 324 | 5 | AND id_right='.$babDB->quote($id_right)); |
|
| 325 | |||
| 326 | 5 | $row = $babDB->db_fetch_assoc($res); |
|
| 327 | |||
| 328 | 5 | if (!$row) { |
|
| 329 | return null; |
||
| 330 | } |
||
| 331 | |||
| 332 | 5 | $elem = new absences_EntryElem(); |
|
| 333 | 5 | $elem->setRow($row); |
|
| 334 | |||
| 335 | 5 | if ($right instanceof absences_Right) { |
|
| 336 | $elem->setRight($right); |
||
| 337 | } |
||
| 338 | |||
| 339 | 5 | return $elem; |
|
| 340 | } |
||
| 341 | |||
| 342 | |||
| 343 | // already loaded |
||
| 344 | |||
| 345 | 14 | foreach($this->elements as $element) { |
|
| 346 | 14 | if ($element->id_right == $id_right) { |
|
| 347 | 14 | return $element; |
|
| 348 | } |
||
| 349 | 11 | } |
|
| 350 | |||
| 351 | return null; |
||
| 352 | } |
||
| 353 | |||
| 354 | |||
| 355 | |||
| 356 | /** |
||
| 357 | * Add a planned period |
||
| 358 | * @param absences_EntryPeriod $plannedPeriod |
||
| 359 | */ |
||
| 360 | public function addPeriod(absences_EntryPeriod $plannedPeriod) |
||
| 364 | |||
| 365 | |||
| 366 | |||
| 367 | |||
| 368 | /** |
||
| 369 | * Load the planned working periods from database |
||
| 370 | * @throws Exception |
||
| 371 | */ |
||
| 372 | 12 | public function loadPlannedPeriods() |
|
| 373 | { |
||
| 374 | 12 | if (!isset($this->id)) |
|
| 375 | 12 | { |
|
| 376 | throw new Exception('Failed to load entry periods, id missing'); |
||
| 377 | } |
||
| 378 | |||
| 379 | 11 | $this->plannedPeriods = array(); |
|
| 380 | |||
| 381 | 11 | $res = $this->getPlannedPeriodsIterator(); |
|
| 382 | |||
| 383 | 11 | if (0 === $res->count()) { |
|
| 384 | 11 | return $this->createPlannedPeriods(); |
|
| 385 | } |
||
| 386 | |||
| 387 | foreach($res as $plannedPeriod) |
||
| 388 | { |
||
| 389 | /*@var $plannedPeriod absences_EntryPeriod */ |
||
| 390 | $this->addPeriod($plannedPeriod); |
||
| 391 | } |
||
| 392 | } |
||
| 393 | |||
| 394 | /** |
||
| 395 | * Get the loaded planned working periods |
||
| 396 | * @return absences_EntryPeriod[] |
||
| 397 | */ |
||
| 398 | 13 | public function getPlannedPeriods() |
|
| 402 | |||
| 403 | |||
| 404 | /** |
||
| 405 | * Get planned duration |
||
| 406 | * |
||
| 407 | * @param string $begin Optional limit to use for duration |
||
| 408 | * @param string $end Optional limit to use for duration |
||
| 409 | * |
||
| 410 | * @return float |
||
| 411 | */ |
||
| 412 | 4 | View Code Duplication | public function getPlannedDurationDays($begin = null, $end = null) |
| 413 | { |
||
| 414 | 4 | if (empty($this->plannedPeriods)) { |
|
| 415 | $this->loadPlannedPeriods(); |
||
| 416 | } |
||
| 417 | |||
| 418 | 4 | $total = 0.0; |
|
| 419 | |||
| 420 | 4 | foreach ($this->getPlannedPeriods() as $entryPeriod) { |
|
| 421 | 4 | $total += $entryPeriod->getDurationDays($begin, $end); |
|
| 422 | 4 | } |
|
| 423 | |||
| 424 | |||
| 425 | |||
| 426 | |||
| 427 | |||
| 428 | 4 | return $total; |
|
| 429 | } |
||
| 430 | |||
| 431 | |||
| 432 | /** |
||
| 433 | * Get planned duration |
||
| 434 | * |
||
| 435 | * @param string $begin Optional limit to use for duration |
||
| 436 | * @param string $end Optional limit to use for duration |
||
| 437 | * |
||
| 438 | * @return float |
||
| 439 | */ |
||
| 440 | 3 | View Code Duplication | public function getPlannedDurationHours($begin = null, $end = null) |
| 441 | { |
||
| 442 | 3 | if (empty($this->plannedPeriods)) { |
|
| 443 | $this->loadPlannedPeriods(); |
||
| 444 | } |
||
| 445 | |||
| 446 | 3 | $total = 0.0; |
|
| 447 | |||
| 448 | 3 | foreach ($this->getPlannedPeriods() as $entryPeriod) { |
|
| 449 | 3 | $total += $entryPeriod->getDurationHours($begin, $end); |
|
| 450 | 3 | } |
|
| 451 | |||
| 452 | 3 | return $total; |
|
| 453 | } |
||
| 454 | |||
| 455 | |||
| 456 | 7 | public function loadDefaultValues() |
|
| 457 | { |
||
| 458 | |||
| 459 | 7 | if (!isset($this->createdOn)) { |
|
| 460 | $this->createdOn = date('Y-m-d H:i:s'); |
||
| 461 | } |
||
| 462 | |||
| 463 | 7 | if (!isset($this->date)) { |
|
| 464 | $this->date = date('Y-m-d H:i:s'); |
||
| 465 | } |
||
| 466 | |||
| 467 | 7 | if (!isset($this->comment)) { |
|
| 468 | 7 | $this->comment = ''; |
|
| 469 | 7 | } |
|
| 470 | |||
| 471 | 7 | if (!isset($this->comment2)) { |
|
| 472 | 7 | $this->comment2 = ''; |
|
| 473 | 7 | } |
|
| 474 | |||
| 475 | 7 | if (!isset($this->idfai)) { |
|
| 476 | 7 | $this->idfai = '0'; |
|
| 477 | 7 | } |
|
| 478 | |||
| 479 | 7 | if (!isset($this->status)) { |
|
| 480 | $this->status = 'N'; |
||
| 481 | } |
||
| 482 | |||
| 483 | 7 | if (!isset($this->id_approver)) { |
|
| 484 | 7 | $this->id_approver = '0'; |
|
| 485 | 7 | } |
|
| 486 | |||
| 487 | 7 | if (!isset($this->folder)) { |
|
| 488 | 7 | $this->folder = '0'; |
|
| 489 | 7 | } |
|
| 490 | |||
| 491 | 7 | if (!isset($this->creation_type)) { |
|
| 492 | 7 | $this->creation_type = '0'; |
|
| 493 | 7 | } |
|
| 494 | |||
| 495 | 7 | } |
|
| 496 | |||
| 497 | |||
| 498 | /** |
||
| 499 | * Save entry to database |
||
| 500 | * without validity checking |
||
| 501 | * |
||
| 502 | * @return bool |
||
| 503 | */ |
||
| 504 | 7 | public function save() |
|
| 505 | { |
||
| 506 | // save entry |
||
| 507 | |||
| 508 | 7 | global $babDB; |
|
| 509 | |||
| 510 | 7 | $this->loadDefaultValues(); |
|
| 511 | |||
| 512 | 7 | if (isset($this->id)) |
|
| 513 | 7 | { |
|
| 514 | $req = " |
||
| 515 | UPDATE absences_entries |
||
| 516 | SET |
||
| 517 | 2 | `date` =".$babDB->quote($this->date).", |
|
| 518 | 2 | date_begin =".$babDB->quote($this->date_begin).", |
|
| 519 | 2 | date_end =".$babDB->quote($this->date_end).", |
|
| 520 | 2 | comment =".$babDB->quote($this->comment).", |
|
| 521 | 2 | idfai =".$babDB->quote($this->idfai).", |
|
| 522 | 2 | status =".$babDB->quote($this->status).", |
|
| 523 | 2 | comment2 =".$babDB->quote($this->comment2).", |
|
| 524 | 2 | id_approver =".$babDB->quote($this->id_approver).", |
|
| 525 | 2 | folder =".$babDB->quote($this->folder).", |
|
| 526 | 2 | creation_type =".$babDB->quote($this->creation_type)." |
|
| 527 | 2 | "; |
|
| 528 | |||
| 529 | 2 | if (isset($this->todelete)) |
|
| 530 | 2 | { |
|
| 531 | $req .= ", todelete=".$babDB->quote($this->todelete); |
||
| 532 | } |
||
| 533 | |||
| 534 | 2 | if (isset($this->appr_notified)) |
|
| 535 | 2 | { |
|
| 536 | $req .= ", appr_notified=".$babDB->quote($this->appr_notified); |
||
| 537 | } |
||
| 538 | |||
| 539 | |||
| 540 | $req .= " WHERE |
||
| 541 | 2 | id=".$babDB->quote($this->id)." "; |
|
| 542 | |||
| 543 | 2 | $babDB->db_query($req); |
|
| 544 | |||
| 545 | |||
| 546 | 2 | View Code Duplication | } else { |
| 547 | |||
| 548 | 7 | $babDB->db_query(" |
|
| 549 | INSERT INTO absences_entries |
||
| 550 | ( |
||
| 551 | id_user, |
||
| 552 | date_begin, |
||
| 553 | date_end, |
||
| 554 | comment, |
||
| 555 | `createdOn`, |
||
| 556 | `date`, |
||
| 557 | idfai, |
||
| 558 | status, |
||
| 559 | comment2, |
||
| 560 | id_approver, |
||
| 561 | folder, |
||
| 562 | creation_type |
||
| 563 | ) |
||
| 564 | VALUES |
||
| 565 | ( |
||
| 566 | 7 | ".$babDB->quote($this->id_user).", |
|
| 567 | 7 | ".$babDB->quote($this->date_begin).", |
|
| 568 | 7 | ".$babDB->quote($this->date_end).", |
|
| 569 | 7 | ".$babDB->quote($this->comment).", |
|
| 570 | 7 | ".$babDB->quote($this->createdOn).", |
|
| 571 | 7 | ".$babDB->quote($this->date).", |
|
| 572 | 7 | ".$babDB->quote($this->idfai).", |
|
| 573 | 7 | ".$babDB->quote($this->status).", |
|
| 574 | 7 | ".$babDB->quote($this->comment2).", |
|
| 575 | 7 | ".$babDB->quote($this->id_approver).", |
|
| 576 | 7 | ".$babDB->quote($this->folder).", |
|
| 577 | 7 | ".$babDB->quote($this->creation_type)." |
|
| 578 | ) |
||
| 579 | 7 | "); |
|
| 580 | |||
| 581 | 7 | $this->id = $babDB->db_insert_id(); |
|
| 582 | } |
||
| 583 | |||
| 584 | |||
| 585 | 7 | } |
|
| 586 | |||
| 587 | |||
| 588 | /** |
||
| 589 | * Sort the loaded element by right order, type name |
||
| 590 | */ |
||
| 591 | 23 | public function sortElements() |
|
| 595 | |||
| 596 | 23 | private static function sortElem(absences_EntryElem $elem1, absences_EntryElem $elem2) |
|
| 597 | { |
||
| 598 | 23 | $right1 = $elem1->getRight(); |
|
| 599 | 23 | $right2 = $elem2->getRight(); |
|
| 600 | |||
| 601 | 23 | if ($right1->sortkey > $right2->sortkey) { |
|
| 602 | 22 | return 1; |
|
| 603 | } |
||
| 604 | |||
| 605 | 2 | if ($right1->sortkey < $right2->sortkey) { |
|
| 606 | 2 | return -1; |
|
| 607 | } |
||
| 608 | |||
| 609 | 1 | $type1 = $right1->getType(); |
|
| 610 | 1 | $type2 = $right2->getType(); |
|
| 611 | |||
| 612 | 1 | return bab_compare(mb_strtolower($type1->name), mb_strtolower($type2->name)); |
|
| 613 | } |
||
| 614 | |||
| 615 | |||
| 616 | /** |
||
| 617 | * Verifier si les dates des elements sont correctement parametres |
||
| 618 | * en cas de modificiation de la quantite, toujours mettre les dates a zero |
||
| 619 | * @return bool |
||
| 620 | */ |
||
| 621 | 29 | public function checkElementsDates() |
|
| 622 | { |
||
| 623 | 29 | foreach($this->elements as $elem) { |
|
| 624 | 29 | if (!isset($elem->date_begin) || '0000-00-00 00:00:00' === $elem->date_begin) { |
|
| 625 | 29 | return false; |
|
| 626 | } |
||
| 627 | |||
| 628 | 10 | if (!isset($elem->date_end) || '0000-00-00 00:00:00' === $elem->date_end) { |
|
| 629 | return false; |
||
| 630 | } |
||
| 631 | 10 | } |
|
| 632 | |||
| 633 | 10 | return true; |
|
| 634 | } |
||
| 635 | |||
| 636 | |||
| 637 | /** |
||
| 638 | * Add dates to loaded elements using the user calendar |
||
| 639 | */ |
||
| 640 | 29 | public function setElementsDates() |
|
| 641 | { |
||
| 642 | 29 | include_once $GLOBALS['babInstallPath']."utilit/dateTime.php"; |
|
| 643 | |||
| 644 | 29 | if (0 === count($this->elements)) { |
|
| 645 | throw new absences_EntryException('No elements to set dates on, id_entry='.$this->id.', owner='.$this->getUserName()); |
||
| 646 | } |
||
| 647 | |||
| 648 | 29 | if ($this->checkElementsDates()) { |
|
| 649 | // dates allready set |
||
| 650 | // calling getFutureDate twice does not work |
||
| 651 | 10 | return; |
|
| 652 | } |
||
| 653 | |||
| 654 | 29 | if (1 === count($this->elements)) { |
|
| 655 | 6 | $element = reset($this->elements); |
|
| 656 | /*@var $element absences_EntryElem */ |
||
| 657 | 6 | $element->date_begin = $this->date_begin; |
|
| 658 | 6 | $element->date_end = $this->date_end; |
|
| 659 | 6 | return; |
|
| 660 | } |
||
| 661 | |||
| 662 | 23 | $this->sortElements(); |
|
| 663 | |||
| 664 | 23 | $loop = BAB_DateTime::fromIsoDateTime($this->date_begin); |
|
| 665 | |||
| 666 | 23 | foreach($this->elements as $element) { |
|
| 667 | /*@var $element absences_EntryElem */ |
||
| 668 | 23 | $element->date_begin = $loop->getIsoDateTime(); |
|
| 669 | |||
| 670 | 23 | $loop = $this->getFutureDate($loop, (float) $element->quantity, $element->getRight()->quantity_unit); |
|
| 671 | 23 | $element->date_end = $loop->getIsoDateTime(); |
|
| 672 | |||
| 673 | 23 | if ($element->date_end > $this->date_end) { |
|
| 674 | 2 | $element->date_end = $this->date_end; |
|
| 675 | 2 | } |
|
| 676 | |||
| 677 | 23 | $loop = $this->getNextValidDate($loop); |
|
| 678 | 23 | } |
|
| 679 | |||
| 680 | // round the last half day to the request period end |
||
| 681 | 23 | if ($this->getElementEndGap() <= 3600) { |
|
| 682 | 21 | $this->elements[count($this->elements)-1]->date_end = $this->date_end; |
|
| 683 | 21 | } |
|
| 684 | 23 | } |
|
| 685 | |||
| 686 | /** |
||
| 687 | * Get the gap beetween the last element end date and the period end date |
||
| 688 | * @return int |
||
| 689 | */ |
||
| 690 | 23 | protected function getElementEndGap() |
|
| 691 | { |
||
| 692 | 23 | $computedLastDate = bab_mktime($this->elements[count($this->elements)-1]->date_end); |
|
| 693 | 23 | $periodEnd = bab_mktime($this->date_end); |
|
| 694 | |||
| 695 | 23 | if ($periodEnd > $computedLastDate) { |
|
| 696 | 3 | return ($periodEnd - $computedLastDate); |
|
| 697 | } |
||
| 698 | |||
| 699 | 20 | if ($computedLastDate > $periodEnd) { |
|
| 700 | return ($computedLastDate - $periodEnd); |
||
| 701 | } |
||
| 702 | |||
| 703 | 20 | return 0; |
|
| 704 | } |
||
| 705 | |||
| 706 | |||
| 707 | /** |
||
| 708 | * set the date to the next valid date |
||
| 709 | * @param BAB_DateTime $date |
||
| 710 | * @return BAB_DateTime |
||
| 711 | */ |
||
| 712 | 23 | protected function getNextValidDate(BAB_DateTime $date) |
|
| 713 | { |
||
| 714 | 23 | $moment = $date->getTimeStamp(); |
|
| 715 | |||
| 716 | 23 | foreach ($this->getWorkingPeriods() as $period) { |
|
| 717 | |||
| 718 | 23 | if ($moment >= $period->ts_end) { |
|
| 719 | 23 | continue; |
|
| 720 | } |
||
| 721 | |||
| 722 | // if the future date (end date of the element) is in a worked period |
||
| 723 | // the future date is valid as a next date |
||
| 724 | 23 | if ($moment < $period->ts_end && $moment > $period->ts_begin) { |
|
| 725 | 10 | return $date; |
|
| 726 | } |
||
| 727 | |||
| 728 | |||
| 729 | 13 | return BAB_DateTime::fromTimeStamp($period->ts_begin); |
|
| 730 | 21 | } |
|
| 731 | |||
| 732 | |||
| 733 | 21 | return $date; |
|
| 734 | } |
||
| 735 | |||
| 736 | |||
| 737 | |||
| 738 | /** |
||
| 739 | * Add quantity to startdate only on working periods |
||
| 740 | * |
||
| 741 | * @param BAB_DateTime $startdate |
||
| 742 | * @param float $quantity |
||
| 743 | * @param string $quantity_unit D|H |
||
| 744 | * |
||
| 745 | * @return BAB_DateTime |
||
| 746 | */ |
||
| 747 | 23 | protected function getFutureDate(BAB_DateTime $startdate, $quantity, $quantity_unit) |
|
| 748 | { |
||
| 749 | 23 | if ('H' === $quantity_unit) { |
|
| 750 | 4 | return $this->getFutureDate_Hours($startdate, $quantity); |
|
| 751 | } |
||
| 752 | |||
| 753 | 20 | return $this->getFutureDate_Days($startdate, $quantity); |
|
| 754 | } |
||
| 755 | |||
| 756 | |||
| 757 | /** |
||
| 758 | * Split working periods |
||
| 759 | * @return array |
||
| 760 | */ |
||
| 761 | 18 | protected function getWorkingPeriodsFromDate(BAB_DateTime $startdate) |
|
| 762 | { |
||
| 763 | 18 | $periods = array(); |
|
| 764 | 18 | $start = $startdate->getTimeStamp(); |
|
| 765 | |||
| 766 | 18 | foreach ($this->getWorkingPeriods() as $period) { |
|
| 767 | |||
| 768 | 18 | if ($start >= $period->ts_end) { |
|
| 769 | // continue to the next worked period |
||
| 770 | 15 | continue; |
|
| 771 | } |
||
| 772 | |||
| 773 | 18 | if ($start > $period->ts_begin && $start < $period->ts_end) { |
|
| 774 | 10 | $period->setBeginDate($startdate); |
|
| 775 | 10 | $periods[] = $period; |
|
| 776 | 10 | continue; |
|
| 777 | } |
||
| 778 | |||
| 779 | 18 | $periods[] = $period; |
|
| 780 | 18 | } |
|
| 781 | |||
| 782 | 18 | return $periods; |
|
| 783 | } |
||
| 784 | |||
| 785 | |||
| 786 | |||
| 787 | /** |
||
| 788 | * Add quantity to startdate only on working periods |
||
| 789 | * |
||
| 790 | * @param BAB_DateTime $startdate |
||
| 791 | * @param float $seconds_to_add |
||
| 792 | * |
||
| 793 | * @return BAB_DateTime |
||
| 794 | */ |
||
| 795 | 18 | protected function getFutureDate_Seconds(BAB_DateTime $startdate, $seconds_to_add) |
|
| 796 | { |
||
| 797 | 18 | $worked_total = 0; //seconds |
|
| 798 | |||
| 799 | |||
| 800 | 18 | foreach ($this->getWorkingPeriodsFromDate($startdate) as $period) { |
|
| 801 | |||
| 802 | 18 | $add_in_period = ($seconds_to_add - $worked_total); |
|
| 803 | 18 | $worked_total += $period->getDuration(); |
|
| 804 | |||
| 805 | 18 | if ((int) $worked_total === (int) $seconds_to_add) { |
|
| 806 | // la duree de la periode de travail est egale a duree demandee |
||
| 807 | // en tenant compte des periodes de travail precedentes |
||
| 808 | |||
| 809 | 17 | return BAB_DateTime::fromTimeStamp($period->ts_end); |
|
| 810 | } |
||
| 811 | |||
| 812 | |||
| 813 | 15 | if ($worked_total > $seconds_to_add) { |
|
| 814 | // la date future se trouve a l'interieur d'une periode travaillee |
||
| 815 | 10 | $futureDate = $period->ts_begin + $add_in_period; |
|
| 816 | 10 | return BAB_DateTime::fromTimeStamp($futureDate); |
|
| 817 | } |
||
| 818 | |||
| 819 | // continue to the next worked period |
||
| 820 | |||
| 821 | 15 | } |
|
| 822 | |||
| 823 | 2 | return BAB_DateTime::fromIsoDateTime($this->date_end); |
|
| 824 | } |
||
| 825 | |||
| 826 | |||
| 827 | |||
| 828 | |||
| 829 | |||
| 830 | |||
| 831 | /** |
||
| 832 | * Add quantity to startdate only on working periods |
||
| 833 | * |
||
| 834 | * @param BAB_DateTime $startdate |
||
| 835 | * @param float $quantity hours |
||
| 836 | * |
||
| 837 | * @return BAB_DateTime |
||
| 838 | */ |
||
| 839 | 4 | protected function getFutureDate_Hours(BAB_DateTime $startdate, $quantity) |
|
| 840 | { |
||
| 841 | 4 | $seconds_to_add = $quantity * 3600; |
|
| 842 | |||
| 843 | 4 | return $this->getFutureDate_Seconds($startdate, $seconds_to_add); |
|
| 844 | } |
||
| 845 | |||
| 846 | |||
| 847 | /** |
||
| 848 | * periodes travailles, durees et types a partir d'une date |
||
| 849 | * |
||
| 850 | * duration: seconds |
||
| 851 | * type: AMPM | AM | PM |
||
| 852 | * dayend: timestamp |
||
| 853 | * |
||
| 854 | * @param BAB_DateTime $startdate |
||
| 855 | * @return array |
||
| 856 | */ |
||
| 857 | 20 | protected function getWorkingTimeByDay(BAB_DateTime $startdate) |
|
| 858 | { |
||
| 859 | 20 | $start = $startdate->getTimeStamp(); |
|
| 860 | 20 | $days = array(); |
|
| 861 | 20 | foreach ($this->getWorkingPeriods() as $period) { |
|
| 862 | |||
| 863 | |||
| 864 | 20 | if ($start >= $period->ts_end) { |
|
| 865 | 15 | continue; |
|
| 866 | } |
||
| 867 | |||
| 868 | |||
| 869 | |||
| 870 | 20 | $d = date('Y-m-d', $period->ts_begin); |
|
| 871 | |||
| 872 | 20 | if (!isset($days[$d])) { |
|
| 873 | |||
| 874 | 20 | $days[$d] = array( |
|
| 875 | 20 | 'duration' => 0, |
|
| 876 | 20 | 'type' => null, |
|
| 877 | 'dayend' => null |
||
| 878 | 20 | ); |
|
| 879 | 20 | } |
|
| 880 | |||
| 881 | |||
| 882 | 20 | $days[$d]['duration'] += $period->getDuration(); |
|
| 883 | |||
| 884 | 20 | if ($period->ts_end > $days[$d]['dayend']) { |
|
| 885 | 20 | $days[$d]['dayend'] = $period->ts_end; |
|
| 886 | 20 | } |
|
| 887 | |||
| 888 | |||
| 889 | 20 | $type = $this->getPeriodType($period); |
|
| 890 | |||
| 891 | 20 | View Code Duplication | if ('AM' === $days[$d]['type'] && 'PM' === $type) { |
| 892 | 19 | $days[$d]['type'] = 'AMPM'; |
|
| 893 | 19 | } |
|
| 894 | |||
| 895 | 20 | View Code Duplication | if ('PM' === $days[$d]['type'] && 'AM' === $type) { |
| 896 | $days[$d]['type'] = 'AMPM'; |
||
| 897 | } |
||
| 898 | |||
| 899 | 20 | if (!isset($days[$d]['type'])) { |
|
| 900 | 20 | $days[$d]['type'] = $type; |
|
| 901 | 20 | } |
|
| 902 | 20 | } |
|
| 903 | |||
| 904 | |||
| 905 | |||
| 906 | 20 | return $days; |
|
| 907 | } |
||
| 908 | |||
| 909 | |||
| 910 | |||
| 911 | |||
| 912 | |||
| 913 | |||
| 914 | |||
| 915 | |||
| 916 | /** |
||
| 917 | * Add quantity to startdate only on working periods |
||
| 918 | * |
||
| 919 | * @param BAB_DateTime $startdate |
||
| 920 | * @param float $quantity days |
||
| 921 | * |
||
| 922 | * @return BAB_DateTime |
||
| 923 | */ |
||
| 924 | 20 | protected function getFutureDate_Days(BAB_DateTime $startdate, $quantity) |
|
| 925 | { |
||
| 926 | |||
| 927 | 20 | $return = clone $startdate; |
|
| 928 | |||
| 929 | 20 | $morning = clone $startdate; |
|
| 930 | 20 | $morning->setIsoTime('00:00:00'); |
|
| 931 | |||
| 932 | 20 | $days = $this->getWorkingTimeByDay($morning); |
|
| 933 | |||
| 934 | |||
| 935 | 20 | $seconds_to_add = 0; |
|
| 936 | |||
| 937 | |||
| 938 | // traiter les jours entiers |
||
| 939 | |||
| 940 | 20 | $fulldays = $lastfulldays = (float) floor($quantity); |
|
| 941 | 20 | $lastquantity = $quantity; |
|
| 942 | 20 | $lastdays = $days; |
|
| 943 | 20 | $day = key($days); |
|
| 944 | |||
| 945 | 20 | $pos = 0; |
|
| 946 | 20 | if (0 < $fulldays) { |
|
| 947 | |||
| 948 | 15 | foreach($days as $keyday => $arr) { |
|
| 949 | |||
| 950 | 15 | $dayquantity = 'AMPM' === $arr['type'] ? 1.0 : 0.5; |
|
| 951 | |||
| 952 | 15 | $lastfulldays -= $dayquantity; |
|
| 953 | |||
| 954 | 15 | if ($lastfulldays <= 0) { |
|
| 955 | 15 | $lastquantity = $quantity - $fulldays - $lastfulldays; |
|
| 956 | |||
| 957 | 15 | if ($pos > 0) { |
|
| 958 | 9 | $lastdays = array_slice($days, $pos, null, true); |
|
| 959 | |||
| 960 | 9 | } else { |
|
| 961 | 12 | $lastdays = $days; |
|
| 962 | } |
||
| 963 | |||
| 964 | 15 | $day = $keyday; |
|
| 965 | |||
| 966 | 15 | break; |
|
| 967 | } |
||
| 968 | |||
| 969 | 9 | $pos++; |
|
| 970 | 15 | } |
|
| 971 | |||
| 972 | |||
| 973 | |||
| 974 | |||
| 975 | |||
| 976 | 15 | if ($fulldays > 0 && $lastquantity <= 0) { |
|
| 977 | |||
| 978 | |||
| 979 | |||
| 980 | // il ne reste pas de temps a appliquer sur la date |
||
| 981 | // on se place donc a la fin d'une periode travaillee |
||
| 982 | |||
| 983 | 7 | reset($days); |
|
| 984 | 7 | for($i=0; $i<$fulldays-1; $i++) { |
|
| 985 | 6 | next($days); |
|
| 986 | 6 | } |
|
| 987 | |||
| 988 | 7 | $newstart = current($days); |
|
| 989 | 7 | $return = BAB_DateTime::fromTimeStamp($newstart['dayend']); |
|
| 990 | |||
| 991 | //echo $fulldays.' '.$startdate->getIsoDateTime().' -> '.$return->getIsoDateTime()."\n"; |
||
| 992 | |||
| 993 | 7 | } else { |
|
| 994 | |||
| 995 | // il reste du temps a ajouter sur la date |
||
| 996 | // on ajoute juste le nombre de jours complets |
||
| 997 | |||
| 998 | 8 | $return->add($fulldays, BAB_DATETIME_DAY); |
|
| 999 | } |
||
| 1000 | |||
| 1001 | |||
| 1002 | |||
| 1003 | // si la date de debut est supperieur a la date d'ouverture de la premiere periode travaillee |
||
| 1004 | // on considere que la date de debut est sur la prochaine periode travaillee, par exemple commence l'apres-midi |
||
| 1005 | 15 | $start = reset($days); |
|
| 1006 | 15 | $fromstart = $this->getWorkingTimeByDay($startdate); |
|
| 1007 | 15 | $firstday = reset($fromstart); |
|
| 1008 | 15 | $missing_duration = $start['duration'] - $firstday['duration']; |
|
| 1009 | 15 | if ($missing_duration > 0) { |
|
| 1010 | // var_dump($startdate->getIsoDateTime().' '.($missing_duration/3600).'H'); |
||
| 1011 | 3 | $seconds_to_add = $missing_duration; |
|
| 1012 | 3 | } |
|
| 1013 | 15 | } |
|
| 1014 | |||
| 1015 | |||
| 1016 | |||
| 1017 | 20 | if ($seconds_to_add === 0 && ($lastquantity <= 0 || !isset($lastdays))) { |
|
| 1018 | 6 | return $return; |
|
| 1019 | } |
||
| 1020 | |||
| 1021 | 15 | $seconds_to_add += $this->getSecondsToAdd($lastdays, $lastquantity); |
|
| 1022 | |||
| 1023 | |||
| 1024 | 15 | if (0 === $seconds_to_add) { |
|
| 1025 | return $return; |
||
| 1026 | } |
||
| 1027 | |||
| 1028 | |||
| 1029 | 15 | $return = $this->getFutureDate_Seconds($return, $seconds_to_add); |
|
| 1030 | |||
| 1031 | 15 | return $return; |
|
| 1032 | } |
||
| 1033 | |||
| 1034 | |||
| 1035 | /** |
||
| 1036 | * Trouver le nombre de secondes a ajouter a une date pour une quantite |
||
| 1037 | * @param array $lastdays Jours restants sur la periode |
||
| 1038 | * @param float $lastquantity Nombre de jours a ajouter, uniquement les jours incomplets de la fin de periode, les jours complets ont ete traites avant |
||
| 1039 | * |
||
| 1040 | */ |
||
| 1041 | 15 | protected function getSecondsToAdd(Array $lastdays, $lastquantity) |
|
| 1042 | { |
||
| 1043 | 15 | $seconds_to_add = 0; |
|
| 1044 | |||
| 1045 | //var_dump('lastquantity: '.$lastquantity); |
||
| 1046 | |||
| 1047 | // trouver les heures a partir de la quantite restante |
||
| 1048 | |||
| 1049 | 15 | foreach($lastdays as $keyday => $arr) { |
|
| 1050 | |||
| 1051 | 15 | $q = 'AMPM' === $arr['type'] ? 1.0 : 0.5; |
|
| 1052 | |||
| 1053 | 15 | if ($lastquantity > $q) { |
|
| 1054 | $lastquantity -= $q; |
||
| 1055 | continue; |
||
| 1056 | } |
||
| 1057 | |||
| 1058 | //var_dump(($arr['duration']/3600).' '.$lastquantity.' '.$arr['type'].' '.$q); |
||
| 1059 | |||
| 1060 | 15 | if ($lastquantity == $q) { |
|
| 1061 | 1 | $seconds_to_add = $arr['duration']; |
|
| 1062 | 1 | break; |
|
| 1063 | } |
||
| 1064 | |||
| 1065 | 14 | $seconds_to_add = $arr['duration'] * $lastquantity; |
|
| 1066 | 14 | break; |
|
| 1067 | 15 | } |
|
| 1068 | |||
| 1069 | 15 | return $seconds_to_add; |
|
| 1070 | } |
||
| 1071 | |||
| 1072 | |||
| 1073 | |||
| 1074 | /** |
||
| 1075 | * Add quantity to startdate only on working periods |
||
| 1076 | * |
||
| 1077 | * @deprecated probleme avec les periodes a cheval sur 12:00 conbinne aux quantites inferieurs a 1 jour |
||
| 1078 | * |
||
| 1079 | * @param BAB_DateTime $startdate |
||
| 1080 | * @param float $quantity days |
||
| 1081 | * |
||
| 1082 | * @return BAB_DateTime |
||
| 1083 | */ |
||
| 1084 | protected function getFutureDate_Days_Old(BAB_DateTime $startdate, $quantity) |
||
| 1085 | { |
||
| 1086 | |||
| 1087 | $start = $startdate->getTimeStamp(); |
||
| 1088 | |||
| 1089 | $periods_quantity = 0; // days |
||
| 1090 | |||
| 1091 | // get the number of worked hours from startdate to the end of the day |
||
| 1092 | |||
| 1093 | foreach ($this->getWorkingPeriods() as $period) { |
||
| 1094 | |||
| 1095 | if ($start >= $period->ts_end) { |
||
| 1096 | // continue to the next worked period |
||
| 1097 | //var_dump('working period ignored, start='.bab_shortDate($start, true).' >= '.bab_shortDate($period->ts_end, true)); |
||
| 1098 | continue; |
||
| 1099 | } |
||
| 1100 | |||
| 1101 | $periods_quantity += $this->getPeriodQuantity($startdate, $period); |
||
| 1102 | |||
| 1103 | |||
| 1104 | if ($periods_quantity >= $quantity) { |
||
| 1105 | |||
| 1106 | $overhead = $periods_quantity - $quantity; |
||
| 1107 | |||
| 1108 | $futureDate = BAB_DateTime::fromTimeStamp($period->ts_end); |
||
| 1109 | |||
| 1110 | // var_dump($futureDate->getIsoDateTime().' overhead='.$overhead.' ('.$periods_quantity.' - '.$quantity.')'); |
||
| 1111 | |||
| 1112 | if ($overhead) { |
||
| 1113 | $futureDate->less( |
||
| 1114 | 3600 * $this->getDayDurationInHours($futureDate->getIsoDate(), $overhead), |
||
| 1115 | BAB_DATETIME_SECOND |
||
| 1116 | ); |
||
| 1117 | } |
||
| 1118 | |||
| 1119 | if ($futureDate->getIsoDateTime() > $this->date_end) { |
||
| 1120 | $futureDate = BAB_DateTime::fromIsoDateTime($this->date_end); |
||
| 1121 | } |
||
| 1122 | |||
| 1123 | return $futureDate; |
||
| 1124 | } |
||
| 1125 | } |
||
| 1126 | |||
| 1127 | return BAB_DateTime::fromIsoDateTime($this->date_end); |
||
| 1128 | } |
||
| 1129 | |||
| 1130 | |||
| 1131 | /** |
||
| 1132 | * Create the planned periods in the entry boundaries |
||
| 1133 | * from the calendar working periods |
||
| 1134 | */ |
||
| 1135 | 23 | public function createPlannedPeriods() |
|
| 1136 | { |
||
| 1137 | 23 | require_once dirname(__FILE__).'/entry_period.class.php'; |
|
| 1138 | 23 | $this->plannedPeriods = array(); |
|
| 1139 | |||
| 1140 | 23 | foreach ($this->getWorkingPeriods() as $workingPeriod) { |
|
| 1141 | |||
| 1142 | /*@var $workingPeriod bab_CalendarPeriod */ |
||
| 1143 | |||
| 1144 | 23 | $plannedPeriod = new absences_EntryPeriod(); |
|
| 1145 | 23 | $plannedPeriod->setEntry($this); |
|
| 1146 | 23 | $plannedPeriod->date_begin = date('Y-m-d H:i:s', $workingPeriod->ts_begin); |
|
| 1147 | 23 | $plannedPeriod->date_end = date('Y-m-d H:i:s', $workingPeriod->ts_end); |
|
| 1148 | |||
| 1149 | 23 | $this->plannedPeriods[] = $plannedPeriod; |
|
| 1150 | 23 | } |
|
| 1151 | 23 | } |
|
| 1152 | |||
| 1153 | |||
| 1154 | /** |
||
| 1155 | * Get period quantity in days from a datetime |
||
| 1156 | * |
||
| 1157 | * @param BAB_DateTime $startdate |
||
| 1158 | * @param bab_CalendarPeriod $p |
||
| 1159 | * |
||
| 1160 | * @return float |
||
| 1161 | */ |
||
| 1162 | protected function getPeriodQuantity(BAB_DateTime $startdate, bab_CalendarPeriod $p) |
||
| 1163 | { |
||
| 1164 | $type = $this->getPeriodType($p); |
||
| 1165 | |||
| 1166 | if ('AMPM' === $type) { |
||
| 1167 | $period_days = 1.0; |
||
| 1168 | } |
||
| 1169 | |||
| 1170 | if ('AM' === $type || 'PM' === $type) { |
||
| 1171 | $period_days = 0.5; |
||
| 1172 | } |
||
| 1173 | |||
| 1174 | $moment = $startdate->getTimeStamp(); |
||
| 1175 | |||
| 1176 | |||
| 1177 | if ($moment > $p->ts_begin && $moment < $p->ts_end) { |
||
| 1178 | $period_seconds = $p->getDuration(); |
||
| 1179 | $new_period = clone $p; |
||
| 1180 | $new_period->setBeginDate($startdate); |
||
| 1181 | |||
| 1182 | $new_seconds = $new_period->getDuration(); |
||
| 1183 | |||
| 1184 | $period_days = ($new_seconds * $period_days) / $period_seconds; |
||
| 1185 | } |
||
| 1186 | |||
| 1187 | return $period_days; |
||
| 1188 | } |
||
| 1189 | |||
| 1190 | |||
| 1191 | |||
| 1192 | |||
| 1193 | /** |
||
| 1194 | * Convert days to hours |
||
| 1195 | * using the number of hours in a specified day |
||
| 1196 | * the number of days given as parameter should be less than 1 |
||
| 1197 | * |
||
| 1198 | * @param string $date Must be a date in the entry period |
||
| 1199 | * @param float $days |
||
| 1200 | * |
||
| 1201 | * @return float Hours |
||
| 1202 | */ |
||
| 1203 | protected function getDayDurationInHours($date, $days) |
||
| 1204 | { |
||
| 1205 | $hours_in_day = 0; |
||
| 1206 | |||
| 1207 | foreach ($this->getWorkingPeriods() as $p) { |
||
| 1208 | $pdate = date('Y-m-d', $p->ts_begin); |
||
| 1209 | |||
| 1210 | if ($pdate !== $date) { |
||
| 1211 | continue; |
||
| 1212 | } |
||
| 1213 | |||
| 1214 | $hours_in_day += ($p->getDuration()/3600); |
||
| 1215 | } |
||
| 1216 | |||
| 1217 | $hours = ($days * $hours_in_day); |
||
| 1218 | |||
| 1219 | return $hours; |
||
| 1220 | } |
||
| 1221 | |||
| 1222 | |||
| 1223 | |||
| 1224 | |||
| 1225 | /** |
||
| 1226 | * |
||
| 1227 | * |
||
| 1228 | * @param bab_CalendarPeriod $period |
||
| 1229 | * |
||
| 1230 | * @return AM | PM | AMPM |
||
| 1231 | */ |
||
| 1232 | 20 | protected function getPeriodType(bab_CalendarPeriod $period) |
|
| 1233 | { |
||
| 1234 | 20 | $endtype = date('A', $period->ts_end); |
|
| 1235 | 20 | $begintype = date('A', $period->ts_begin); |
|
| 1236 | |||
| 1237 | 20 | if ('AM' === $endtype || '12:00:00' === date('H:i:s', $period->ts_end)) { // || 'AM' === $begintype && '14:00:00' >= date('H:i:s', $period->ts_end) |
|
| 1238 | 14 | return 'AM'; |
|
| 1239 | } |
||
| 1240 | |||
| 1241 | 20 | if ('AM' === $begintype && '14:00:00' >= date('H:i:s', $period->ts_end)) { |
|
| 1242 | 6 | return 'AM'; |
|
| 1243 | } |
||
| 1244 | |||
| 1245 | 20 | if ('PM' === $begintype || '12:00:00' === date('H:i:s', $period->ts_begin)) { |
|
| 1246 | 20 | return 'PM'; |
|
| 1247 | } |
||
| 1248 | |||
| 1249 | return 'AMPM'; |
||
| 1250 | } |
||
| 1251 | |||
| 1252 | |||
| 1253 | |||
| 1254 | |||
| 1255 | /** |
||
| 1256 | * Save elements of entry to database |
||
| 1257 | * |
||
| 1258 | */ |
||
| 1259 | public function saveElements() |
||
| 1260 | { |
||
| 1261 | $processed_ids = array(); |
||
| 1262 | |||
| 1263 | foreach ($this->elements as $elem) |
||
| 1264 | { |
||
| 1265 | /*@var $elem absences_EntryElem */ |
||
| 1266 | |||
| 1267 | try { |
||
| 1268 | |||
| 1269 | $elem->save(); |
||
| 1270 | $processed_ids[] = $elem->id; |
||
| 1271 | |||
| 1272 | } catch(Exception $e) { |
||
| 1273 | // fail to save one element, it will be deleted or not created |
||
| 1274 | bab_debug($e->getMessage()); |
||
| 1275 | } |
||
| 1276 | } |
||
| 1277 | |||
| 1278 | // delete removed elements |
||
| 1279 | |||
| 1280 | global $babDB; |
||
| 1281 | |||
| 1282 | $babDB->db_query('DELETE FROM absences_entries_elem WHERE id_entry='.$babDB->quote($this->id).' AND id NOT IN('.$babDB->quote($processed_ids).')'); |
||
| 1283 | |||
| 1284 | } |
||
| 1285 | |||
| 1286 | |||
| 1287 | |||
| 1288 | |||
| 1289 | public function savePlannedPeriods() |
||
| 1290 | { |
||
| 1291 | if (empty($this->plannedPeriods)) { |
||
| 1292 | throw new Exception('Planned periods where not loaded or set'); |
||
| 1293 | } |
||
| 1294 | |||
| 1295 | $processed_ids = array(); |
||
| 1296 | |||
| 1297 | foreach ($this->plannedPeriods as $period) |
||
| 1298 | { |
||
| 1299 | /*@var $elem absences_EntryPeriod */ |
||
| 1300 | $period->save(); |
||
| 1301 | |||
| 1302 | $processed_ids[] = $period->id; |
||
| 1303 | } |
||
| 1304 | |||
| 1305 | global $babDB; |
||
| 1306 | |||
| 1307 | $babDB->db_query('DELETE FROM absences_entries_periods WHERE id_entry='.$babDB->quote($this->id).' AND id NOT IN('.$babDB->quote($processed_ids).')'); |
||
| 1308 | |||
| 1309 | } |
||
| 1310 | |||
| 1311 | |||
| 1312 | |||
| 1313 | /** |
||
| 1314 | * Apply dynamic rights for all right involved in the entry |
||
| 1315 | */ |
||
| 1316 | public function applyDynamicRight() |
||
| 1317 | { |
||
| 1318 | require_once dirname(__FILE__).'/agent_right.class.php'; |
||
| 1319 | |||
| 1320 | $I = new absences_AgentRightManagerIterator(); |
||
| 1321 | $I->setAgent($this->getAgent()); |
||
| 1322 | |||
| 1323 | foreach ($I as $agentRight) |
||
| 1324 | { |
||
| 1325 | /*@var $agentRight absences_AgentRight */ |
||
| 1326 | $agentRight->applyDynamicRight(); |
||
| 1327 | } |
||
| 1328 | } |
||
| 1329 | |||
| 1330 | |||
| 1331 | |||
| 1332 | |||
| 1333 | /** |
||
| 1334 | * Add element to list |
||
| 1335 | * @param absences_EntryElem $elem |
||
| 1336 | */ |
||
| 1337 | 39 | public function addElement(absences_EntryElem $elem) |
|
| 1341 | |||
| 1342 | /** |
||
| 1343 | * Remove an element in the list |
||
| 1344 | * @param int $id_right |
||
| 1345 | * |
||
| 1346 | * @return bool |
||
| 1347 | */ |
||
| 1348 | public function removeElement($id_right) |
||
| 1349 | { |
||
| 1350 | foreach ($this->elements as $key => $elem) |
||
| 1351 | { |
||
| 1352 | if ($elem->id_right == $id_right) |
||
| 1353 | { |
||
| 1354 | unset($this->elements[$key]); |
||
| 1355 | return true; |
||
| 1356 | } |
||
| 1357 | } |
||
| 1358 | |||
| 1359 | return false; |
||
| 1360 | } |
||
| 1361 | |||
| 1362 | |||
| 1363 | /** |
||
| 1364 | * Set the working period index for the entry |
||
| 1365 | * Used in unit tests to set differents working periods |
||
| 1366 | * if not used, the workingPeriodIndex will be generated from the calendar API |
||
| 1367 | * |
||
| 1368 | */ |
||
| 1369 | 38 | public function setWorkingPeriodIndex(Array $index_working) |
|
| 1370 | { |
||
| 1371 | 38 | $this->workingPeriodIndex = $index_working; |
|
| 1372 | 38 | return $this; |
|
| 1373 | } |
||
| 1374 | |||
| 1375 | /** |
||
| 1376 | * Get working period index for the user and for the period |
||
| 1377 | * @return array |
||
| 1378 | */ |
||
| 1379 | 35 | private function getWorkingPeriodIndex() |
|
| 1380 | { |
||
| 1381 | 35 | if (!isset($this->workingPeriodIndex)) { |
|
| 1382 | |||
| 1383 | include_once $GLOBALS['babInstallPath']."utilit/dateTime.php"; |
||
| 1384 | |||
| 1385 | list($index_working,, $is_free) = absences_getHalfDaysIndex( |
||
| 1386 | $this->id_user, |
||
| 1387 | BAB_DateTime::fromIsoDateTime($this->date_begin), |
||
| 1388 | BAB_DateTime::fromIsoDateTime($this->date_end), |
||
| 1389 | true |
||
| 1390 | ); |
||
| 1391 | |||
| 1392 | |||
| 1393 | foreach ($index_working as $key => $period_list) { |
||
| 1394 | if (!isset($is_free[$key])) { |
||
| 1395 | unset($index_working[$key]); |
||
| 1396 | } |
||
| 1397 | } |
||
| 1398 | |||
| 1399 | $this->workingPeriodIndex = $index_working; |
||
| 1400 | } |
||
| 1401 | |||
| 1402 | 35 | return $this->workingPeriodIndex; |
|
| 1403 | } |
||
| 1404 | |||
| 1405 | |||
| 1406 | |||
| 1407 | /** |
||
| 1408 | * Number of free days and hours between two dates |
||
| 1409 | * |
||
| 1410 | */ |
||
| 1411 | 35 | private function loadDurations() { |
|
| 1412 | |||
| 1413 | 35 | $this->duration_days = 0.0; |
|
| 1414 | 35 | $this->duration_hours = 0.0; |
|
| 1415 | 35 | $this->working_periods = array(); |
|
| 1416 | |||
| 1417 | |||
| 1418 | |||
| 1419 | 35 | $index_working = $this->getWorkingPeriodIndex(); |
|
| 1420 | |||
| 1421 | |||
| 1422 | 35 | foreach ($index_working as $key => $period_list) { |
|
| 1423 | |||
| 1424 | 35 | $this->duration_days += 0.5; |
|
| 1425 | |||
| 1426 | 35 | foreach($period_list as $p) |
|
| 1427 | { |
||
| 1428 | /*@var $p bab_CalendarPeriod */ |
||
| 1429 | |||
| 1430 | 35 | if ($p->getCollection() instanceof bab_WorkingPeriodCollection) |
|
| 1431 | 35 | { |
|
| 1432 | 35 | $this->working_periods[] = $p; |
|
| 1433 | 35 | $this->duration_hours += ($p->getDuration() / 3600); |
|
| 1434 | 35 | } |
|
| 1435 | 35 | } |
|
| 1436 | 35 | } |
|
| 1437 | 35 | } |
|
| 1438 | |||
| 1439 | |||
| 1440 | /** |
||
| 1441 | * Get list of working periods of the entry |
||
| 1442 | * @return bab_CalendarPeriod[] |
||
| 1443 | */ |
||
| 1444 | 35 | protected function getWorkingPeriods() |
|
| 1445 | { |
||
| 1446 | 35 | if (!isset($this->working_periods)) { |
|
| 1447 | 35 | $this->loadDurations(); |
|
| 1448 | 35 | } |
|
| 1449 | |||
| 1450 | 35 | return $this->working_periods; |
|
| 1451 | } |
||
| 1452 | |||
| 1453 | |||
| 1454 | /** |
||
| 1455 | * List of working periods for one day |
||
| 1456 | * @param string $date 10 chars |
||
| 1457 | * |
||
| 1458 | * @return bab_CalendarPeriod[] |
||
| 1459 | */ |
||
| 1460 | public function getDayWorkingPeriods($date) |
||
| 1461 | { |
||
| 1462 | $return = array(); |
||
| 1463 | foreach ($this->getWorkingPeriods() as $period) { |
||
| 1464 | if ($date === date('Y-m-d', $period->ts_begin)) { |
||
| 1465 | $return[] = $period; |
||
| 1466 | } |
||
| 1467 | } |
||
| 1468 | |||
| 1469 | return $return; |
||
| 1470 | } |
||
| 1471 | |||
| 1472 | |||
| 1473 | /** |
||
| 1474 | * List of working periods for one day |
||
| 1475 | * @param string $date 10 chars |
||
| 1476 | * |
||
| 1477 | * @return absences_EntryPeriod[] |
||
| 1478 | */ |
||
| 1479 | public function getDayPlannedPeriods($date) |
||
| 1480 | { |
||
| 1481 | $return = array(); |
||
| 1482 | foreach ($this->getPlannedPeriodsIterator() as $period) { |
||
| 1483 | if ($date === substr($period->date_begin, 0, 10)) { |
||
| 1484 | $return[] = $period; |
||
| 1485 | } |
||
| 1486 | } |
||
| 1487 | |||
| 1488 | return $return; |
||
| 1489 | } |
||
| 1490 | |||
| 1491 | |||
| 1492 | |||
| 1493 | |||
| 1494 | /** |
||
| 1495 | * Get period duration in days |
||
| 1496 | * @return float |
||
| 1497 | */ |
||
| 1498 | public function getDurationDays() |
||
| 1499 | { |
||
| 1500 | if (!isset($this->duration_days)) |
||
| 1501 | { |
||
| 1502 | $this->loadDurations(); |
||
| 1503 | } |
||
| 1504 | |||
| 1505 | return $this->duration_days; |
||
| 1506 | } |
||
| 1507 | |||
| 1508 | /** |
||
| 1509 | * Get period duration in hours |
||
| 1510 | * @return float |
||
| 1511 | */ |
||
| 1512 | public function getDurationHours() |
||
| 1513 | { |
||
| 1514 | if (!isset($this->duration_hours)) |
||
| 1515 | { |
||
| 1516 | $this->loadDurations(); |
||
| 1517 | } |
||
| 1518 | |||
| 1519 | return $this->duration_hours; |
||
| 1520 | } |
||
| 1521 | |||
| 1522 | |||
| 1523 | /** |
||
| 1524 | * Convert a number of days to hours |
||
| 1525 | * @param float $days |
||
| 1526 | * @return float |
||
| 1527 | */ |
||
| 1528 | View Code Duplication | private function daysToHours($days) |
|
| 1529 | { |
||
| 1530 | |||
| 1531 | |||
| 1532 | if (0 === (int) round(100 * $this->getTotalDays())) |
||
| 1533 | { |
||
| 1534 | return 0; |
||
| 1535 | } |
||
| 1536 | |||
| 1537 | $ratio = $this->getPlannedDurationHours() / $this->getPlannedDurationDays(); |
||
| 1538 | return round(($ratio * $days), 2); |
||
| 1539 | } |
||
| 1540 | |||
| 1541 | /** |
||
| 1542 | * Convert a number of hours to days |
||
| 1543 | * @param float $hours |
||
| 1544 | * @return float |
||
| 1545 | */ |
||
| 1546 | View Code Duplication | private function hoursToDays($hours) |
|
| 1547 | { |
||
| 1548 | if (0 == $this->getTotalHours()) |
||
| 1549 | { |
||
| 1550 | return 0; |
||
| 1551 | } |
||
| 1552 | |||
| 1553 | $ratio = $this->getPlannedDurationDays() / $this->getPlannedDurationHours(); |
||
| 1554 | return round(($ratio * $hours), 2); |
||
| 1555 | } |
||
| 1556 | |||
| 1557 | |||
| 1558 | |||
| 1559 | /** |
||
| 1560 | * Compute totals for loaded elements |
||
| 1561 | */ |
||
| 1562 | private function loadedElementsTotal() |
||
| 1563 | { |
||
| 1564 | if (empty($this->elements)) |
||
| 1565 | { |
||
| 1566 | $this->loadElements(); |
||
| 1567 | } |
||
| 1568 | |||
| 1569 | $this->total_days = 0.0; |
||
| 1570 | $this->total_hours = 0.0; |
||
| 1571 | $this->total_type_days = array(); |
||
| 1572 | $this->total_type_hours = array(); |
||
| 1573 | |||
| 1574 | foreach($this->elements as $elem) |
||
| 1575 | { |
||
| 1576 | /*@var $elem absences_EntryElem */ |
||
| 1577 | $right = $elem->getRight(); |
||
| 1578 | |||
| 1579 | $quantity = (float) $elem->quantity; |
||
| 1580 | |||
| 1581 | switch($right->quantity_unit) |
||
| 1582 | { |
||
| 1583 | case 'D': |
||
| 1584 | $hours = $this->daysToHours($quantity); |
||
| 1585 | $this->addQUantityInCache($right, $quantity, $hours); |
||
| 1586 | break; |
||
| 1587 | case 'H': |
||
| 1588 | $days = $this->hoursToDays($quantity); |
||
| 1589 | $this->addQUantityInCache($right, $days, $quantity); |
||
| 1590 | break; |
||
| 1591 | } |
||
| 1592 | } |
||
| 1593 | } |
||
| 1594 | |||
| 1595 | |||
| 1596 | /** |
||
| 1597 | * Populate the cache variables for one element |
||
| 1598 | * |
||
| 1599 | * @param absences_Right $right |
||
| 1600 | * @param float $days |
||
| 1601 | * @param float $hours |
||
| 1602 | */ |
||
| 1603 | private function addQUantityInCache(absences_Right $right, $days, $hours) |
||
| 1604 | { |
||
| 1605 | if (!isset($this->total_type_days[$right->id_type])) { |
||
| 1606 | $this->total_type_days[$right->id_type] = 0.0; |
||
| 1607 | } |
||
| 1608 | |||
| 1609 | if (!isset($this->total_type_hours[$right->id_type])) { |
||
| 1610 | $this->total_type_hours[$right->id_type] = 0.0; |
||
| 1611 | } |
||
| 1612 | |||
| 1613 | $this->total_days += $days; |
||
| 1614 | $this->total_hours += $hours; |
||
| 1615 | $this->total_type_days[$right->id_type] += $days; |
||
| 1616 | $this->total_type_hours[$right->id_type] += $hours; |
||
| 1617 | } |
||
| 1618 | |||
| 1619 | |||
| 1620 | |||
| 1621 | |||
| 1622 | |||
| 1623 | /** |
||
| 1624 | * Get sum of elements quantity, converted in days |
||
| 1625 | * |
||
| 1626 | * @param int $id_type Optional filter by type |
||
| 1627 | * |
||
| 1628 | * @return float |
||
| 1629 | */ |
||
| 1630 | View Code Duplication | public function getTotalDays($id_type = null) |
|
| 1647 | |||
| 1648 | /** |
||
| 1649 | * Get sum of elements quantity, converted in hours |
||
| 1650 | * |
||
| 1651 | * @param int $id_type Optional filter by type |
||
| 1652 | * |
||
| 1653 | * @return float |
||
| 1654 | */ |
||
| 1655 | View Code Duplication | public function getTotalHours($id_type = null) |
|
| 1672 | |||
| 1673 | |||
| 1674 | |||
| 1675 | |||
| 1676 | /** |
||
| 1677 | * Number of days on entry between two dates |
||
| 1678 | * si les dates de l'element sont a cheval sur la periode demandee |
||
| 1679 | * on utlise les heures travailles qui etait en vigeur au moment de la creation |
||
| 1680 | * de la demande |
||
| 1681 | * |
||
| 1682 | * @param string $begin Datetime |
||
| 1683 | * @param string $end Datetime |
||
| 1684 | * @param int $id_type Optional filter by type |
||
| 1685 | * |
||
| 1686 | * @return float (days) |
||
| 1687 | */ |
||
| 1688 | 1 | View Code Duplication | public function getPlannedDaysBetween($begin, $end, $id_type = null) |
| 1689 | { |
||
| 1690 | 1 | if (empty($this->elements)) |
|
| 1691 | 1 | { |
|
| 1692 | $this->loadElements(); |
||
| 1693 | } |
||
| 1694 | |||
| 1695 | 1 | $total = 0.0; |
|
| 1696 | 1 | foreach($this->elements as $elem) |
|
| 1697 | { |
||
| 1698 | /*@var $elem absences_EntryElem */ |
||
| 1699 | 1 | $right = $elem->getRight(); |
|
| 1700 | |||
| 1701 | 1 | if (isset($id_type) && (int) $id_type !== (int) $right->id_type) { |
|
| 1702 | continue; |
||
| 1703 | } |
||
| 1704 | |||
| 1705 | 1 | $quantity = $elem->getPlannedQuantityBetween($begin, $end); |
|
| 1706 | |||
| 1707 | 1 | if ('H' === $right->quantity_unit) { |
|
| 1708 | $days = $this->hoursToDays($quantity); |
||
| 1709 | } else { |
||
| 1710 | 1 | $days = $quantity; |
|
| 1711 | } |
||
| 1712 | |||
| 1713 | 1 | $total += $days; |
|
| 1714 | 1 | } |
|
| 1715 | |||
| 1716 | 1 | return $total; |
|
| 1717 | } |
||
| 1718 | |||
| 1719 | |||
| 1720 | |||
| 1721 | |||
| 1722 | /** |
||
| 1723 | * Number of hours on entry between two dates |
||
| 1724 | * si les dates de l'element sont a cheval sur la periode demandee |
||
| 1725 | * on utlise les heures travailles qui etait en vigeur au moment de la creation |
||
| 1726 | * de la demande |
||
| 1727 | * |
||
| 1728 | * @param string $begin Datetime |
||
| 1729 | * @param string $end Datetime |
||
| 1730 | * @param int $id_type Optional filter by type |
||
| 1731 | * |
||
| 1732 | * @return float (hours) |
||
| 1733 | */ |
||
| 1734 | View Code Duplication | public function getPlannedHoursBetween($begin, $end, $id_type = null) |
|
| 1735 | { |
||
| 1736 | if (empty($this->elements)) |
||
| 1737 | { |
||
| 1738 | $this->loadElements(); |
||
| 1739 | } |
||
| 1740 | |||
| 1741 | $total = 0.0; |
||
| 1742 | foreach($this->elements as $elem) |
||
| 1743 | { |
||
| 1744 | /*@var $elem absences_EntryElem */ |
||
| 1745 | $right = $elem->getRight(); |
||
| 1746 | |||
| 1747 | if (isset($id_type) && (int) $id_type !== (int) $right->id_type) { |
||
| 1748 | continue; |
||
| 1749 | } |
||
| 1750 | |||
| 1751 | $quantity = $elem->getPlannedQuantityBetween($begin, $end); |
||
| 1752 | |||
| 1753 | if ('D' === $right->quantity_unit) { |
||
| 1754 | $hours = $this->daysToHours($quantity); |
||
| 1755 | } else { |
||
| 1756 | $hours = $quantity; |
||
| 1757 | } |
||
| 1758 | |||
| 1759 | $total += $hours; |
||
| 1760 | } |
||
| 1761 | |||
| 1762 | return $total; |
||
| 1763 | } |
||
| 1764 | |||
| 1765 | |||
| 1766 | |||
| 1767 | |||
| 1768 | |||
| 1769 | |||
| 1770 | |||
| 1771 | |||
| 1772 | /** |
||
| 1773 | * Test if the loaded elements in entry contains rights in hours |
||
| 1774 | * @return bool |
||
| 1775 | */ |
||
| 1776 | public function containsHours() |
||
| 1777 | { |
||
| 1778 | foreach($this->elements as $elem) |
||
| 1779 | { |
||
| 1780 | if ('H' === $elem->getRight()->quantity_unit) |
||
| 1781 | { |
||
| 1782 | return true; |
||
| 1783 | } |
||
| 1784 | } |
||
| 1785 | |||
| 1786 | return false; |
||
| 1787 | } |
||
| 1788 | |||
| 1789 | |||
| 1790 | /** |
||
| 1791 | * Test if loaded elements in entry require approval |
||
| 1792 | * |
||
| 1793 | * @return bool |
||
| 1794 | */ |
||
| 1795 | public function requireApproval() |
||
| 1812 | |||
| 1813 | |||
| 1814 | public function checkAvailable() |
||
| 1815 | { |
||
| 1816 | $res = $this->getElementsIterator(); |
||
| 1817 | foreach ($res as $element) { |
||
| 1818 | /*@var $element absences_EntryElem */ |
||
| 1819 | if (!$element->isQuantityAvailable()) { |
||
| 1820 | throw new Exception(sprintf(absences_translate('Failed to submit this request, the quantity for right %s s not available'), $element->getRight()->description)); |
||
| 1821 | } |
||
| 1822 | } |
||
| 1823 | } |
||
| 1824 | |||
| 1825 | |||
| 1826 | /** |
||
| 1827 | * Check elements validity |
||
| 1828 | * @throws UnexpectedValueException |
||
| 1829 | * |
||
| 1830 | * @return int number of elements with quantity > 0 |
||
| 1831 | */ |
||
| 1832 | protected function checkElementsValidity() |
||
| 1833 | { |
||
| 1834 | $count = 0; |
||
| 1835 | foreach($this->elements as $elem) |
||
| 1836 | { |
||
| 1837 | $quantity = (int) round(100 * $elem->quantity); |
||
| 1838 | if ($quantity > 0) |
||
| 1839 | { |
||
| 1840 | $count++; |
||
| 1841 | } |
||
| 1842 | |||
| 1843 | $elem->checkValidity(); |
||
| 1844 | } |
||
| 1845 | |||
| 1846 | return $count; |
||
| 1847 | } |
||
| 1848 | |||
| 1849 | |||
| 1850 | /** |
||
| 1851 | * throw an exception if there is another entry in the same period |
||
| 1852 | * @throws absences_EntryException |
||
| 1853 | */ |
||
| 1854 | protected function checkOtherEntriesValidity() |
||
| 1855 | { |
||
| 1856 | $otherEntries = new absences_EntryIterator(); |
||
| 1857 | $otherEntries->from = $this->date_begin; |
||
| 1858 | $otherEntries->to = $this->date_end; |
||
| 1859 | $otherEntries->users = array($this->id_user); |
||
| 1860 | |||
| 1861 | |||
| 1862 | foreach ($otherEntries as $otherEntry) { |
||
| 1863 | |||
| 1864 | /* @var $otherEntry absences_Entry */ |
||
| 1865 | |||
| 1875 | |||
| 1876 | |||
| 1877 | /** |
||
| 1878 | * Check request validity |
||
| 1879 | * |
||
| 1880 | * @throws absences_EntryException |
||
| 1881 | * @throws UnexpectedValueException |
||
| 1882 | * |
||
| 1883 | * @return bool |
||
| 1884 | */ |
||
| 1885 | public function checkValidity() |
||
| 1990 | |||
| 1991 | |||
| 1992 | /** |
||
| 1993 | * (non-PHPdoc) |
||
| 1994 | * @see absences_Request::modifiedOn() |
||
| 1995 | * |
||
| 1996 | * @return string |
||
| 1997 | */ |
||
| 1998 | 1 | public function modifiedOn() |
|
| 2002 | |||
| 2003 | /** |
||
| 2004 | * Test if the entry is a fixed vacation |
||
| 2005 | * @return bool |
||
| 2006 | */ |
||
| 2007 | public function isFixed() |
||
| 2012 | |||
| 2013 | |||
| 2014 | |||
| 2015 | |||
| 2016 | |||
| 2017 | /** |
||
| 2018 | * Test if entry is previsonal |
||
| 2019 | * @return bool |
||
| 2020 | */ |
||
| 2021 | public function isPrevisonal() |
||
| 2025 | |||
| 2026 | /** |
||
| 2027 | * Test if at least one entry in folder is previsonal |
||
| 2028 | * @return boolean |
||
| 2029 | */ |
||
| 2030 | public function isFolderPrevisonal() |
||
| 2043 | |||
| 2044 | /** |
||
| 2045 | * Get the first entry in folder |
||
| 2046 | * @return absences_Entry |
||
| 2047 | */ |
||
| 2048 | View Code Duplication | public function getFolderFirst() |
|
| 2065 | |||
| 2066 | |||
| 2067 | /** |
||
| 2068 | * Process specific code when the request is rejected |
||
| 2069 | * |
||
| 2070 | */ |
||
| 2071 | protected function onReject() |
||
| 2075 | |||
| 2076 | |||
| 2077 | /** |
||
| 2078 | * Process specific code when the request is confirmed |
||
| 2079 | * |
||
| 2080 | */ |
||
| 2081 | public function onConfirm() |
||
| 2085 | |||
| 2086 | |||
| 2087 | |||
| 2088 | /** |
||
| 2089 | * Call the user calendar backend to update the event |
||
| 2090 | * call the event to notify about calendar event modification |
||
| 2091 | */ |
||
| 2092 | public function updateCalendar() |
||
| 2121 | |||
| 2122 | |||
| 2123 | public function getTitle() |
||
| 2131 | |||
| 2132 | |||
| 2133 | View Code Duplication | public function getNotifyFields() |
|
| 2141 | |||
| 2142 | |||
| 2143 | View Code Duplication | public function getYear() |
|
| 2154 | |||
| 2155 | |||
| 2156 | View Code Duplication | public function getArchiveYear() |
|
| 2176 | |||
| 2177 | View Code Duplication | public function archive() |
|
| 2188 | |||
| 2189 | |||
| 2190 | View Code Duplication | public function setNotified() |
|
| 2206 | |||
| 2207 | |||
| 2208 | public function getManagerEditUrl() |
||
| 2214 | |||
| 2215 | |||
| 2216 | public function getManagerDeleteUrl() |
||
| 2225 | |||
| 2226 | |||
| 2227 | public function getManagerFrame() |
||
| 2242 | |||
| 2243 | |||
| 2244 | /** |
||
| 2245 | * |
||
| 2246 | * @param bool $display_username Affiche le nom du demandeur dans la card frame ou non, utile pour les listes contenant plusieurs demandeurs possibles |
||
| 2247 | * @param int $rfrom si les demandes de la liste sont modifiee par un gestionnaire ou gestionnaire delegue |
||
| 2248 | * @param int $ide id entite de l'organigramme >0 si gestionnaire delegue seulement |
||
| 2249 | */ |
||
| 2250 | public function getCardFrame($display_username, $rfrom, $ide) |
||
| 2324 | |||
| 2325 | |||
| 2326 | |||
| 2327 | |||
| 2328 | |||
| 2329 | /** |
||
| 2330 | * @return string |
||
| 2331 | */ |
||
| 2332 | public function getEditUrl($rfrom, $ide = null) |
||
| 2349 | |||
| 2350 | |||
| 2351 | |||
| 2352 | /** |
||
| 2353 | * Delete the vacation request |
||
| 2354 | * @return bool |
||
| 2355 | */ |
||
| 2356 | public function delete() |
||
| 2413 | |||
| 2414 | |||
| 2415 | |||
| 2416 | |||
| 2417 | |||
| 2418 | |||
| 2419 | |||
| 2420 | /** |
||
| 2421 | * (non-PHPdoc) |
||
| 2422 | * @see absences_Request::notifyOwner() |
||
| 2423 | */ |
||
| 2424 | public function notifyOwner() |
||
| 2443 | |||
| 2444 | } |
||
| 2445 | |||
| 2896 |
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.
Unreachable code is most often the result of
return,dieorexitstatements that have been added for debug purposes.In the above example, the last
return falsewill never be executed, because a return statement has already been met in every possible execution path.