dolibarr 21.0.0-alpha
holiday.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2011 Dimitri Mouillard <dmouillard@teclib.com>
3 * Copyright (C) 2012-2014 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2012-2016 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
6 * Copyright (C) 2016 Juanjo Menent <jmenent@2byte.es>
7 * Copyright (C) 2018-2024 Frédéric France <frederic.france@free.fr>
8 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
29require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
30
31
35class Holiday extends CommonObject
36{
40 public $element = 'holiday';
41
45 public $table_element = 'holiday';
46
50 public $fk_element = 'fk_holiday';
51
55 public $picto = 'holiday';
56
60 public $fk_user;
61
65 public $date_create = '';
66
70 public $description;
71
75 public $date_debut = '';
76
80 public $date_fin = '';
81
85 public $date_debut_gmt = '';
86
90 public $date_fin_gmt = '';
91
95 public $halfday = '';
96
101 public $statut = 0;
102
106 public $fk_validator;
107
111 public $date_valid = 0;
112
116 public $fk_user_valid;
117
121 public $date_approval;
122
126 public $fk_user_approve;
127
131 public $date_refuse = 0;
132
136 public $fk_user_refuse;
137
141 public $date_cancel = 0;
142
146 public $fk_user_cancel;
147
151 public $fk_user_create;
152
156 public $detail_refuse = '';
157
161 public $fk_type;
162
163 public $holiday = array();
164 public $events = array();
165 public $logs = array();
166
167
171 public $optName = '';
175 public $optValue = '';
179 public $optRowid = 0;
180
184 const STATUS_DRAFT = 1;
200 const STATUS_REFUSED = 5;
201
202
208 public function __construct($db)
209 {
210 $this->db = $db;
211
212 $this->ismultientitymanaged = 0;
213 }
214
215
223 public function getNextNumRef($objsoc)
224 {
225 global $langs, $conf;
226 $langs->load("order");
227
228 if (!getDolGlobalString('HOLIDAY_ADDON')) {
229 $conf->global->HOLIDAY_ADDON = 'mod_holiday_madonna';
230 }
231
232 if (getDolGlobalString('HOLIDAY_ADDON')) {
233 $mybool = false;
234
235 $file = getDolGlobalString('HOLIDAY_ADDON') . ".php";
236 $classname = getDolGlobalString('HOLIDAY_ADDON');
237
238 // Include file with class
239 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
240 foreach ($dirmodels as $reldir) {
241 $dir = dol_buildpath($reldir."core/modules/holiday/");
242
243 // Load file with numbering class (if found)
244 $mybool = ((bool) @include_once $dir.$file) || $mybool;
245 }
246
247 if (!$mybool) {
248 dol_print_error(null, "Failed to include file ".$file);
249 return '';
250 }
251
252 $obj = new $classname();
253 '@phan-var-force ModelNumRefHolidays $obj';
254 $numref = $obj->getNextValue($objsoc, $this);
255
256 if ($numref != "") {
257 return $numref;
258 } else {
259 $this->error = $obj->error;
260 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
261 return "";
262 }
263 } else {
264 print $langs->trans("Error")." ".$langs->trans("Error_HOLIDAY_ADDON_NotDefined");
265 return "";
266 }
267 }
268
274 public function updateBalance()
275 {
276 $this->db->begin();
277
278 // Update sold of vocations
279 $result = $this->updateSoldeCP();
280
281 // Check nb of users into table llx_holiday_users and update with empty lines
282 //if ($result > 0) $result = $this->verifNbUsers($this->countActiveUsersWithoutCP(), $this->getConfCP('nbUser'));
283
284 if ($result >= 0) {
285 $this->db->commit();
286 return 0; // for cronjob use (0 is OK, any other value is an error code)
287 } else {
288 $this->db->rollback();
289 return -1;
290 }
291 }
292
300 public function create($user, $notrigger = 0)
301 {
302 global $conf;
303 $error = 0;
304
305 $now = dol_now();
306
307 // Check parameters
308 if (empty($this->fk_user) || !is_numeric($this->fk_user) || $this->fk_user < 0) {
309 $this->error = "ErrorBadParameterFkUser";
310 return -1;
311 }
312 if (empty($this->fk_validator) || !is_numeric($this->fk_validator) || $this->fk_validator < 0) {
313 $this->error = "ErrorBadParameterFkValidator";
314 return -1;
315 }
316 if (empty($this->fk_type) || !is_numeric($this->fk_type) || $this->fk_type < 0) {
317 $this->error = "ErrorBadParameterFkType";
318 return -1;
319 }
320
321 // Insert request
322 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday(";
323 $sql .= "ref,";
324 $sql .= "fk_user,";
325 $sql .= "date_create,";
326 $sql .= "description,";
327 $sql .= "date_debut,";
328 $sql .= "date_fin,";
329 $sql .= "halfday,";
330 $sql .= "statut,";
331 $sql .= "fk_validator,";
332 $sql .= "fk_type,";
333 $sql .= "fk_user_create,";
334 $sql .= "entity";
335 $sql .= ") VALUES (";
336 $sql .= "'(PROV)',";
337 $sql .= " ".((int) $this->fk_user).",";
338 $sql .= " '".$this->db->idate($now)."',";
339 $sql .= " '".$this->db->escape($this->description)."',";
340 $sql .= " '".$this->db->idate($this->date_debut)."',";
341 $sql .= " '".$this->db->idate($this->date_fin)."',";
342 $sql .= " ".((int) $this->halfday).",";
343 $sql .= " '1',";
344 $sql .= " ".((int) $this->fk_validator).",";
345 $sql .= " ".((int) $this->fk_type).",";
346 $sql .= " ".((int) $user->id).",";
347 $sql .= " ".((int) $conf->entity);
348 $sql .= ")";
349
350 $this->db->begin();
351
352 dol_syslog(get_class($this)."::create", LOG_DEBUG);
353 $resql = $this->db->query($sql);
354 if (!$resql) {
355 $error++;
356 $this->errors[] = "Error ".$this->db->lasterror();
357 }
358
359 if (!$error) {
360 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."holiday");
361
362 if ($this->id) {
363 // update ref
364 $initialref = '(PROV'.$this->id.')';
365 if (!empty($this->ref)) {
366 $initialref = $this->ref;
367 }
368
369 $sql = 'UPDATE '.MAIN_DB_PREFIX."holiday SET ref='".$this->db->escape($initialref)."' WHERE rowid=".((int) $this->id);
370 if ($this->db->query($sql)) {
371 $this->ref = $initialref;
372
373 if (!$error) {
374 $result = $this->insertExtraFields();
375 if ($result < 0) {
376 $error++;
377 }
378 }
379
380 if (!$error && !$notrigger) {
381 // Call trigger
382 $result = $this->call_trigger('HOLIDAY_CREATE', $user);
383 if ($result < 0) {
384 $error++;
385 }
386 // End call triggers
387 }
388 }
389 }
390 }
391
392 // Commit or rollback
393 if ($error) {
394 foreach ($this->errors as $errmsg) {
395 dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR);
396 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
397 }
398 $this->db->rollback();
399 return -1 * $error;
400 } else {
401 $this->db->commit();
402 return $this->id;
403 }
404 }
405
406
414 public function fetch($id, $ref = '')
415 {
416 $sql = "SELECT";
417 $sql .= " cp.rowid,";
418 $sql .= " cp.ref,";
419 $sql .= " cp.fk_user,";
420 $sql .= " cp.date_create,";
421 $sql .= " cp.description,";
422 $sql .= " cp.date_debut,";
423 $sql .= " cp.date_fin,";
424 $sql .= " cp.halfday,";
425 $sql .= " cp.statut as status,";
426 $sql .= " cp.fk_validator,";
427 $sql .= " cp.date_valid,";
428 $sql .= " cp.fk_user_valid,";
429 $sql .= " cp.date_approval,";
430 $sql .= " cp.fk_user_approve,";
431 $sql .= " cp.date_refuse,";
432 $sql .= " cp.fk_user_refuse,";
433 $sql .= " cp.date_cancel,";
434 $sql .= " cp.fk_user_cancel,";
435 $sql .= " cp.detail_refuse,";
436 $sql .= " cp.note_private,";
437 $sql .= " cp.note_public,";
438 $sql .= " cp.fk_user_create,";
439 $sql .= " cp.fk_type,";
440 $sql .= " cp.entity";
441 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp";
442 if ($id > 0) {
443 $sql .= " WHERE cp.rowid = ".((int) $id);
444 } else {
445 $sql .= " WHERE cp.ref = '".$this->db->escape($ref)."'";
446 }
447
448 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
449 $resql = $this->db->query($sql);
450 if ($resql) {
451 if ($this->db->num_rows($resql)) {
452 $obj = $this->db->fetch_object($resql);
453
454 $this->id = $obj->rowid;
455 $this->ref = ($obj->ref ? $obj->ref : $obj->rowid);
456 $this->fk_user = $obj->fk_user;
457 $this->date_create = $this->db->jdate($obj->date_create);
458 $this->description = $obj->description;
459 $this->date_debut = $this->db->jdate($obj->date_debut);
460 $this->date_fin = $this->db->jdate($obj->date_fin);
461 $this->date_debut_gmt = $this->db->jdate($obj->date_debut, 1);
462 $this->date_fin_gmt = $this->db->jdate($obj->date_fin, 1);
463 $this->halfday = $obj->halfday;
464 $this->status = $obj->status;
465 $this->statut = $obj->status; // deprecated
466 $this->fk_validator = $obj->fk_validator;
467 $this->date_valid = $this->db->jdate($obj->date_valid);
468 $this->fk_user_valid = $obj->fk_user_valid;
469 $this->user_validation_id = $obj->fk_user_valid;
470 $this->date_approval = $this->db->jdate($obj->date_approval);
471 $this->fk_user_approve = $obj->fk_user_approve;
472 $this->date_refuse = $this->db->jdate($obj->date_refuse);
473 $this->fk_user_refuse = $obj->fk_user_refuse;
474 $this->date_cancel = $this->db->jdate($obj->date_cancel);
475 $this->fk_user_cancel = $obj->fk_user_cancel;
476 $this->detail_refuse = $obj->detail_refuse;
477 $this->note_private = $obj->note_private;
478 $this->note_public = $obj->note_public;
479 $this->fk_user_create = $obj->fk_user_create;
480 $this->fk_type = $obj->fk_type;
481 $this->entity = $obj->entity;
482
483 $this->fetch_optionals();
484
485 $result = 1;
486 } else {
487 $result = 0;
488 }
489 $this->db->free($resql);
490
491 return $result;
492 } else {
493 $this->error = "Error ".$this->db->lasterror();
494 return -1;
495 }
496 }
497
506 public function fetchByUser($user_id, $order = '', $filter = '')
507 {
508 $sql = "SELECT";
509 $sql .= " cp.rowid,";
510 $sql .= " cp.ref,";
511
512 $sql .= " cp.fk_user,";
513 $sql .= " cp.fk_type,";
514 $sql .= " cp.date_create,";
515 $sql .= " cp.description,";
516 $sql .= " cp.date_debut,";
517 $sql .= " cp.date_fin,";
518 $sql .= " cp.halfday,";
519 $sql .= " cp.statut as status,";
520 $sql .= " cp.fk_validator,";
521 $sql .= " cp.date_valid,";
522 $sql .= " cp.fk_user_valid,";
523 $sql .= " cp.date_approval,";
524 $sql .= " cp.fk_user_approve,";
525 $sql .= " cp.date_refuse,";
526 $sql .= " cp.fk_user_refuse,";
527 $sql .= " cp.date_cancel,";
528 $sql .= " cp.fk_user_cancel,";
529 $sql .= " cp.detail_refuse,";
530
531 $sql .= " uu.lastname as user_lastname,";
532 $sql .= " uu.firstname as user_firstname,";
533 $sql .= " uu.login as user_login,";
534 $sql .= " uu.statut as user_status,";
535 $sql .= " uu.photo as user_photo,";
536
537 $sql .= " ua.lastname as validator_lastname,";
538 $sql .= " ua.firstname as validator_firstname,";
539 $sql .= " ua.login as validator_login,";
540 $sql .= " ua.statut as validator_status,";
541 $sql .= " ua.photo as validator_photo";
542
543 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp, ".MAIN_DB_PREFIX."user as uu, ".MAIN_DB_PREFIX."user as ua";
544 $sql .= " WHERE cp.entity IN (".getEntity('holiday').")";
545 $sql .= " AND cp.fk_user = uu.rowid AND cp.fk_validator = ua.rowid"; // Hack pour la recherche sur le tableau
546 $sql .= " AND cp.fk_user IN (".$this->db->sanitize($user_id).")";
547
548 // Selection filter
549 if (!empty($filter)) {
550 $sql .= $filter;
551 }
552
553 // Order of display of the result
554 if (!empty($order)) {
555 $sql .= $order;
556 }
557
558 dol_syslog(get_class($this)."::fetchByUser", LOG_DEBUG);
559 $resql = $this->db->query($sql);
560
561 // If no SQL error
562 if ($resql) {
563 $i = 0;
564 $tab_result = $this->holiday;
565 $num = $this->db->num_rows($resql);
566
567 // If no registration
568 if (!$num) {
569 return 2;
570 }
571
572 // List the records and add them to the table
573 while ($i < $num) {
574 $obj = $this->db->fetch_object($resql);
575
576 $tab_result[$i]['rowid'] = $obj->rowid;
577 $tab_result[$i]['id'] = $obj->rowid;
578 $tab_result[$i]['ref'] = ($obj->ref ? $obj->ref : $obj->rowid);
579
580 $tab_result[$i]['fk_user'] = $obj->fk_user;
581 $tab_result[$i]['fk_type'] = $obj->fk_type;
582 $tab_result[$i]['date_create'] = $this->db->jdate($obj->date_create);
583 $tab_result[$i]['description'] = $obj->description;
584 $tab_result[$i]['date_debut'] = $this->db->jdate($obj->date_debut);
585 $tab_result[$i]['date_fin'] = $this->db->jdate($obj->date_fin);
586 $tab_result[$i]['date_debut_gmt'] = $this->db->jdate($obj->date_debut, 1);
587 $tab_result[$i]['date_fin_gmt'] = $this->db->jdate($obj->date_fin, 1);
588 $tab_result[$i]['halfday'] = $obj->halfday;
589 $tab_result[$i]['statut'] = $obj->status;
590 $tab_result[$i]['status'] = $obj->status;
591 $tab_result[$i]['fk_validator'] = $obj->fk_validator;
592 $tab_result[$i]['date_valid'] = $this->db->jdate($obj->date_valid);
593 $tab_result[$i]['fk_user_valid'] = $obj->fk_user_valid;
594 $tab_result[$i]['date_approval'] = $this->db->jdate($obj->date_approval);
595 $tab_result[$i]['fk_user_approve'] = $obj->fk_user_approve;
596 $tab_result[$i]['date_refuse'] = $this->db->jdate($obj->date_refuse);
597 $tab_result[$i]['fk_user_refuse'] = $obj->fk_user_refuse;
598 $tab_result[$i]['date_cancel'] = $this->db->jdate($obj->date_cancel);
599 $tab_result[$i]['fk_user_cancel'] = $obj->fk_user_cancel;
600 $tab_result[$i]['detail_refuse'] = $obj->detail_refuse;
601
602 $tab_result[$i]['user_firstname'] = $obj->user_firstname;
603 $tab_result[$i]['user_lastname'] = $obj->user_lastname;
604 $tab_result[$i]['user_login'] = $obj->user_login;
605 $tab_result[$i]['user_statut'] = $obj->user_status;
606 $tab_result[$i]['user_status'] = $obj->user_status;
607 $tab_result[$i]['user_photo'] = $obj->user_photo;
608
609 $tab_result[$i]['validator_firstname'] = $obj->validator_firstname;
610 $tab_result[$i]['validator_lastname'] = $obj->validator_lastname;
611 $tab_result[$i]['validator_login'] = $obj->validator_login;
612 $tab_result[$i]['validator_statut'] = $obj->validator_status;
613 $tab_result[$i]['validator_status'] = $obj->validator_status;
614 $tab_result[$i]['validator_photo'] = $obj->validator_photo;
615
616 $i++;
617 }
618
619 // Returns 1 with the filled array
620 $this->holiday = $tab_result;
621 return 1;
622 } else {
623 // SQL Error
624 $this->error = "Error ".$this->db->lasterror();
625 return -1;
626 }
627 }
628
636 public function fetchAll($order, $filter)
637 {
638 $sql = "SELECT";
639 $sql .= " cp.rowid,";
640 $sql .= " cp.ref,";
641 $sql .= " cp.fk_user,";
642 $sql .= " cp.fk_type,";
643 $sql .= " cp.date_create,";
644 $sql .= " cp.tms as date_modification,";
645 $sql .= " cp.description,";
646 $sql .= " cp.date_debut,";
647 $sql .= " cp.date_fin,";
648 $sql .= " cp.halfday,";
649 $sql .= " cp.statut as status,";
650 $sql .= " cp.fk_validator,";
651 $sql .= " cp.date_valid,";
652 $sql .= " cp.fk_user_valid,";
653 $sql .= " cp.date_approval,";
654 $sql .= " cp.fk_user_approve,";
655 $sql .= " cp.date_refuse,";
656 $sql .= " cp.fk_user_refuse,";
657 $sql .= " cp.date_cancel,";
658 $sql .= " cp.fk_user_cancel,";
659 $sql .= " cp.detail_refuse,";
660
661 $sql .= " uu.lastname as user_lastname,";
662 $sql .= " uu.firstname as user_firstname,";
663 $sql .= " uu.login as user_login,";
664 $sql .= " uu.statut as user_status,";
665 $sql .= " uu.photo as user_photo,";
666
667 $sql .= " ua.lastname as validator_lastname,";
668 $sql .= " ua.firstname as validator_firstname,";
669 $sql .= " ua.login as validator_login,";
670 $sql .= " ua.statut as validator_status,";
671 $sql .= " ua.photo as validator_photo";
672
673 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp, ".MAIN_DB_PREFIX."user as uu, ".MAIN_DB_PREFIX."user as ua";
674 $sql .= " WHERE cp.entity IN (".getEntity('holiday').")";
675 $sql .= " AND cp.fk_user = uu.rowid AND cp.fk_validator = ua.rowid "; // Hack pour la recherche sur le tableau
676
677 // Selection filtering
678 if (!empty($filter)) {
679 $sql .= $filter;
680 }
681
682 // order of display
683 if (!empty($order)) {
684 $sql .= $order;
685 }
686
687 dol_syslog(get_class($this)."::fetchAll", LOG_DEBUG);
688 $resql = $this->db->query($sql);
689
690 // If no SQL error
691 if ($resql) {
692 $i = 0;
693 $tab_result = $this->holiday;
694 $num = $this->db->num_rows($resql);
695
696 // If no registration
697 if (!$num) {
698 return 2;
699 }
700
701 // List the records and add them to the table
702 while ($i < $num) {
703 $obj = $this->db->fetch_object($resql);
704
705 $tab_result[$i]['rowid'] = $obj->rowid;
706 $tab_result[$i]['id'] = $obj->rowid;
707 $tab_result[$i]['ref'] = ($obj->ref ? $obj->ref : $obj->rowid);
708
709 $tab_result[$i]['fk_user'] = $obj->fk_user;
710 $tab_result[$i]['fk_type'] = $obj->fk_type;
711 $tab_result[$i]['date_create'] = $this->db->jdate($obj->date_create);
712 $tab_result[$i]['date_modification'] = $this->db->jdate($obj->date_modification);
713 $tab_result[$i]['description'] = $obj->description;
714 $tab_result[$i]['date_debut'] = $this->db->jdate($obj->date_debut);
715 $tab_result[$i]['date_fin'] = $this->db->jdate($obj->date_fin);
716 $tab_result[$i]['date_debut_gmt'] = $this->db->jdate($obj->date_debut, 1);
717 $tab_result[$i]['date_fin_gmt'] = $this->db->jdate($obj->date_fin, 1);
718 $tab_result[$i]['halfday'] = $obj->halfday;
719 $tab_result[$i]['statut'] = $obj->status;
720 $tab_result[$i]['status'] = $obj->status;
721 $tab_result[$i]['fk_validator'] = $obj->fk_validator;
722 $tab_result[$i]['date_valid'] = $this->db->jdate($obj->date_valid);
723 $tab_result[$i]['fk_user_valid'] = $obj->fk_user_valid;
724 $tab_result[$i]['date_approval'] = $this->db->jdate($obj->date_approval);
725 $tab_result[$i]['fk_user_approve'] = $obj->fk_user_approve;
726 $tab_result[$i]['date_refuse'] = $obj->date_refuse;
727 $tab_result[$i]['fk_user_refuse'] = $obj->fk_user_refuse;
728 $tab_result[$i]['date_cancel'] = $obj->date_cancel;
729 $tab_result[$i]['fk_user_cancel'] = $obj->fk_user_cancel;
730 $tab_result[$i]['detail_refuse'] = $obj->detail_refuse;
731
732 $tab_result[$i]['user_firstname'] = $obj->user_firstname;
733 $tab_result[$i]['user_lastname'] = $obj->user_lastname;
734 $tab_result[$i]['user_login'] = $obj->user_login;
735 $tab_result[$i]['user_statut'] = $obj->user_status;
736 $tab_result[$i]['user_status'] = $obj->user_status;
737 $tab_result[$i]['user_photo'] = $obj->user_photo;
738
739 $tab_result[$i]['validator_firstname'] = $obj->validator_firstname;
740 $tab_result[$i]['validator_lastname'] = $obj->validator_lastname;
741 $tab_result[$i]['validator_login'] = $obj->validator_login;
742 $tab_result[$i]['validator_statut'] = $obj->validator_status;
743 $tab_result[$i]['validator_status'] = $obj->validator_status;
744 $tab_result[$i]['validator_photo'] = $obj->validator_photo;
745
746 $i++;
747 }
748 // Returns 1 and adds the array to the variable
749 $this->holiday = $tab_result;
750 return 1;
751 } else {
752 // SQL Error
753 $this->error = "Error ".$this->db->lasterror();
754 return -1;
755 }
756 }
757
758
766 public function validate($user = null, $notrigger = 0)
767 {
768 global $conf, $langs;
769 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
770 $error = 0;
771
772 $checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type, true);
773
774 if ($checkBalance > 0) {
775 $balance = $this->getCPforUser($this->fk_user, $this->fk_type);
776
777 if ($balance < 0) {
778 $this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
779 return -1;
780 }
781 }
782
783 // Define new ref
784 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref) || $this->ref == $this->id)) {
785 $num = $this->getNextNumRef(null);
786 } else {
787 $num = $this->ref;
788 }
789 $this->newref = dol_sanitizeFileName($num);
790
791 // Update status
792 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
793 $sql .= " fk_user_valid = ".((int) $user->id).",";
794 $sql .= " date_valid = '".$this->db->idate(dol_now())."',";
795 if (!empty($this->status) && is_numeric($this->status)) {
796 $sql .= " statut = ".((int) $this->status).",";
797 } else {
798 $this->error = 'Property status must be a numeric value';
799 $error++;
800 }
801 $sql .= " ref = '".$this->db->escape($num)."'";
802 $sql .= " WHERE rowid = ".((int) $this->id);
803
804 $this->db->begin();
805
806 dol_syslog(get_class($this)."::validate", LOG_DEBUG);
807 $resql = $this->db->query($sql);
808 if (!$resql) {
809 $error++;
810 $this->errors[] = "Error ".$this->db->lasterror();
811 }
812
813 if (!$error) {
814 if (!$notrigger) {
815 // Call trigger
816 $result = $this->call_trigger('HOLIDAY_VALIDATE', $user);
817 if ($result < 0) {
818 $error++;
819 }
820 // End call triggers
821 }
822 }
823
824 if (!$error) {
825 $this->oldref = $this->ref;
826
827 // Rename directory if dir was a temporary ref
828 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
829 // Now we rename also files into index
830 $sql = 'UPDATE ' . MAIN_DB_PREFIX . "ecm_files set filename = CONCAT('" . $this->db->escape($this->newref) . "', SUBSTR(filename, " . (strlen($this->ref) + 1) . ")), filepath = 'holiday/" . $this->db->escape($this->newref) . "'";
831 $sql .= " WHERE filename LIKE '" . $this->db->escape($this->ref) . "%' AND filepath = 'holiday/" . $this->db->escape($this->ref) . "' and entity = " . ((int) $conf->entity);
832 $resql = $this->db->query($sql);
833 if (!$resql) {
834 $error++;
835 $this->error = $this->db->lasterror();
836 }
837 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'holiday/".$this->db->escape($this->newref)."'";
838 $sql .= " WHERE filepath = 'holiday/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
839 $resql = $this->db->query($sql);
840 if (!$resql) {
841 $error++;
842 $this->error = $this->db->lasterror();
843 }
844
845 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
846 $oldref = dol_sanitizeFileName($this->ref);
847 $newref = dol_sanitizeFileName($num);
848 $dirsource = $conf->holiday->multidir_output[$this->entity] . '/' . $oldref;
849 $dirdest = $conf->holiday->multidir_output[$this->entity] . '/' . $newref;
850 if (!$error && file_exists($dirsource)) {
851 dol_syslog(get_class($this) . "::validate rename dir " . $dirsource . " into " . $dirdest);
852 if (@rename($dirsource, $dirdest)) {
853 dol_syslog("Rename ok");
854 // Rename docs starting with $oldref with $newref
855 $listoffiles = dol_dir_list($dirdest, 'files', 1, '^' . preg_quote($oldref, '/'));
856 foreach ($listoffiles as $fileentry) {
857 $dirsource = $fileentry['name'];
858 $dirdest = preg_replace('/^' . preg_quote($oldref, '/') . '/', $newref, $dirsource);
859 $dirsource = $fileentry['path'] . '/' . $dirsource;
860 $dirdest = $fileentry['path'] . '/' . $dirdest;
861 @rename($dirsource, $dirdest);
862 }
863 }
864 }
865 }
866 }
867
868
869 // Commit or rollback
870 if ($error) {
871 foreach ($this->errors as $errmsg) {
872 dol_syslog(get_class($this)."::validate ".$errmsg, LOG_ERR);
873 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
874 }
875 $this->db->rollback();
876 return -1 * $error;
877 } else {
878 $this->db->commit();
879 return 1;
880 }
881 }
882
883
891 public function approve($user = null, $notrigger = 0)
892 {
893 $error = 0;
894
895 $checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type, true);
896
897 if ($checkBalance > 0) {
898 $balance = $this->getCPforUser($this->fk_user, $this->fk_type);
899
900 if ($balance < 0) {
901 $this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
902 return -1;
903 }
904 }
905
906 // Update request
907 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
908 $sql .= " description= '".$this->db->escape($this->description)."',";
909 if (!empty($this->date_debut)) {
910 $sql .= " date_debut = '".$this->db->idate($this->date_debut)."',";
911 } else {
912 $error++;
913 }
914 if (!empty($this->date_fin)) {
915 $sql .= " date_fin = '".$this->db->idate($this->date_fin)."',";
916 } else {
917 $error++;
918 }
919 $sql .= " halfday = ".((int) $this->halfday).",";
920 if (!empty($this->status) && is_numeric($this->status)) {
921 $sql .= " statut = ".((int) $this->status).",";
922 } else {
923 $error++;
924 }
925 if (!empty($this->fk_validator)) {
926 $sql .= " fk_validator = ".((int) $this->fk_validator).",";
927 } else {
928 $error++;
929 }
930 if (!empty($this->date_valid)) {
931 $sql .= " date_valid = '".$this->db->idate($this->date_valid)."',";
932 } else {
933 $sql .= " date_valid = NULL,";
934 }
935 if (!empty($this->fk_user_valid)) {
936 $sql .= " fk_user_valid = ".((int) $this->fk_user_valid).",";
937 } else {
938 $sql .= " fk_user_valid = NULL,";
939 }
940 if (!empty($this->date_approval)) {
941 $sql .= " date_approval = '".$this->db->idate($this->date_approval)."',";
942 } else {
943 $sql .= " date_approval = NULL,";
944 }
945 if (!empty($this->fk_user_approve)) {
946 $sql .= " fk_user_approve = ".((int) $this->fk_user_approve).",";
947 } else {
948 $sql .= " fk_user_approve = NULL,";
949 }
950 if (!empty($this->date_refuse)) {
951 $sql .= " date_refuse = '".$this->db->idate($this->date_refuse)."',";
952 } else {
953 $sql .= " date_refuse = NULL,";
954 }
955 if (!empty($this->fk_user_refuse)) {
956 $sql .= " fk_user_refuse = ".((int) $this->fk_user_refuse).",";
957 } else {
958 $sql .= " fk_user_refuse = NULL,";
959 }
960 if (!empty($this->date_cancel)) {
961 $sql .= " date_cancel = '".$this->db->idate($this->date_cancel)."',";
962 } else {
963 $sql .= " date_cancel = NULL,";
964 }
965 if (!empty($this->fk_user_cancel)) {
966 $sql .= " fk_user_cancel = ".((int) $this->fk_user_cancel).",";
967 } else {
968 $sql .= " fk_user_cancel = NULL,";
969 }
970 if (!empty($this->detail_refuse)) {
971 $sql .= " detail_refuse = '".$this->db->escape($this->detail_refuse)."'";
972 } else {
973 $sql .= " detail_refuse = NULL";
974 }
975 $sql .= " WHERE rowid = ".((int) $this->id);
976
977 $this->db->begin();
978
979 dol_syslog(get_class($this)."::approve", LOG_DEBUG);
980 $resql = $this->db->query($sql);
981 if (!$resql) {
982 $error++;
983 $this->errors[] = "Error ".$this->db->lasterror();
984 }
985
986 if (!$error) {
987 if (!$notrigger) {
988 // Call trigger
989 $result = $this->call_trigger('HOLIDAY_APPROVE', $user);
990 if ($result < 0) {
991 $error++;
992 }
993 // End call triggers
994 }
995 }
996
997 // Commit or rollback
998 if ($error) {
999 foreach ($this->errors as $errmsg) {
1000 dol_syslog(get_class($this)."::approve ".$errmsg, LOG_ERR);
1001 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1002 }
1003 $this->db->rollback();
1004 return -1 * $error;
1005 } else {
1006 $this->db->commit();
1007 return 1;
1008 }
1009 }
1010
1018 public function update($user = null, $notrigger = 0)
1019 {
1020 global $conf, $langs;
1021 $error = 0;
1022
1023 $checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type, true);
1024
1025 if ($checkBalance > 0 && $this->status != self::STATUS_DRAFT) {
1026 $balance = $this->getCPforUser($this->fk_user, $this->fk_type);
1027
1028 if ($balance < 0) {
1029 $this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
1030 return -1;
1031 }
1032 }
1033
1034 // Update request
1035 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
1036
1037 $sql .= " description= '".$this->db->escape($this->description)."',";
1038
1039 if (!empty($this->date_debut)) {
1040 $sql .= " date_debut = '".$this->db->idate($this->date_debut)."',";
1041 } else {
1042 $error++;
1043 }
1044 if (!empty($this->date_fin)) {
1045 $sql .= " date_fin = '".$this->db->idate($this->date_fin)."',";
1046 } else {
1047 $error++;
1048 }
1049 $sql .= " halfday = ".$this->halfday.",";
1050 if (!empty($this->status) && is_numeric($this->status)) {
1051 $sql .= " statut = ".$this->status.",";
1052 } else {
1053 $error++;
1054 }
1055 if (!empty($this->fk_validator)) {
1056 $sql .= " fk_validator = '".$this->db->escape($this->fk_validator)."',";
1057 } else {
1058 $error++;
1059 }
1060 if (!empty($this->date_valid)) {
1061 $sql .= " date_valid = '".$this->db->idate($this->date_valid)."',";
1062 } else {
1063 $sql .= " date_valid = NULL,";
1064 }
1065 if (!empty($this->fk_user_valid)) {
1066 $sql .= " fk_user_valid = ".((int) $this->fk_user_valid).",";
1067 } else {
1068 $sql .= " fk_user_valid = NULL,";
1069 }
1070 if (!empty($this->date_approval)) {
1071 $sql .= " date_approval = '".$this->db->idate($this->date_approval)."',";
1072 } else {
1073 $sql .= " date_approval = NULL,";
1074 }
1075 if (!empty($this->fk_user_approve)) {
1076 $sql .= " fk_user_approve = ".((int) $this->fk_user_approve).",";
1077 } else {
1078 $sql .= " fk_user_approve = NULL,";
1079 }
1080 if (!empty($this->date_refuse)) {
1081 $sql .= " date_refuse = '".$this->db->idate($this->date_refuse)."',";
1082 } else {
1083 $sql .= " date_refuse = NULL,";
1084 }
1085 if (!empty($this->fk_user_refuse)) {
1086 $sql .= " fk_user_refuse = ".((int) $this->fk_user_refuse).",";
1087 } else {
1088 $sql .= " fk_user_refuse = NULL,";
1089 }
1090 if (!empty($this->date_cancel)) {
1091 $sql .= " date_cancel = '".$this->db->idate($this->date_cancel)."',";
1092 } else {
1093 $sql .= " date_cancel = NULL,";
1094 }
1095 if (!empty($this->fk_user_cancel)) {
1096 $sql .= " fk_user_cancel = ".((int) $this->fk_user_cancel).",";
1097 } else {
1098 $sql .= " fk_user_cancel = NULL,";
1099 }
1100 if (!empty($this->detail_refuse)) {
1101 $sql .= " detail_refuse = '".$this->db->escape($this->detail_refuse)."'";
1102 } else {
1103 $sql .= " detail_refuse = NULL";
1104 }
1105
1106 $sql .= " WHERE rowid = ".((int) $this->id);
1107
1108 $this->db->begin();
1109
1110 dol_syslog(get_class($this)."::update", LOG_DEBUG);
1111 $resql = $this->db->query($sql);
1112 if (!$resql) {
1113 $error++;
1114 $this->errors[] = "Error ".$this->db->lasterror();
1115 }
1116
1117 if (!$error) {
1118 if (!$notrigger) {
1119 // Call trigger
1120 $result = $this->call_trigger('HOLIDAY_MODIFY', $user);
1121 if ($result < 0) {
1122 $error++;
1123 }
1124 // End call triggers
1125 }
1126 }
1127
1128 // Commit or rollback
1129 if ($error) {
1130 foreach ($this->errors as $errmsg) {
1131 dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
1132 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1133 }
1134 $this->db->rollback();
1135 return -1 * $error;
1136 } else {
1137 $this->db->commit();
1138 return 1;
1139 }
1140 }
1141
1142
1150 public function delete($user, $notrigger = 0)
1151 {
1152 global $conf, $langs;
1153 $error = 0;
1154
1155 $sql = "DELETE FROM ".MAIN_DB_PREFIX."holiday";
1156 $sql .= " WHERE rowid=".((int) $this->id);
1157
1158 $this->db->begin();
1159
1160 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1161 $resql = $this->db->query($sql);
1162 if (!$resql) {
1163 $error++;
1164 $this->errors[] = "Error ".$this->db->lasterror();
1165 }
1166
1167 if (!$error) {
1168 if (!$notrigger) {
1169 // Call trigger
1170 $result = $this->call_trigger('HOLIDAY_DELETE', $user);
1171 if ($result < 0) {
1172 $error++;
1173 }
1174 // End call triggers
1175 }
1176 }
1177
1178 // Commit or rollback
1179 if ($error) {
1180 foreach ($this->errors as $errmsg) {
1181 dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
1182 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1183 }
1184 $this->db->rollback();
1185 return -1 * $error;
1186 } else {
1187 $this->db->commit();
1188 return 1;
1189 }
1190 }
1191
1205 public function verifDateHolidayCP($fk_user, $dateStart, $dateEnd, $halfday = 0)
1206 {
1207 $this->fetchByUser($fk_user, '', '');
1208
1209 foreach ($this->holiday as $infos_CP) {
1210 if ($infos_CP['statut'] == Holiday::STATUS_CANCELED) {
1211 continue; // ignore not validated holidays
1212 }
1213 if ($infos_CP['statut'] == Holiday::STATUS_REFUSED) {
1214 continue; // ignore refused holidays
1215 }
1216 //var_dump("--");
1217 //var_dump("old: ".dol_print_date($infos_CP['date_debut'],'dayhour').' '.dol_print_date($infos_CP['date_fin'],'dayhour').' '.$infos_CP['halfday']);
1218 //var_dump("new: ".dol_print_date($dateStart,'dayhour').' '.dol_print_date($dateEnd,'dayhour').' '.$halfday);
1219
1220 if ($halfday == 0) {
1221 if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1222 return false;
1223 }
1224 if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1225 return false;
1226 }
1227 } elseif ($halfday == -1) {
1228 // new start afternoon, new end afternoon
1229 if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1230 if ($dateStart < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
1231 return false;
1232 }
1233 }
1234 if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1235 if ($dateStart < $dateEnd) {
1236 return false;
1237 }
1238 if ($dateEnd < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
1239 return false;
1240 }
1241 }
1242 } elseif ($halfday == 1) {
1243 // new start morning, new end morning
1244 if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1245 if ($dateStart < $dateEnd) {
1246 return false;
1247 }
1248 if ($dateStart > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
1249 return false;
1250 }
1251 }
1252 if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1253 if ($dateEnd > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
1254 return false;
1255 }
1256 }
1257 } elseif ($halfday == 2) {
1258 // new start afternoon, new end morning
1259 if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1260 if ($dateStart < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
1261 return false;
1262 }
1263 }
1264 if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1265 if ($dateEnd > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
1266 return false;
1267 }
1268 }
1269 } else {
1270 dol_print_error(null, 'Bad value of parameter halfday when calling function verifDateHolidayCP');
1271 }
1272 }
1273
1274 return true;
1275 }
1276
1277
1287 public function verifDateHolidayForTimestamp($fk_user, $timestamp, $status = '-1')
1288 {
1289 $isavailablemorning = true;
1290 $isavailableafternoon = true;
1291
1292 // Check into leave requests
1293 $sql = "SELECT cp.rowid, cp.date_debut as date_start, cp.date_fin as date_end, cp.halfday, cp.statut as status";
1294 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp";
1295 $sql .= " WHERE cp.entity IN (".getEntity('holiday').")";
1296 $sql .= " AND cp.fk_user = ".(int) $fk_user;
1297 $sql .= " AND cp.date_debut <= '".$this->db->idate($timestamp)."' AND cp.date_fin >= '".$this->db->idate($timestamp)."'";
1298 if ($status != '-1') {
1299 $sql .= " AND cp.statut IN (".$this->db->sanitize($status).")";
1300 }
1301
1302 $resql = $this->db->query($sql);
1303 if ($resql) {
1304 $num_rows = $this->db->num_rows($resql); // Note, we can have 2 records if on is morning and the other one is afternoon
1305 if ($num_rows > 0) {
1306 $arrayofrecord = array();
1307 $i = 0;
1308 while ($i < $num_rows) {
1309 $obj = $this->db->fetch_object($resql);
1310
1311 // Note: $obj->halfday is 0:Full days, 2:Start afternoon end morning, -1:Start afternoon, 1:End morning
1312 $arrayofrecord[$obj->rowid] = array('date_start' => $this->db->jdate($obj->date_start), 'date_end' => $this->db->jdate($obj->date_end), 'halfday' => $obj->halfday, 'status' => $obj->status);
1313 $i++;
1314 }
1315
1316 // We found a record, user is on holiday by default, so is not available is true.
1317 $isavailablemorning = true;
1318 foreach ($arrayofrecord as $record) {
1319 if ($timestamp == $record['date_start'] && $record['halfday'] == 2) {
1320 continue;
1321 }
1322 if ($timestamp == $record['date_start'] && $record['halfday'] == -1) {
1323 continue;
1324 }
1325 $isavailablemorning = false;
1326 break;
1327 }
1328 $isavailableafternoon = true;
1329 foreach ($arrayofrecord as $record) {
1330 if ($timestamp == $record['date_end'] && $record['halfday'] == 2) {
1331 continue;
1332 }
1333 if ($timestamp == $record['date_end'] && $record['halfday'] == 1) {
1334 continue;
1335 }
1336 $isavailableafternoon = false;
1337 break;
1338 }
1339 }
1340 } else {
1341 dol_print_error($this->db);
1342 }
1343
1344 $result = array('morning' => $isavailablemorning, 'afternoon' => $isavailableafternoon);
1345 if (!$isavailablemorning) {
1346 $result['morning_reason'] = 'leave_request';
1347 }
1348 if (!$isavailableafternoon) {
1349 $result['afternoon_reason'] = 'leave_request';
1350 }
1351 return $result;
1352 }
1353
1360 public function getTooltipContentArray($params)
1361 {
1362 global $langs;
1363
1364 $langs->load('holiday');
1365 $nofetch = !empty($params['nofetch']);
1366
1367 $datas = array();
1368 $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Holiday").'</u>';
1369 if (isset($this->status)) {
1370 $datas['picto'] .= ' '.$this->getLibStatut(5);
1371 }
1372 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
1373 // show type for this record only in ajax to not overload lists
1374 if (!$nofetch && !empty($this->fk_type)) {
1375 $typeleaves = $this->getTypes(1, -1);
1376 if (empty($typeleaves[$this->fk_type])) {
1377 $labeltoshow = $langs->trans("TypeWasDisabledOrRemoved", $this->fk_type);
1378 } else {
1379 $labeltoshow = (($typeleaves[$this->fk_type]['code'] && $langs->trans($typeleaves[$this->fk_type]['code']) != $typeleaves[$this->fk_type]['code']) ? $langs->trans($typeleaves[$this->fk_type]['code']) : $typeleaves[$this->fk_type]['label']);
1380 }
1381 $datas['type'] = '<br><b>'.$langs->trans("Type") . ':</b> ' . $labeltoshow;
1382 }
1383 if (isset($this->halfday) && !empty($this->date_debut) && !empty($this->date_fin)) {
1384 $listhalfday = array(
1385 'morning' => $langs->trans("Morning"),
1386 "afternoon" => $langs->trans("Afternoon")
1387 );
1388 $starthalfday = ($this->halfday == -1 || $this->halfday == 2) ? 'afternoon' : 'morning';
1389 $endhalfday = ($this->halfday == 1 || $this->halfday == 2) ? 'morning' : 'afternoon';
1390 $datas['date_start'] = '<br><b>'.$langs->trans('DateDebCP') . '</b>: '. dol_print_date($this->date_debut, 'day') . '&nbsp;&nbsp;<span class="opacitymedium">'.$langs->trans($listhalfday[$starthalfday]).'</span>';
1391 $datas['date_end'] = '<br><b>'.$langs->trans('DateFinCP') . '</b>: '. dol_print_date($this->date_fin, 'day') . '&nbsp;&nbsp;<span class="opacitymedium">'.$langs->trans($listhalfday[$endhalfday]).'</span>';
1392 }
1393
1394
1395 return $datas;
1396 }
1397
1407 public function getNomUrl($withpicto = 0, $save_lastsearch_value = -1, $notooltip = 0, $morecss = '')
1408 {
1409 global $conf, $langs, $hookmanager;
1410
1411 if (!empty($conf->dol_no_mouse_hover)) {
1412 $notooltip = 1; // Force disable tooltips
1413 }
1414
1415 $result = '';
1416 $params = [
1417 'id' => $this->id,
1418 'objecttype' => $this->element,
1419 'nofetch' => 1,
1420 ];
1421 $classfortooltip = 'classfortooltip';
1422 $dataparams = '';
1423 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1424 $classfortooltip = 'classforajaxtooltip';
1425 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1426 $label = '';
1427 } else {
1428 $label = implode($this->getTooltipContentArray($params));
1429 }
1430
1431 $url = DOL_URL_ROOT.'/holiday/card.php?id='.$this->id;
1432
1433 //if ($option != 'nolink')
1434 //{
1435 // Add param to save lastsearch_values or not
1436 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1437 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1438 $add_save_lastsearch_values = 1;
1439 }
1440 if ($add_save_lastsearch_values) {
1441 $url .= '&save_lastsearch_values=1';
1442 }
1443 //}
1444
1445 $linkclose = '';
1446 if (empty($notooltip)) {
1447 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1448 $label = $langs->trans("ShowMyObject");
1449 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
1450 }
1451 $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
1452 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
1453 } else {
1454 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1455 }
1456
1457 $linkstart = '<a href="'.$url.'"';
1458 $linkstart .= $linkclose.'>';
1459 $linkend = '</a>';
1460
1461 $result .= $linkstart;
1462
1463 if ($withpicto) {
1464 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
1465 }
1466 if ($withpicto != 2) {
1467 $result .= $this->ref;
1468 }
1469 $result .= $linkend;
1470
1471 global $action;
1472 $hookmanager->initHooks(array($this->element . 'dao'));
1473 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1474 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1475 if ($reshook > 0) {
1476 $result = $hookmanager->resPrint;
1477 } else {
1478 $result .= $hookmanager->resPrint;
1479 }
1480 return $result;
1481 }
1482
1483
1490 public function getLibStatut($mode = 0)
1491 {
1492 return $this->LibStatut($this->status, $mode, $this->date_debut);
1493 }
1494
1495 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1504 public function LibStatut($status, $mode = 0, $startdate = '')
1505 {
1506 // phpcs:enable
1507 global $langs;
1508
1509 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
1510 global $langs;
1511 //$langs->load("mymodule");
1512 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP');
1513 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP');
1514 $this->labelStatus[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP');
1515 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP');
1516 $this->labelStatus[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP');
1517 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP');
1518 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP');
1519 $this->labelStatusShort[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP');
1520 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP');
1521 $this->labelStatusShort[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP');
1522 }
1523
1524 $params = array();
1525 $statusType = 'status6';
1526 if (!empty($startdate) && $startdate >= dol_now()) { // If not yet passed, we use a green "in live" color
1527 $statusType = 'status4';
1528 $params = array('tooltip' => $this->labelStatus[$status].' - '.$langs->trans("Forthcoming"));
1529 }
1530 if ($status == self::STATUS_DRAFT) {
1531 $statusType = 'status0';
1532 }
1533 if ($status == self::STATUS_VALIDATED) {
1534 $statusType = 'status1';
1535 }
1536 if ($status == self::STATUS_CANCELED) {
1537 $statusType = 'status9';
1538 }
1539 if ($status == self::STATUS_REFUSED) {
1540 $statusType = 'status9';
1541 }
1542
1543 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode, '', $params);
1544 }
1545
1546
1555 public function selectStatutCP($selected = 0, $htmlname = 'select_statut', $morecss = 'minwidth125')
1556 {
1557 global $langs;
1558
1559 // List of status label
1560 $name = array('DraftCP', 'ToReviewCP', 'ApprovedCP', 'CancelCP', 'RefuseCP');
1561 $nb = count($name) + 1;
1562
1563 // Select HTML
1564 $out = '<select name="'.$htmlname.'" id="'.$htmlname.'" class="flat'.($morecss ? ' '.$morecss : '').'">'."\n";
1565 $out .= '<option value="-1">&nbsp;</option>'."\n";
1566
1567 // Loop on status
1568 for ($i = 1; $i < $nb; $i++) {
1569 if ($i == $selected) {
1570 $out .= '<option value="'.$i.'" selected>'.$langs->trans($name[$i - 1]).'</option>'."\n";
1571 } else {
1572 $out .= '<option value="'.$i.'">'.$langs->trans($name[$i - 1]).'</option>'."\n";
1573 }
1574 }
1575
1576 $out .= "</select>\n";
1577
1578 $showempty = 0;
1579 $out .= ajax_combobox($htmlname, array(), 0, 0, 'resolve', ($showempty < 0 ? (string) $showempty : '-1'), $morecss);
1580
1581 return $out;
1582 }
1583
1591 public function updateConfCP($name, $value)
1592 {
1593 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
1594 $sql .= " value = '".$this->db->escape($value)."'";
1595 $sql .= " WHERE name = '".$this->db->escape($name)."'";
1596
1597 dol_syslog(get_class($this).'::updateConfCP name='.$name, LOG_DEBUG);
1598 $result = $this->db->query($sql);
1599 if ($result) {
1600 return true;
1601 }
1602
1603 return false;
1604 }
1605
1614 public function getConfCP($name, $createifnotfound = '')
1615 {
1616 $sql = "SELECT value";
1617 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_config";
1618 $sql .= " WHERE name = '".$this->db->escape($name)."'";
1619
1620 dol_syslog(get_class($this).'::getConfCP name='.$name.' createifnotfound='.$createifnotfound, LOG_DEBUG);
1621 $result = $this->db->query($sql);
1622
1623 if ($result) {
1624 $obj = $this->db->fetch_object($result);
1625 // Return value
1626 if (empty($obj)) {
1627 if ($createifnotfound) {
1628 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_config(name, value)";
1629 $sql .= " VALUES('".$this->db->escape($name)."', '".$this->db->escape($createifnotfound)."')";
1630 $result = $this->db->query($sql);
1631 if ($result) {
1632 return $createifnotfound;
1633 } else {
1634 $this->error = $this->db->lasterror();
1635 return -2;
1636 }
1637 } else {
1638 return '';
1639 }
1640 } else {
1641 return $obj->value;
1642 }
1643 } else {
1644 // Erreur SQL
1645 $this->error = $this->db->lasterror();
1646 return -1;
1647 }
1648 }
1649
1658 public function updateSoldeCP($userID = 0, $nbHoliday = 0, $fk_type = 0)
1659 {
1660 global $user, $langs;
1661
1662 $error = 0;
1663
1664 if (empty($userID) && empty($nbHoliday) && empty($fk_type)) {
1665 $langs->load("holiday");
1666
1667 // Si mise à jour pour tout le monde en début de mois
1668 $now = dol_now();
1669
1670 $month = date('m', $now);
1671 $newdateforlastupdate = dol_print_date($now, '%Y%m%d%H%M%S');
1672
1673 // Get month of last update
1674 $lastUpdate = $this->getConfCP('lastUpdate', $newdateforlastupdate);
1675 $monthLastUpdate = $lastUpdate[4].$lastUpdate[5];
1676 //print 'month: '.$month.' lastUpdate:'.$lastUpdate.' monthLastUpdate:'.$monthLastUpdate;exit;
1677
1678 // If month date is not same than the one of last update (the one we saved in database), then we update the timestamp and balance of each open user.
1679 if ($month != $monthLastUpdate) {
1680 $this->db->begin();
1681
1682 $users = $this->fetchUsers(false, false, ' AND u.statut > 0');
1683 $nbUser = count($users);
1684
1685 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
1686 $sql .= " value = '".$this->db->escape($newdateforlastupdate)."'";
1687 $sql .= " WHERE name = 'lastUpdate'";
1688 $result = $this->db->query($sql);
1689
1690 $typeleaves = $this->getTypes(1, 1);
1691
1692 // Update each user counter
1693 foreach ($users as $userCounter) {
1694 $nbDaysToAdd = (isset($typeleaves[$userCounter['type']]['newbymonth']) ? $typeleaves[$userCounter['type']]['newbymonth'] : 0);
1695 if (empty($nbDaysToAdd)) {
1696 continue;
1697 }
1698
1699 dol_syslog("We update leave type id ".$userCounter['type']." for user id ".$userCounter['rowid'], LOG_DEBUG);
1700
1701 $nowHoliday = (float) $userCounter['nb_holiday'];
1702 $newSolde = $nowHoliday + $nbDaysToAdd;
1703
1704 // We add a log for each user
1705 $this->addLogCP($user->id, $userCounter['rowid'], $langs->trans('HolidaysMonthlyUpdate'), $newSolde, $userCounter['type']);
1706
1707 $result = $this->updateSoldeCP($userCounter['rowid'], $newSolde, $userCounter['type']);
1708
1709 if ($result < 0) {
1710 $error++;
1711 break;
1712 }
1713 }
1714
1715 if (!$error) {
1716 $this->db->commit();
1717 return 1;
1718 } else {
1719 $this->db->rollback();
1720 return -1;
1721 }
1722 }
1723
1724 return 0;
1725 } else {
1726 // Mise à jour pour un utilisateur
1727 $nbHoliday = price2num($nbHoliday, 5);
1728
1729 $sql = "SELECT nb_holiday FROM ".MAIN_DB_PREFIX."holiday_users";
1730 $sql .= " WHERE fk_user = ".(int) $userID." AND fk_type = ".(int) $fk_type;
1731 $resql = $this->db->query($sql);
1732 if ($resql) {
1733 $num = $this->db->num_rows($resql);
1734
1735 if ($num > 0) {
1736 // Update for user
1737 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_users SET";
1738 $sql .= " nb_holiday = ".((float) $nbHoliday);
1739 $sql .= " WHERE fk_user = ".(int) $userID." AND fk_type = ".(int) $fk_type;
1740 $result = $this->db->query($sql);
1741 if (!$result) {
1742 $error++;
1743 $this->errors[] = $this->db->lasterror();
1744 }
1745 } else {
1746 // Insert for user
1747 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users(nb_holiday, fk_user, fk_type) VALUES (";
1748 $sql .= ((float) $nbHoliday);
1749 $sql .= ", ".(int) $userID.", ".(int) $fk_type.")";
1750 $result = $this->db->query($sql);
1751 if (!$result) {
1752 $error++;
1753 $this->errors[] = $this->db->lasterror();
1754 }
1755 }
1756 } else {
1757 $this->errors[] = $this->db->lasterror();
1758 $error++;
1759 }
1760
1761 if (!$error) {
1762 return 1;
1763 } else {
1764 return -1;
1765 }
1766 }
1767 }
1768
1776 public function createCPusers($single = false, $userid = 0)
1777 {
1778 // do we have to add balance for all users ?
1779 if (!$single) {
1780 dol_syslog(get_class($this).'::createCPusers');
1781 $arrayofusers = $this->fetchUsers(false, true);
1782
1783 foreach ($arrayofusers as $users) {
1784 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users";
1785 $sql .= " (fk_user, nb_holiday)";
1786 $sql .= " VALUES (".((int) $users['rowid'])."', '0')";
1787
1788 $resql = $this->db->query($sql);
1789 if (!$resql) {
1790 dol_print_error($this->db);
1791 }
1792 }
1793 } else {
1794 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users";
1795 $sql .= " (fk_user, nb_holiday)";
1796 $sql .= " VALUES (".((int) $userid)."', '0')";
1797
1798 $resql = $this->db->query($sql);
1799 if (!$resql) {
1800 dol_print_error($this->db);
1801 }
1802 }
1803 }
1804
1812 public function getCPforUser($user_id, $fk_type = 0)
1813 {
1814 $sql = "SELECT nb_holiday";
1815 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users";
1816 $sql .= " WHERE fk_user = ".(int) $user_id;
1817 if ($fk_type > 0) {
1818 $sql .= " AND fk_type = ".(int) $fk_type;
1819 }
1820
1821 dol_syslog(get_class($this).'::getCPforUser user_id='.$user_id.' type_id='.$fk_type, LOG_DEBUG);
1822 $result = $this->db->query($sql);
1823 if ($result) {
1824 $obj = $this->db->fetch_object($result);
1825 //return number_format($obj->nb_holiday,2);
1826 if ($obj) {
1827 return $obj->nb_holiday;
1828 } else {
1829 return null;
1830 }
1831 } else {
1832 return null;
1833 }
1834 }
1835
1844 public function fetchUsers($stringlist = true, $type = true, $filters = '')
1845 {
1846 global $conf;
1847
1848 dol_syslog(get_class($this)."::fetchUsers", LOG_DEBUG);
1849
1850 if ($stringlist) {
1851 if ($type) {
1852 // If user of Dolibarr
1853 $sql = "SELECT";
1854 if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
1855 $sql .= " DISTINCT";
1856 }
1857 $sql .= " u.rowid";
1858 $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
1859
1860 if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
1861 $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
1862 $sql .= " WHERE ((ug.fk_user = u.rowid";
1863 $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
1864 $sql .= " OR u.entity = 0)"; // Show always superadmin
1865 } else {
1866 $sql .= " WHERE u.entity IN (".getEntity('user').")";
1867 }
1868 $sql .= " AND u.statut > 0";
1869 $sql .= " AND u.employee = 1"; // We only want employee users for holidays
1870 if ($filters) {
1871 $sql .= $filters;
1872 }
1873
1874 $resql = $this->db->query($sql);
1875
1876 // Si pas d'erreur SQL
1877 if ($resql) {
1878 $i = 0;
1879 $num = $this->db->num_rows($resql);
1880 $stringlist = '';
1881
1882 // Boucles du listage des utilisateurs
1883 while ($i < $num) {
1884 $obj = $this->db->fetch_object($resql);
1885
1886 if ($i == 0) {
1887 $stringlist .= $obj->rowid;
1888 } else {
1889 $stringlist .= ', '.$obj->rowid;
1890 }
1891
1892 $i++;
1893 }
1894 // Retoune le tableau des utilisateurs
1895 return $stringlist;
1896 } else {
1897 // Erreur SQL
1898 $this->error = "Error ".$this->db->lasterror();
1899 return -1;
1900 }
1901 } else {
1902 // We want only list of vacation balance for user ids
1903 $sql = "SELECT DISTINCT cpu.fk_user";
1904 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u";
1905 $sql .= " WHERE cpu.fk_user = u.rowid";
1906 if ($filters) {
1907 $sql .= $filters;
1908 }
1909
1910 $resql = $this->db->query($sql);
1911
1912 // Si pas d'erreur SQL
1913 if ($resql) {
1914 $i = 0;
1915 $num = $this->db->num_rows($resql);
1916 $stringlist = '';
1917
1918 // Boucles du listage des utilisateurs
1919 while ($i < $num) {
1920 $obj = $this->db->fetch_object($resql);
1921
1922 if ($i == 0) {
1923 $stringlist .= $obj->fk_user;
1924 } else {
1925 $stringlist .= ', '.$obj->fk_user;
1926 }
1927
1928 $i++;
1929 }
1930 // Retoune le tableau des utilisateurs
1931 return $stringlist;
1932 } else {
1933 // Erreur SQL
1934 $this->error = "Error ".$this->db->lasterror();
1935 return -1;
1936 }
1937 }
1938 } else {
1939 // Si faux donc return array
1940 // List for Dolibarr users
1941 if ($type) {
1942 // If we need users of Dolibarr
1943 $sql = "SELECT";
1944 if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
1945 $sql .= " DISTINCT";
1946 }
1947 $sql .= " u.rowid, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut as status, u.fk_user";
1948 $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
1949
1950 if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
1951 $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
1952 $sql .= " WHERE ((ug.fk_user = u.rowid";
1953 $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
1954 $sql .= " OR u.entity = 0)"; // Show always superadmin
1955 } else {
1956 $sql .= " WHERE u.entity IN (".getEntity('user').")";
1957 }
1958
1959 $sql .= " AND u.statut > 0";
1960 $sql .= " AND u.employee = 1"; // We only want employee users for holidays
1961 if ($filters) {
1962 $sql .= $filters;
1963 }
1964
1965 $resql = $this->db->query($sql);
1966
1967 // Si pas d'erreur SQL
1968 if ($resql) {
1969 $i = 0;
1970 $tab_result = $this->holiday;
1971 $num = $this->db->num_rows($resql);
1972
1973 // Boucles du listage des utilisateurs
1974 while ($i < $num) {
1975 $obj = $this->db->fetch_object($resql);
1976
1977 $tab_result[$i]['rowid'] = (int) $obj->rowid; // rowid of user
1978 $tab_result[$i]['id'] = (int) $obj->rowid; // id of user
1979 $tab_result[$i]['name'] = $obj->lastname; // deprecated
1980 $tab_result[$i]['lastname'] = $obj->lastname;
1981 $tab_result[$i]['firstname'] = $obj->firstname;
1982 $tab_result[$i]['gender'] = $obj->gender;
1983 $tab_result[$i]['status'] = (int) $obj->status;
1984 $tab_result[$i]['employee'] = $obj->employee;
1985 $tab_result[$i]['photo'] = $obj->photo;
1986 $tab_result[$i]['fk_user'] = (int) $obj->fk_user; // rowid of manager
1987 //$tab_result[$i]['type'] = $obj->type;
1988 //$tab_result[$i]['nb_holiday'] = $obj->nb_holiday;
1989
1990 $i++;
1991 }
1992 // Retoune le tableau des utilisateurs
1993 return $tab_result;
1994 } else {
1995 // Erreur SQL
1996 $this->errors[] = "Error ".$this->db->lasterror();
1997 return -1;
1998 }
1999 } else {
2000 // List of vacation balance users
2001 $sql = "SELECT cpu.fk_type, cpu.nb_holiday, u.rowid, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut as status, u.fk_user";
2002 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u";
2003 $sql .= " WHERE cpu.fk_user = u.rowid";
2004 if ($filters) {
2005 $sql .= $filters;
2006 }
2007
2008 $resql = $this->db->query($sql);
2009
2010 // Si pas d'erreur SQL
2011 if ($resql) {
2012 $i = 0;
2013 $tab_result = $this->holiday;
2014 $num = $this->db->num_rows($resql);
2015
2016 // Boucles du listage des utilisateurs
2017 while ($i < $num) {
2018 $obj = $this->db->fetch_object($resql);
2019
2020 $tab_result[$i]['rowid'] = $obj->rowid; // rowid of user
2021 $tab_result[$i]['id'] = $obj->rowid; // id of user
2022 $tab_result[$i]['name'] = $obj->lastname; // deprecated
2023 $tab_result[$i]['lastname'] = $obj->lastname;
2024 $tab_result[$i]['firstname'] = $obj->firstname;
2025 $tab_result[$i]['gender'] = $obj->gender;
2026 $tab_result[$i]['status'] = $obj->status;
2027 $tab_result[$i]['employee'] = $obj->employee;
2028 $tab_result[$i]['photo'] = $obj->photo;
2029 $tab_result[$i]['fk_user'] = $obj->fk_user; // rowid of manager
2030
2031 $tab_result[$i]['type'] = $obj->fk_type;
2032 $tab_result[$i]['nb_holiday'] = $obj->nb_holiday;
2033
2034 $i++;
2035 }
2036 // Retoune le tableau des utilisateurs
2037 return $tab_result;
2038 } else {
2039 // Erreur SQL
2040 $this->error = "Error ".$this->db->lasterror();
2041 return -1;
2042 }
2043 }
2044 }
2045 }
2046
2047
2048 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2056 {
2057 // phpcs:enable
2058 $users_validator = array();
2059
2060 $sql = "SELECT DISTINCT ur.fk_user";
2061 $sql .= " FROM ".MAIN_DB_PREFIX."user_rights as ur, ".MAIN_DB_PREFIX."rights_def as rd";
2062 $sql .= " WHERE ur.fk_id = rd.id and rd.module = 'holiday' AND rd.perms = 'approve'"; // Permission 'Approve';
2063 $sql .= "UNION";
2064 $sql .= " SELECT DISTINCT ugu.fk_user";
2065 $sql .= " FROM ".MAIN_DB_PREFIX."usergroup_user as ugu, ".MAIN_DB_PREFIX."usergroup_rights as ur, ".MAIN_DB_PREFIX."rights_def as rd";
2066 $sql .= " WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'holiday' AND rd.perms = 'approve'"; // Permission 'Approve';
2067 //print $sql;
2068
2069 dol_syslog(get_class($this)."::fetch_users_approver_holiday sql=".$sql);
2070 $result = $this->db->query($sql);
2071 if ($result) {
2072 $num_rows = $this->db->num_rows($result);
2073 $i = 0;
2074 while ($i < $num_rows) {
2075 $objp = $this->db->fetch_object($result);
2076 array_push($users_validator, $objp->fk_user);
2077 $i++;
2078 }
2079 return $users_validator;
2080 } else {
2081 $this->error = $this->db->lasterror();
2082 dol_syslog(get_class($this)."::fetch_users_approver_holiday Error ".$this->error, LOG_ERR);
2083 return -1;
2084 }
2085 }
2086
2087
2093 public function countActiveUsers()
2094 {
2095 $sql = "SELECT count(u.rowid) as compteur";
2096 $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
2097 $sql .= " WHERE u.statut > 0";
2098
2099 $result = $this->db->query($sql);
2100 $object = $this->db->fetch_object($result);
2101
2102 return $object->compteur;
2103 }
2110 {
2111 $sql = "SELECT count(u.rowid) as compteur";
2112 $sql .= " FROM ".MAIN_DB_PREFIX."user as u LEFT OUTER JOIN ".MAIN_DB_PREFIX."holiday_users hu ON (hu.fk_user=u.rowid)";
2113 $sql .= " WHERE u.statut > 0 AND hu.fk_user IS NULL";
2114
2115 $result = $this->db->query($sql);
2116 $object = $this->db->fetch_object($result);
2117
2118 return $object->compteur;
2119 }
2120
2128 public function verifNbUsers($userDolibarrWithoutCP, $userCP)
2129 {
2130 if (empty($userCP)) {
2131 $userCP = 0;
2132 }
2133 dol_syslog(get_class($this).'::verifNbUsers userDolibarr='.$userDolibarrWithoutCP.' userCP='.$userCP);
2134 return 1;
2135 }
2136
2137
2148 public function addLogCP($fk_user_action, $fk_user_update, $label, $new_solde, $fk_type)
2149 {
2150 global $conf, $langs;
2151
2152 $error = 0;
2153
2154 $prev_solde = price2num($this->getCPforUser($fk_user_update, $fk_type), 5);
2155 $new_solde = price2num($new_solde, 5);
2156 //print "$prev_solde == $new_solde";
2157
2158 if ($prev_solde == $new_solde) {
2159 return 0;
2160 }
2161
2162 $this->db->begin();
2163
2164 // Insert request
2165 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_logs (";
2166 $sql .= "date_action,";
2167 $sql .= "fk_user_action,";
2168 $sql .= "fk_user_update,";
2169 $sql .= "type_action,";
2170 $sql .= "prev_solde,";
2171 $sql .= "new_solde,";
2172 $sql .= "fk_type";
2173 $sql .= ") VALUES (";
2174 $sql .= " '".$this->db->idate(dol_now())."',";
2175 $sql .= " ".((int) $fk_user_action).",";
2176 $sql .= " ".((int) $fk_user_update).",";
2177 $sql .= " '".$this->db->escape($label)."',";
2178 $sql .= " ".((float) $prev_solde).",";
2179 $sql .= " ".((float) $new_solde).",";
2180 $sql .= " ".((int) $fk_type);
2181 $sql .= ")";
2182
2183 $resql = $this->db->query($sql);
2184 if (!$resql) {
2185 $error++;
2186 $this->errors[] = "Error ".$this->db->lasterror();
2187 }
2188
2189 if (!$error) {
2190 $this->optRowid = $this->db->last_insert_id(MAIN_DB_PREFIX."holiday_logs");
2191 }
2192
2193 // Commit or rollback
2194 if ($error) {
2195 foreach ($this->errors as $errmsg) {
2196 dol_syslog(get_class($this)."::addLogCP ".$errmsg, LOG_ERR);
2197 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
2198 }
2199 $this->db->rollback();
2200 return -1 * $error;
2201 } else {
2202 $this->db->commit();
2203 return $this->optRowid;
2204 }
2205 }
2206
2214 public function fetchLog($order, $filter)
2215 {
2216 $sql = "SELECT";
2217 $sql .= " cpl.rowid,";
2218 $sql .= " cpl.date_action,";
2219 $sql .= " cpl.fk_user_action,";
2220 $sql .= " cpl.fk_user_update,";
2221 $sql .= " cpl.type_action,";
2222 $sql .= " cpl.prev_solde,";
2223 $sql .= " cpl.new_solde,";
2224 $sql .= " cpl.fk_type";
2225 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_logs as cpl";
2226 $sql .= " WHERE cpl.rowid > 0"; // To avoid error with other search and criteria
2227
2228 // Filtrage de séléction
2229 if (!empty($filter)) {
2230 $sql .= " ".$filter;
2231 }
2232
2233 // Ordre d'affichage
2234 if (!empty($order)) {
2235 $sql .= " ".$order;
2236 }
2237
2238 dol_syslog(get_class($this)."::fetchLog", LOG_DEBUG);
2239 $resql = $this->db->query($sql);
2240
2241 // Si pas d'erreur SQL
2242 if ($resql) {
2243 $i = 0;
2244 $tab_result = $this->logs;
2245 $num = $this->db->num_rows($resql);
2246
2247 // Si pas d'enregistrement
2248 if (!$num) {
2249 return 2;
2250 }
2251
2252 // On liste les résultats et on les ajoutent dans le tableau
2253 while ($i < $num) {
2254 $obj = $this->db->fetch_object($resql);
2255
2256 $tab_result[$i]['rowid'] = $obj->rowid;
2257 $tab_result[$i]['id'] = $obj->rowid;
2258 $tab_result[$i]['date_action'] = $obj->date_action;
2259 $tab_result[$i]['fk_user_action'] = $obj->fk_user_action;
2260 $tab_result[$i]['fk_user_update'] = $obj->fk_user_update;
2261 $tab_result[$i]['type_action'] = $obj->type_action;
2262 $tab_result[$i]['prev_solde'] = $obj->prev_solde;
2263 $tab_result[$i]['new_solde'] = $obj->new_solde;
2264 $tab_result[$i]['fk_type'] = $obj->fk_type;
2265
2266 $i++;
2267 }
2268 // Retourne 1 et ajoute le tableau à la variable
2269 $this->logs = $tab_result;
2270 return 1;
2271 } else {
2272 // Erreur SQL
2273 $this->error = "Error ".$this->db->lasterror();
2274 return -1;
2275 }
2276 }
2277
2278
2286 public function getTypes($active = -1, $affect = -1)
2287 {
2288 global $mysoc;
2289
2290 $sql = "SELECT rowid, code, label, affect, delay, newbymonth";
2291 $sql .= " FROM ".MAIN_DB_PREFIX."c_holiday_types";
2292 $sql .= " WHERE (fk_country IS NULL OR fk_country = ".((int) $mysoc->country_id).')';
2293 $sql .= " AND entity IN (".getEntity('c_holiday_types').")";
2294 if ($active >= 0) {
2295 $sql .= " AND active = ".((int) $active);
2296 }
2297 if ($affect >= 0) {
2298 $sql .= " AND affect = ".((int) $affect);
2299 }
2300 $sql .= " ORDER BY sortorder";
2301
2302 $result = $this->db->query($sql);
2303 if ($result) {
2304 $num = $this->db->num_rows($result);
2305 if ($num) {
2306 $types = array();
2307 while ($obj = $this->db->fetch_object($result)) {
2308 $types[$obj->rowid] = array('id' => $obj->rowid, 'rowid' => $obj->rowid, 'code' => $obj->code, 'label' => $obj->label, 'affect' => $obj->affect, 'delay' => $obj->delay, 'newbymonth' => $obj->newbymonth);
2309 }
2310
2311 return $types;
2312 }
2313 } else {
2314 dol_print_error($this->db);
2315 }
2316
2317 return array();
2318 }
2319
2320
2327 public function info($id)
2328 {
2329 global $conf;
2330
2331 $sql = "SELECT f.rowid, f.statut as status,";
2332 $sql .= " f.date_create as datec,";
2333 $sql .= " f.tms as date_modification,";
2334 $sql .= " f.date_valid as datev,";
2335 $sql .= " f.date_approval as datea,";
2336 $sql .= " f.date_refuse as dater,";
2337 $sql .= " f.fk_user_create as fk_user_creation,";
2338 $sql .= " f.fk_user_modif as fk_user_modification,";
2339 $sql .= " f.fk_user_valid as fk_user_validation,";
2340 $sql .= " f.fk_user_approve as fk_user_approval_done,";
2341 $sql .= " f.fk_validator as fk_user_approval_expected,";
2342 $sql .= " f.fk_user_refuse as fk_user_refuse";
2343 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as f";
2344 $sql .= " WHERE f.rowid = ".((int) $id);
2345 $sql .= " AND f.entity = ".$conf->entity;
2346
2347 $resql = $this->db->query($sql);
2348 if ($resql) {
2349 if ($this->db->num_rows($resql)) {
2350 $obj = $this->db->fetch_object($resql);
2351
2352 $this->id = $obj->rowid;
2353
2354 $this->date_creation = $this->db->jdate($obj->datec);
2355 $this->date_modification = $this->db->jdate($obj->date_modification);
2356 $this->date_validation = $this->db->jdate($obj->datev);
2357 $this->date_approval = $this->db->jdate($obj->datea);
2358
2359 $this->user_creation_id = $obj->fk_user_creation;
2360 $this->user_validation_id = $obj->fk_user_validation;
2361 $this->user_modification_id = $obj->fk_user_modification;
2362
2363 if ($obj->status == Holiday::STATUS_APPROVED || $obj->status == Holiday::STATUS_CANCELED) {
2364 if ($obj->fk_user_approval_done) {
2365 $this->fk_user_approve = $obj->fk_user_approval_done;
2366 }
2367 }
2368 }
2369 $this->db->free($resql);
2370 } else {
2371 dol_print_error($this->db);
2372 }
2373 }
2374
2375
2383 public function initAsSpecimen()
2384 {
2385 global $user, $langs;
2386
2387 // Initialise parameters
2388 $this->id = 0;
2389 $this->specimen = 1;
2390
2391 $this->fk_user = $user->id;
2392 $this->description = 'SPECIMEN description';
2393 $this->date_debut = dol_now();
2394 $this->date_fin = dol_now() + (24 * 3600);
2395 $this->date_valid = dol_now();
2396 $this->fk_validator = $user->id;
2397 $this->halfday = 0;
2398 $this->fk_type = 1;
2400
2401 return 1;
2402 }
2403
2409 public function loadStateBoard()
2410 {
2411 global $user;
2412
2413 $this->nb = array();
2414
2415 $sql = "SELECT count(h.rowid) as nb";
2416 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
2417 $sql .= " WHERE h.statut > 1";
2418 $sql .= " AND h.entity IN (".getEntity('holiday').")";
2419 if (!$user->hasRight('expensereport', 'readall')) {
2420 $userchildids = $user->getAllChildIds(1);
2421 $sql .= " AND (h.fk_user IN (".$this->db->sanitize(implode(',', $userchildids)).")";
2422 $sql .= " OR h.fk_validator IN (".$this->db->sanitize(implode(',', $userchildids))."))";
2423 }
2424
2425 $resql = $this->db->query($sql);
2426 if ($resql) {
2427 while ($obj = $this->db->fetch_object($resql)) {
2428 $this->nb["holidays"] = $obj->nb;
2429 }
2430 $this->db->free($resql);
2431 return 1;
2432 } else {
2433 dol_print_error($this->db);
2434 $this->error = $this->db->error();
2435 return -1;
2436 }
2437 }
2438
2439 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2446 public function load_board($user)
2447 {
2448 // phpcs:enable
2449 global $conf, $langs;
2450
2451 if ($user->socid) {
2452 return -1; // protection pour eviter appel par utilisateur externe
2453 }
2454
2455 $now = dol_now();
2456
2457 $sql = "SELECT h.rowid, h.date_debut";
2458 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
2459 $sql .= " WHERE h.statut = 2";
2460 $sql .= " AND h.entity IN (".getEntity('holiday').")";
2461 if (!$user->hasRight('expensereport', 'read_all')) {
2462 $userchildids = $user->getAllChildIds(1);
2463 $sql .= " AND (h.fk_user IN (".$this->db->sanitize(implode(',', $userchildids)).")";
2464 $sql .= " OR h.fk_validator IN (".$this->db->sanitize(implode(',', $userchildids))."))";
2465 }
2466
2467 $resql = $this->db->query($sql);
2468 if ($resql) {
2469 $langs->load("members");
2470
2471 $response = new WorkboardResponse();
2472 $response->warning_delay = $conf->holiday->approve->warning_delay / 60 / 60 / 24;
2473 $response->label = $langs->trans("HolidaysToApprove");
2474 $response->labelShort = $langs->trans("ToApprove");
2475 $response->url = DOL_URL_ROOT.'/holiday/list.php?search_status=2&amp;mainmenu=hrm&amp;leftmenu=holiday';
2476 $response->img = img_object('', "holiday");
2477
2478 while ($obj = $this->db->fetch_object($resql)) {
2479 $response->nbtodo++;
2480
2481 if ($this->db->jdate($obj->date_debut) < ($now - $conf->holiday->approve->warning_delay)) {
2482 $response->nbtodolate++;
2483 }
2484 }
2485
2486 return $response;
2487 } else {
2488 dol_print_error($this->db);
2489 $this->error = $this->db->error();
2490 return -1;
2491 }
2492 }
2500 public function getKanbanView($option = '', $arraydata = null)
2501 {
2502 global $langs;
2503
2504 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
2505
2506 $return = '<div class="box-flex-item box-flex-grow-zero">';
2507 $return .= '<div class="info-box info-box-sm">';
2508 $return .= '<span class="info-box-icon bg-infobox-action">';
2509 $return .= img_picto('', $this->picto);
2510 $return .= '</span>';
2511 $return .= '<div class="info-box-content">';
2512 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.$this->getNomUrl().'</span>';
2513 if ($selected >= 0) {
2514 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
2515 }
2516 if (property_exists($this, 'fk_type')) {
2517 $return .= '<br>';
2518 //$return .= '<span class="opacitymedium">'.$langs->trans("Type").'</span> : ';
2519 $return .= '<div class="info_box-label tdoverflowmax100" title="'.dol_escape_htmltag($arraydata['labeltype']).'">'.dol_escape_htmltag($arraydata['labeltype']).'</div>';
2520 }
2521 if (property_exists($this, 'date_debut') && property_exists($this, 'date_fin')) {
2522 $return .= '<span class="info-box-label small">'.dol_print_date($this->date_debut, 'day').'</span>';
2523 $return .= ' <span class="opacitymedium small">'.$langs->trans("To").'</span> ';
2524 $return .= '<span class="info-box-label small">'.dol_print_date($this->date_fin, 'day').'</span>';
2525 if (!empty($arraydata['nbopenedday'])) {
2526 $return .= ' ('.$arraydata['nbopenedday'].')';
2527 }
2528 }
2529 if (method_exists($this, 'getLibStatut')) {
2530 $return .= '<div class="info-box-status">'.$this->getLibStatut(3).'</div>';
2531 }
2532 $return .= '</div>';
2533 $return .= '</div>';
2534 $return .= '</div>';
2535 return $return;
2536 }
2537}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition security.php:640
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:457
$object ref
Definition info.php:79
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Class of the module paid holiday.
getTypes($active=-1, $affect=-1)
Return array with list of types.
getNomUrl($withpicto=0, $save_lastsearch_value=-1, $notooltip=0, $morecss='')
Return clickable name (with picto eventually)
verifDateHolidayCP($fk_user, $dateStart, $dateEnd, $halfday=0)
Check if a user is on holiday (partially or completely) into a period.
validate($user=null, $notrigger=0)
Validate leave request.
info($id)
Load information on object.
updateBalance()
Update balance of vacations and check table of users for holidays is complete.
updateConfCP($name, $value)
Met à jour une option du module Holiday Payés.
const STATUS_VALIDATED
Validated status.
const STATUS_DRAFT
Draft status.
fetch($id, $ref='')
Load object in memory from database.
addLogCP($fk_user_action, $fk_user_update, $label, $new_solde, $fk_type)
addLogCP
verifNbUsers($userDolibarrWithoutCP, $userCP)
Compare le nombre d'utilisateur actif de Dolibarr à celui des utilisateurs des congés payés.
verifDateHolidayForTimestamp($fk_user, $timestamp, $status='-1')
Check that a user is not on holiday for a particular timestamp.
approve($user=null, $notrigger=0)
Approve leave request.
getNextNumRef($objsoc)
Returns the reference to the following non used Order depending on the active numbering module define...
const STATUS_REFUSED
Refused.
getConfCP($name, $createifnotfound='')
Return value of a conf parameter for leave module TODO Move this into llx_const table.
load_board($user)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
initAsSpecimen()
Initialise an instance with random values.
create($user, $notrigger=0)
Créer un congés payés dans la base de données.
selectStatutCP($selected=0, $htmlname='select_statut', $morecss='minwidth125')
Show select with list of leave status.
countActiveUsersWithoutCP()
Compte le nombre d'utilisateur actifs dans Dolibarr sans CP.
updateSoldeCP($userID=0, $nbHoliday=0, $fk_type=0)
Met à jour le timestamp de la dernière mise à jour du solde des CP.
fetchLog($order, $filter)
Liste le log des congés payés.
update($user=null, $notrigger=0)
Update database.
getCPforUser($user_id, $fk_type=0)
Return the balance of annual leave of a user.
fetch_users_approver_holiday()
Return list of people with permission to validate leave requests.
__construct($db)
Constructor.
loadStateBoard()
Load this->nb for dashboard.
getLibStatut($mode=0)
Returns the label status.
createCPusers($single=false, $userid=0)
Create entries for each user at setup step.
fetchAll($order, $filter)
List all holidays of all users.
const STATUS_CANCELED
Canceled.
countActiveUsers()
Compte le nombre d'utilisateur actifs dans Dolibarr.
fetchByUser($user_id, $order='', $filter='')
List holidays for a particular user or list of users.
const STATUS_APPROVED
Approved.
getTooltipContentArray($params)
getTooltipContentArray
fetchUsers($stringlist=true, $type=true, $filters='')
Get list of Users or list of vacation balance.
getKanbanView($option='', $arraydata=null)
Return clickable link of object (with eventually picto)
LibStatut($status, $mode=0, $startdate='')
Returns the label of a status.
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:63
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
getDictionaryValue($tablename, $field, $id, $checkentity=false, $rowidfield='rowid')
Return the value of a filed into a dictionary for the record $id.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...