dolibarr 20.0.5
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
62 public $date_create = '';
63
67 public $description;
68
72 public $date_debut = '';
73
77 public $date_fin = '';
78
82 public $date_debut_gmt = '';
83
87 public $date_fin_gmt = '';
88
92 public $halfday = '';
93
98 public $statut = 0;
99
103 public $fk_validator;
104
108 public $date_valid = 0;
109
113 public $fk_user_valid;
114
118 public $date_approval;
119
123 public $fk_user_approve;
124
128 public $date_refuse = 0;
129
133 public $fk_user_refuse;
134
138 public $date_cancel = 0;
139
143 public $fk_user_cancel;
144
148 public $fk_user_create;
149
153 public $detail_refuse = '';
154
158 public $fk_type;
159
160 public $holiday = array();
161 public $events = array();
162 public $logs = array();
163
164 public $optName = '';
165 public $optValue = '';
166 public $optRowid = '';
167
171 const STATUS_DRAFT = 1;
187 const STATUS_REFUSED = 5;
188
189
195 public function __construct($db)
196 {
197 $this->db = $db;
198
199 $this->ismultientitymanaged = 0;
200 }
201
202
210 public function getNextNumRef($objsoc)
211 {
212 global $langs, $conf;
213 $langs->load("order");
214
215 if (!getDolGlobalString('HOLIDAY_ADDON')) {
216 $conf->global->HOLIDAY_ADDON = 'mod_holiday_madonna';
217 }
218
219 if (getDolGlobalString('HOLIDAY_ADDON')) {
220 $mybool = false;
221
222 $file = getDolGlobalString('HOLIDAY_ADDON') . ".php";
223 $classname = getDolGlobalString('HOLIDAY_ADDON');
224
225 // Include file with class
226 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
227 foreach ($dirmodels as $reldir) {
228 $dir = dol_buildpath($reldir."core/modules/holiday/");
229
230 // Load file with numbering class (if found)
231 $mybool = ((bool) @include_once $dir.$file) || $mybool;
232 }
233
234 if ($mybool === false) {
235 dol_print_error(null, "Failed to include file ".$file);
236 return '';
237 }
238
239 $obj = new $classname();
240 $numref = $obj->getNextValue($objsoc, $this);
241
242 if ($numref != "") {
243 return $numref;
244 } else {
245 $this->error = $obj->error;
246 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
247 return "";
248 }
249 } else {
250 print $langs->trans("Error")." ".$langs->trans("Error_HOLIDAY_ADDON_NotDefined");
251 return "";
252 }
253 }
254
260 public function updateBalance()
261 {
262 $this->db->begin();
263
264 // Update sold of vocations
265 $result = $this->updateSoldeCP();
266
267 // Check nb of users into table llx_holiday_users and update with empty lines
268 //if ($result > 0) $result = $this->verifNbUsers($this->countActiveUsersWithoutCP(), $this->getConfCP('nbUser'));
269
270 if ($result >= 0) {
271 $this->db->commit();
272 return 0; // for cronjob use (0 is OK, any other value is an error code)
273 } else {
274 $this->db->rollback();
275 return -1;
276 }
277 }
278
286 public function create($user, $notrigger = 0)
287 {
288 global $conf;
289 $error = 0;
290
291 $now = dol_now();
292
293 // Check parameters
294 if (empty($this->fk_user) || !is_numeric($this->fk_user) || $this->fk_user < 0) {
295 $this->error = "ErrorBadParameterFkUser";
296 return -1;
297 }
298 if (empty($this->fk_validator) || !is_numeric($this->fk_validator) || $this->fk_validator < 0) {
299 $this->error = "ErrorBadParameterFkValidator";
300 return -1;
301 }
302 if (empty($this->fk_type) || !is_numeric($this->fk_type) || $this->fk_type < 0) {
303 $this->error = "ErrorBadParameterFkType";
304 return -1;
305 }
306
307 // Insert request
308 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday(";
309 $sql .= "ref,";
310 $sql .= "fk_user,";
311 $sql .= "date_create,";
312 $sql .= "description,";
313 $sql .= "date_debut,";
314 $sql .= "date_fin,";
315 $sql .= "halfday,";
316 $sql .= "statut,";
317 $sql .= "fk_validator,";
318 $sql .= "fk_type,";
319 $sql .= "fk_user_create,";
320 $sql .= "entity";
321 $sql .= ") VALUES (";
322 $sql .= "'(PROV)',";
323 $sql .= " ".((int) $this->fk_user).",";
324 $sql .= " '".$this->db->idate($now)."',";
325 $sql .= " '".$this->db->escape($this->description)."',";
326 $sql .= " '".$this->db->idate($this->date_debut)."',";
327 $sql .= " '".$this->db->idate($this->date_fin)."',";
328 $sql .= " ".((int) $this->halfday).",";
329 $sql .= " '1',";
330 $sql .= " ".((int) $this->fk_validator).",";
331 $sql .= " ".((int) $this->fk_type).",";
332 $sql .= " ".((int) $user->id).",";
333 $sql .= " ".((int) $conf->entity);
334 $sql .= ")";
335
336 $this->db->begin();
337
338 dol_syslog(get_class($this)."::create", LOG_DEBUG);
339 $resql = $this->db->query($sql);
340 if (!$resql) {
341 $error++;
342 $this->errors[] = "Error ".$this->db->lasterror();
343 }
344
345 if (!$error) {
346 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."holiday");
347
348 if ($this->id) {
349 // update ref
350 $initialref = '(PROV'.$this->id.')';
351 if (!empty($this->ref)) {
352 $initialref = $this->ref;
353 }
354
355 $sql = 'UPDATE '.MAIN_DB_PREFIX."holiday SET ref='".$this->db->escape($initialref)."' WHERE rowid=".((int) $this->id);
356 if ($this->db->query($sql)) {
357 $this->ref = $initialref;
358
359 if (!$error) {
360 $result = $this->insertExtraFields();
361 if ($result < 0) {
362 $error++;
363 }
364 }
365
366 if (!$error && !$notrigger) {
367 // Call trigger
368 $result = $this->call_trigger('HOLIDAY_CREATE', $user);
369 if ($result < 0) {
370 $error++;
371 }
372 // End call triggers
373 }
374 }
375 }
376 }
377
378 // Commit or rollback
379 if ($error) {
380 foreach ($this->errors as $errmsg) {
381 dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR);
382 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
383 }
384 $this->db->rollback();
385 return -1 * $error;
386 } else {
387 $this->db->commit();
388 return $this->id;
389 }
390 }
391
392
400 public function fetch($id, $ref = '')
401 {
402 $sql = "SELECT";
403 $sql .= " cp.rowid,";
404 $sql .= " cp.ref,";
405 $sql .= " cp.fk_user,";
406 $sql .= " cp.date_create,";
407 $sql .= " cp.description,";
408 $sql .= " cp.date_debut,";
409 $sql .= " cp.date_fin,";
410 $sql .= " cp.halfday,";
411 $sql .= " cp.statut as status,";
412 $sql .= " cp.fk_validator,";
413 $sql .= " cp.date_valid,";
414 $sql .= " cp.fk_user_valid,";
415 $sql .= " cp.date_approval,";
416 $sql .= " cp.fk_user_approve,";
417 $sql .= " cp.date_refuse,";
418 $sql .= " cp.fk_user_refuse,";
419 $sql .= " cp.date_cancel,";
420 $sql .= " cp.fk_user_cancel,";
421 $sql .= " cp.detail_refuse,";
422 $sql .= " cp.note_private,";
423 $sql .= " cp.note_public,";
424 $sql .= " cp.fk_user_create,";
425 $sql .= " cp.fk_type,";
426 $sql .= " cp.entity";
427 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp";
428 if ($id > 0) {
429 $sql .= " WHERE cp.rowid = ".((int) $id);
430 } else {
431 $sql .= " WHERE cp.ref = '".$this->db->escape($ref)."'";
432 }
433
434 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
435 $resql = $this->db->query($sql);
436 if ($resql) {
437 if ($this->db->num_rows($resql)) {
438 $obj = $this->db->fetch_object($resql);
439
440 $this->id = $obj->rowid;
441 $this->ref = ($obj->ref ? $obj->ref : $obj->rowid);
442 $this->fk_user = $obj->fk_user;
443 $this->date_create = $this->db->jdate($obj->date_create);
444 $this->description = $obj->description;
445 $this->date_debut = $this->db->jdate($obj->date_debut);
446 $this->date_fin = $this->db->jdate($obj->date_fin);
447 $this->date_debut_gmt = $this->db->jdate($obj->date_debut, 1);
448 $this->date_fin_gmt = $this->db->jdate($obj->date_fin, 1);
449 $this->halfday = $obj->halfday;
450 $this->status = $obj->status;
451 $this->statut = $obj->status; // deprecated
452 $this->fk_validator = $obj->fk_validator;
453 $this->date_valid = $this->db->jdate($obj->date_valid);
454 $this->fk_user_valid = $obj->fk_user_valid;
455 $this->user_validation_id = $obj->fk_user_valid;
456 $this->date_approval = $this->db->jdate($obj->date_approval);
457 $this->fk_user_approve = $obj->fk_user_approve;
458 $this->date_refuse = $this->db->jdate($obj->date_refuse);
459 $this->fk_user_refuse = $obj->fk_user_refuse;
460 $this->date_cancel = $this->db->jdate($obj->date_cancel);
461 $this->fk_user_cancel = $obj->fk_user_cancel;
462 $this->detail_refuse = $obj->detail_refuse;
463 $this->note_private = $obj->note_private;
464 $this->note_public = $obj->note_public;
465 $this->fk_user_create = $obj->fk_user_create;
466 $this->fk_type = $obj->fk_type;
467 $this->entity = $obj->entity;
468
469 $this->fetch_optionals();
470
471 $result = 1;
472 } else {
473 $result = 0;
474 }
475 $this->db->free($resql);
476
477 return $result;
478 } else {
479 $this->error = "Error ".$this->db->lasterror();
480 return -1;
481 }
482 }
483
492 public function fetchByUser($user_id, $order = '', $filter = '')
493 {
494 $sql = "SELECT";
495 $sql .= " cp.rowid,";
496 $sql .= " cp.ref,";
497
498 $sql .= " cp.fk_user,";
499 $sql .= " cp.fk_type,";
500 $sql .= " cp.date_create,";
501 $sql .= " cp.description,";
502 $sql .= " cp.date_debut,";
503 $sql .= " cp.date_fin,";
504 $sql .= " cp.halfday,";
505 $sql .= " cp.statut as status,";
506 $sql .= " cp.fk_validator,";
507 $sql .= " cp.date_valid,";
508 $sql .= " cp.fk_user_valid,";
509 $sql .= " cp.date_approval,";
510 $sql .= " cp.fk_user_approve,";
511 $sql .= " cp.date_refuse,";
512 $sql .= " cp.fk_user_refuse,";
513 $sql .= " cp.date_cancel,";
514 $sql .= " cp.fk_user_cancel,";
515 $sql .= " cp.detail_refuse,";
516
517 $sql .= " uu.lastname as user_lastname,";
518 $sql .= " uu.firstname as user_firstname,";
519 $sql .= " uu.login as user_login,";
520 $sql .= " uu.statut as user_status,";
521 $sql .= " uu.photo as user_photo,";
522
523 $sql .= " ua.lastname as validator_lastname,";
524 $sql .= " ua.firstname as validator_firstname,";
525 $sql .= " ua.login as validator_login,";
526 $sql .= " ua.statut as validator_status,";
527 $sql .= " ua.photo as validator_photo";
528
529 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp, ".MAIN_DB_PREFIX."user as uu, ".MAIN_DB_PREFIX."user as ua";
530 $sql .= " WHERE cp.entity IN (".getEntity('holiday').")";
531 $sql .= " AND cp.fk_user = uu.rowid AND cp.fk_validator = ua.rowid"; // Hack pour la recherche sur le tableau
532 $sql .= " AND cp.fk_user IN (".$this->db->sanitize($user_id).")";
533
534 // Selection filter
535 if (!empty($filter)) {
536 $sql .= $filter;
537 }
538
539 // Order of display of the result
540 if (!empty($order)) {
541 $sql .= $order;
542 }
543
544 dol_syslog(get_class($this)."::fetchByUser", LOG_DEBUG);
545 $resql = $this->db->query($sql);
546
547 // If no SQL error
548 if ($resql) {
549 $i = 0;
550 $tab_result = $this->holiday;
551 $num = $this->db->num_rows($resql);
552
553 // If no registration
554 if (!$num) {
555 return 2;
556 }
557
558 // List the records and add them to the table
559 while ($i < $num) {
560 $obj = $this->db->fetch_object($resql);
561
562 $tab_result[$i]['rowid'] = $obj->rowid;
563 $tab_result[$i]['id'] = $obj->rowid;
564 $tab_result[$i]['ref'] = ($obj->ref ? $obj->ref : $obj->rowid);
565
566 $tab_result[$i]['fk_user'] = $obj->fk_user;
567 $tab_result[$i]['fk_type'] = $obj->fk_type;
568 $tab_result[$i]['date_create'] = $this->db->jdate($obj->date_create);
569 $tab_result[$i]['description'] = $obj->description;
570 $tab_result[$i]['date_debut'] = $this->db->jdate($obj->date_debut);
571 $tab_result[$i]['date_fin'] = $this->db->jdate($obj->date_fin);
572 $tab_result[$i]['date_debut_gmt'] = $this->db->jdate($obj->date_debut, 1);
573 $tab_result[$i]['date_fin_gmt'] = $this->db->jdate($obj->date_fin, 1);
574 $tab_result[$i]['halfday'] = $obj->halfday;
575 $tab_result[$i]['statut'] = $obj->status;
576 $tab_result[$i]['status'] = $obj->status;
577 $tab_result[$i]['fk_validator'] = $obj->fk_validator;
578 $tab_result[$i]['date_valid'] = $this->db->jdate($obj->date_valid);
579 $tab_result[$i]['fk_user_valid'] = $obj->fk_user_valid;
580 $tab_result[$i]['date_approval'] = $this->db->jdate($obj->date_approval);
581 $tab_result[$i]['fk_user_approve'] = $obj->fk_user_approve;
582 $tab_result[$i]['date_refuse'] = $this->db->jdate($obj->date_refuse);
583 $tab_result[$i]['fk_user_refuse'] = $obj->fk_user_refuse;
584 $tab_result[$i]['date_cancel'] = $this->db->jdate($obj->date_cancel);
585 $tab_result[$i]['fk_user_cancel'] = $obj->fk_user_cancel;
586 $tab_result[$i]['detail_refuse'] = $obj->detail_refuse;
587
588 $tab_result[$i]['user_firstname'] = $obj->user_firstname;
589 $tab_result[$i]['user_lastname'] = $obj->user_lastname;
590 $tab_result[$i]['user_login'] = $obj->user_login;
591 $tab_result[$i]['user_statut'] = $obj->user_status;
592 $tab_result[$i]['user_status'] = $obj->user_status;
593 $tab_result[$i]['user_photo'] = $obj->user_photo;
594
595 $tab_result[$i]['validator_firstname'] = $obj->validator_firstname;
596 $tab_result[$i]['validator_lastname'] = $obj->validator_lastname;
597 $tab_result[$i]['validator_login'] = $obj->validator_login;
598 $tab_result[$i]['validator_statut'] = $obj->validator_status;
599 $tab_result[$i]['validator_status'] = $obj->validator_status;
600 $tab_result[$i]['validator_photo'] = $obj->validator_photo;
601
602 $i++;
603 }
604
605 // Returns 1 with the filled array
606 $this->holiday = $tab_result;
607 return 1;
608 } else {
609 // SQL Error
610 $this->error = "Error ".$this->db->lasterror();
611 return -1;
612 }
613 }
614
622 public function fetchAll($order, $filter)
623 {
624 $sql = "SELECT";
625 $sql .= " cp.rowid,";
626 $sql .= " cp.ref,";
627 $sql .= " cp.fk_user,";
628 $sql .= " cp.fk_type,";
629 $sql .= " cp.date_create,";
630 $sql .= " cp.tms as date_modification,";
631 $sql .= " cp.description,";
632 $sql .= " cp.date_debut,";
633 $sql .= " cp.date_fin,";
634 $sql .= " cp.halfday,";
635 $sql .= " cp.statut as status,";
636 $sql .= " cp.fk_validator,";
637 $sql .= " cp.date_valid,";
638 $sql .= " cp.fk_user_valid,";
639 $sql .= " cp.date_approval,";
640 $sql .= " cp.fk_user_approve,";
641 $sql .= " cp.date_refuse,";
642 $sql .= " cp.fk_user_refuse,";
643 $sql .= " cp.date_cancel,";
644 $sql .= " cp.fk_user_cancel,";
645 $sql .= " cp.detail_refuse,";
646
647 $sql .= " uu.lastname as user_lastname,";
648 $sql .= " uu.firstname as user_firstname,";
649 $sql .= " uu.login as user_login,";
650 $sql .= " uu.statut as user_status,";
651 $sql .= " uu.photo as user_photo,";
652
653 $sql .= " ua.lastname as validator_lastname,";
654 $sql .= " ua.firstname as validator_firstname,";
655 $sql .= " ua.login as validator_login,";
656 $sql .= " ua.statut as validator_status,";
657 $sql .= " ua.photo as validator_photo";
658
659 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp, ".MAIN_DB_PREFIX."user as uu, ".MAIN_DB_PREFIX."user as ua";
660 $sql .= " WHERE cp.entity IN (".getEntity('holiday').")";
661 $sql .= " AND cp.fk_user = uu.rowid AND cp.fk_validator = ua.rowid "; // Hack pour la recherche sur le tableau
662
663 // Selection filtering
664 if (!empty($filter)) {
665 $sql .= $filter;
666 }
667
668 // order of display
669 if (!empty($order)) {
670 $sql .= $order;
671 }
672
673 dol_syslog(get_class($this)."::fetchAll", LOG_DEBUG);
674 $resql = $this->db->query($sql);
675
676 // If no SQL error
677 if ($resql) {
678 $i = 0;
679 $tab_result = $this->holiday;
680 $num = $this->db->num_rows($resql);
681
682 // If no registration
683 if (!$num) {
684 return 2;
685 }
686
687 // List the records and add them to the table
688 while ($i < $num) {
689 $obj = $this->db->fetch_object($resql);
690
691 $tab_result[$i]['rowid'] = $obj->rowid;
692 $tab_result[$i]['id'] = $obj->rowid;
693 $tab_result[$i]['ref'] = ($obj->ref ? $obj->ref : $obj->rowid);
694
695 $tab_result[$i]['fk_user'] = $obj->fk_user;
696 $tab_result[$i]['fk_type'] = $obj->fk_type;
697 $tab_result[$i]['date_create'] = $this->db->jdate($obj->date_create);
698 $tab_result[$i]['date_modification'] = $this->db->jdate($obj->date_modification);
699 $tab_result[$i]['description'] = $obj->description;
700 $tab_result[$i]['date_debut'] = $this->db->jdate($obj->date_debut);
701 $tab_result[$i]['date_fin'] = $this->db->jdate($obj->date_fin);
702 $tab_result[$i]['date_debut_gmt'] = $this->db->jdate($obj->date_debut, 1);
703 $tab_result[$i]['date_fin_gmt'] = $this->db->jdate($obj->date_fin, 1);
704 $tab_result[$i]['halfday'] = $obj->halfday;
705 $tab_result[$i]['statut'] = $obj->status;
706 $tab_result[$i]['status'] = $obj->status;
707 $tab_result[$i]['fk_validator'] = $obj->fk_validator;
708 $tab_result[$i]['date_valid'] = $this->db->jdate($obj->date_valid);
709 $tab_result[$i]['fk_user_valid'] = $obj->fk_user_valid;
710 $tab_result[$i]['date_approval'] = $this->db->jdate($obj->date_approval);
711 $tab_result[$i]['fk_user_approve'] = $obj->fk_user_approve;
712 $tab_result[$i]['date_refuse'] = $obj->date_refuse;
713 $tab_result[$i]['fk_user_refuse'] = $obj->fk_user_refuse;
714 $tab_result[$i]['date_cancel'] = $obj->date_cancel;
715 $tab_result[$i]['fk_user_cancel'] = $obj->fk_user_cancel;
716 $tab_result[$i]['detail_refuse'] = $obj->detail_refuse;
717
718 $tab_result[$i]['user_firstname'] = $obj->user_firstname;
719 $tab_result[$i]['user_lastname'] = $obj->user_lastname;
720 $tab_result[$i]['user_login'] = $obj->user_login;
721 $tab_result[$i]['user_statut'] = $obj->user_status;
722 $tab_result[$i]['user_status'] = $obj->user_status;
723 $tab_result[$i]['user_photo'] = $obj->user_photo;
724
725 $tab_result[$i]['validator_firstname'] = $obj->validator_firstname;
726 $tab_result[$i]['validator_lastname'] = $obj->validator_lastname;
727 $tab_result[$i]['validator_login'] = $obj->validator_login;
728 $tab_result[$i]['validator_statut'] = $obj->validator_status;
729 $tab_result[$i]['validator_status'] = $obj->validator_status;
730 $tab_result[$i]['validator_photo'] = $obj->validator_photo;
731
732 $i++;
733 }
734 // Returns 1 and adds the array to the variable
735 $this->holiday = $tab_result;
736 return 1;
737 } else {
738 // SQL Error
739 $this->error = "Error ".$this->db->lasterror();
740 return -1;
741 }
742 }
743
744
752 public function validate($user = null, $notrigger = 0)
753 {
754 global $conf, $langs;
755 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
756 $error = 0;
757
758 $checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type, true);
759
760 if ($checkBalance > 0) {
761 $balance = $this->getCPforUser($this->fk_user, $this->fk_type);
762
763 if ($balance < 0) {
764 $this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
765 return -1;
766 }
767 }
768
769 // Define new ref
770 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref) || $this->ref == $this->id)) {
771 $num = $this->getNextNumRef(null);
772 } else {
773 $num = $this->ref;
774 }
775 $this->newref = dol_sanitizeFileName($num);
776
777 // Update status
778 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
779 $sql .= " fk_user_valid = ".((int) $user->id).",";
780 $sql .= " date_valid = '".$this->db->idate(dol_now())."',";
781 if (!empty($this->status) && is_numeric($this->status)) {
782 $sql .= " statut = ".((int) $this->status).",";
783 } else {
784 $this->error = 'Property status must be a numeric value';
785 $error++;
786 }
787 $sql .= " ref = '".$this->db->escape($num)."'";
788 $sql .= " WHERE rowid = ".((int) $this->id);
789
790 $this->db->begin();
791
792 dol_syslog(get_class($this)."::validate", LOG_DEBUG);
793 $resql = $this->db->query($sql);
794 if (!$resql) {
795 $error++;
796 $this->errors[] = "Error ".$this->db->lasterror();
797 }
798
799 if (!$error) {
800 if (!$notrigger) {
801 // Call trigger
802 $result = $this->call_trigger('HOLIDAY_VALIDATE', $user);
803 if ($result < 0) {
804 $error++;
805 }
806 // End call triggers
807 }
808 }
809
810 if (!$error) {
811 $this->oldref = $this->ref;
812
813 // Rename directory if dir was a temporary ref
814 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
815 // Now we rename also files into index
816 $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) . "'";
817 $sql .= " WHERE filename LIKE '" . $this->db->escape($this->ref) . "%' AND filepath = 'holiday/" . $this->db->escape($this->ref) . "' and entity = " . ((int) $conf->entity);
818 $resql = $this->db->query($sql);
819 if (!$resql) {
820 $error++;
821 $this->error = $this->db->lasterror();
822 }
823 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'holiday/".$this->db->escape($this->newref)."'";
824 $sql .= " WHERE filepath = 'holiday/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
825 $resql = $this->db->query($sql);
826 if (!$resql) {
827 $error++;
828 $this->error = $this->db->lasterror();
829 }
830
831 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
832 $oldref = dol_sanitizeFileName($this->ref);
833 $newref = dol_sanitizeFileName($num);
834 $dirsource = $conf->holiday->multidir_output[$this->entity] . '/' . $oldref;
835 $dirdest = $conf->holiday->multidir_output[$this->entity] . '/' . $newref;
836 if (!$error && file_exists($dirsource)) {
837 dol_syslog(get_class($this) . "::validate rename dir " . $dirsource . " into " . $dirdest);
838 if (@rename($dirsource, $dirdest)) {
839 dol_syslog("Rename ok");
840 // Rename docs starting with $oldref with $newref
841 $listoffiles = dol_dir_list($dirdest, 'files', 1, '^' . preg_quote($oldref, '/'));
842 foreach ($listoffiles as $fileentry) {
843 $dirsource = $fileentry['name'];
844 $dirdest = preg_replace('/^' . preg_quote($oldref, '/') . '/', $newref, $dirsource);
845 $dirsource = $fileentry['path'] . '/' . $dirsource;
846 $dirdest = $fileentry['path'] . '/' . $dirdest;
847 @rename($dirsource, $dirdest);
848 }
849 }
850 }
851 }
852 }
853
854
855 // Commit or rollback
856 if ($error) {
857 foreach ($this->errors as $errmsg) {
858 dol_syslog(get_class($this)."::validate ".$errmsg, LOG_ERR);
859 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
860 }
861 $this->db->rollback();
862 return -1 * $error;
863 } else {
864 $this->db->commit();
865 return 1;
866 }
867 }
868
869
877 public function approve($user = null, $notrigger = 0)
878 {
879 $error = 0;
880
881 $checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type, true);
882
883 if ($checkBalance > 0) {
884 $balance = $this->getCPforUser($this->fk_user, $this->fk_type);
885 $daysAsked = num_open_day($this->date_debut, $this->date_fin, 0, 1);
886
887 if (($balance - $daysAsked) < 0) {
888 $this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
889 return -1;
890 }
891 }
892
893 // Update request
894 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
895 $sql .= " description= '".$this->db->escape($this->description)."',";
896 if (!empty($this->date_debut)) {
897 $sql .= " date_debut = '".$this->db->idate($this->date_debut)."',";
898 } else {
899 $error++;
900 }
901 if (!empty($this->date_fin)) {
902 $sql .= " date_fin = '".$this->db->idate($this->date_fin)."',";
903 } else {
904 $error++;
905 }
906 $sql .= " halfday = ".((int) $this->halfday).",";
907 if (!empty($this->status) && is_numeric($this->status)) {
908 $sql .= " statut = ".((int) $this->status).",";
909 } else {
910 $error++;
911 }
912 if (!empty($this->fk_validator)) {
913 $sql .= " fk_validator = ".((int) $this->fk_validator).",";
914 } else {
915 $error++;
916 }
917 if (!empty($this->date_valid)) {
918 $sql .= " date_valid = '".$this->db->idate($this->date_valid)."',";
919 } else {
920 $sql .= " date_valid = NULL,";
921 }
922 if (!empty($this->fk_user_valid)) {
923 $sql .= " fk_user_valid = ".((int) $this->fk_user_valid).",";
924 } else {
925 $sql .= " fk_user_valid = NULL,";
926 }
927 if (!empty($this->date_approval)) {
928 $sql .= " date_approval = '".$this->db->idate($this->date_approval)."',";
929 } else {
930 $sql .= " date_approval = NULL,";
931 }
932 if (!empty($this->fk_user_approve)) {
933 $sql .= " fk_user_approve = ".((int) $this->fk_user_approve).",";
934 } else {
935 $sql .= " fk_user_approve = NULL,";
936 }
937 if (!empty($this->date_refuse)) {
938 $sql .= " date_refuse = '".$this->db->idate($this->date_refuse)."',";
939 } else {
940 $sql .= " date_refuse = NULL,";
941 }
942 if (!empty($this->fk_user_refuse)) {
943 $sql .= " fk_user_refuse = ".((int) $this->fk_user_refuse).",";
944 } else {
945 $sql .= " fk_user_refuse = NULL,";
946 }
947 if (!empty($this->date_cancel)) {
948 $sql .= " date_cancel = '".$this->db->idate($this->date_cancel)."',";
949 } else {
950 $sql .= " date_cancel = NULL,";
951 }
952 if (!empty($this->fk_user_cancel)) {
953 $sql .= " fk_user_cancel = ".((int) $this->fk_user_cancel).",";
954 } else {
955 $sql .= " fk_user_cancel = NULL,";
956 }
957 if (!empty($this->detail_refuse)) {
958 $sql .= " detail_refuse = '".$this->db->escape($this->detail_refuse)."'";
959 } else {
960 $sql .= " detail_refuse = NULL";
961 }
962 $sql .= " WHERE rowid = ".((int) $this->id);
963
964 $this->db->begin();
965
966 dol_syslog(get_class($this)."::approve", LOG_DEBUG);
967 $resql = $this->db->query($sql);
968 if (!$resql) {
969 $error++;
970 $this->errors[] = "Error ".$this->db->lasterror();
971 }
972
973 if (!$error) {
974 if (!$notrigger) {
975 // Call trigger
976 $result = $this->call_trigger('HOLIDAY_APPROVE', $user);
977 if ($result < 0) {
978 $error++;
979 }
980 // End call triggers
981 }
982 }
983
984 // Commit or rollback
985 if ($error) {
986 foreach ($this->errors as $errmsg) {
987 dol_syslog(get_class($this)."::approve ".$errmsg, LOG_ERR);
988 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
989 }
990 $this->db->rollback();
991 return -1 * $error;
992 } else {
993 $this->db->commit();
994 return 1;
995 }
996 }
997
1005 public function update($user = null, $notrigger = 0)
1006 {
1007 global $conf, $langs;
1008 $error = 0;
1009
1010 $checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type, true);
1011
1012 if ($checkBalance > 0 && $this->status != self::STATUS_DRAFT) {
1013 $balance = $this->getCPforUser($this->fk_user, $this->fk_type);
1014
1015 if ($balance < 0) {
1016 $this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
1017 return -1;
1018 }
1019 }
1020
1021 // Update request
1022 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
1023
1024 $sql .= " description= '".$this->db->escape($this->description)."',";
1025
1026 if (!empty($this->date_debut)) {
1027 $sql .= " date_debut = '".$this->db->idate($this->date_debut)."',";
1028 } else {
1029 $error++;
1030 }
1031 if (!empty($this->date_fin)) {
1032 $sql .= " date_fin = '".$this->db->idate($this->date_fin)."',";
1033 } else {
1034 $error++;
1035 }
1036 $sql .= " halfday = ".$this->halfday.",";
1037 if (!empty($this->status) && is_numeric($this->status)) {
1038 $sql .= " statut = ".$this->status.",";
1039 } else {
1040 $error++;
1041 }
1042 if (!empty($this->fk_validator)) {
1043 $sql .= " fk_validator = '".$this->db->escape($this->fk_validator)."',";
1044 } else {
1045 $error++;
1046 }
1047 if (!empty($this->date_valid)) {
1048 $sql .= " date_valid = '".$this->db->idate($this->date_valid)."',";
1049 } else {
1050 $sql .= " date_valid = NULL,";
1051 }
1052 if (!empty($this->fk_user_valid)) {
1053 $sql .= " fk_user_valid = ".((int) $this->fk_user_valid).",";
1054 } else {
1055 $sql .= " fk_user_valid = NULL,";
1056 }
1057 if (!empty($this->date_approval)) {
1058 $sql .= " date_approval = '".$this->db->idate($this->date_approval)."',";
1059 } else {
1060 $sql .= " date_approval = NULL,";
1061 }
1062 if (!empty($this->fk_user_approve)) {
1063 $sql .= " fk_user_approve = ".((int) $this->fk_user_approve).",";
1064 } else {
1065 $sql .= " fk_user_approve = NULL,";
1066 }
1067 if (!empty($this->date_refuse)) {
1068 $sql .= " date_refuse = '".$this->db->idate($this->date_refuse)."',";
1069 } else {
1070 $sql .= " date_refuse = NULL,";
1071 }
1072 if (!empty($this->fk_user_refuse)) {
1073 $sql .= " fk_user_refuse = ".((int) $this->fk_user_refuse).",";
1074 } else {
1075 $sql .= " fk_user_refuse = NULL,";
1076 }
1077 if (!empty($this->date_cancel)) {
1078 $sql .= " date_cancel = '".$this->db->idate($this->date_cancel)."',";
1079 } else {
1080 $sql .= " date_cancel = NULL,";
1081 }
1082 if (!empty($this->fk_user_cancel)) {
1083 $sql .= " fk_user_cancel = ".((int) $this->fk_user_cancel).",";
1084 } else {
1085 $sql .= " fk_user_cancel = NULL,";
1086 }
1087 if (!empty($this->detail_refuse)) {
1088 $sql .= " detail_refuse = '".$this->db->escape($this->detail_refuse)."'";
1089 } else {
1090 $sql .= " detail_refuse = NULL";
1091 }
1092
1093 $sql .= " WHERE rowid = ".((int) $this->id);
1094
1095 $this->db->begin();
1096
1097 dol_syslog(get_class($this)."::update", LOG_DEBUG);
1098 $resql = $this->db->query($sql);
1099 if (!$resql) {
1100 $error++;
1101 $this->errors[] = "Error ".$this->db->lasterror();
1102 }
1103
1104 if (!$error) {
1105 $result = $this->insertExtraFields();
1106 if ($result < 0) {
1107 $error++;
1108 }
1109 }
1110
1111 if (!$error) {
1112 if (!$notrigger) {
1113 // Call trigger
1114 $result = $this->call_trigger('HOLIDAY_MODIFY', $user);
1115 if ($result < 0) {
1116 $error++;
1117 }
1118 // End call triggers
1119 }
1120 }
1121
1122 // Commit or rollback
1123 if ($error) {
1124 foreach ($this->errors as $errmsg) {
1125 dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
1126 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1127 }
1128 $this->db->rollback();
1129 return -1 * $error;
1130 } else {
1131 $this->db->commit();
1132 return 1;
1133 }
1134 }
1135
1136
1144 public function delete($user, $notrigger = 0)
1145 {
1146 global $conf, $langs;
1147 $error = 0;
1148
1149 $sql = "DELETE FROM ".MAIN_DB_PREFIX."holiday";
1150 $sql .= " WHERE rowid=".((int) $this->id);
1151
1152 $this->db->begin();
1153
1154 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1155 $resql = $this->db->query($sql);
1156 if (!$resql) {
1157 $error++;
1158 $this->errors[] = "Error ".$this->db->lasterror();
1159 }
1160
1161 if (!$error) {
1162 if (!$notrigger) {
1163 // Call trigger
1164 $result = $this->call_trigger('HOLIDAY_DELETE', $user);
1165 if ($result < 0) {
1166 $error++;
1167 }
1168 // End call triggers
1169 }
1170 }
1171
1172 // Commit or rollback
1173 if ($error) {
1174 foreach ($this->errors as $errmsg) {
1175 dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
1176 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1177 }
1178 $this->db->rollback();
1179 return -1 * $error;
1180 } else {
1181 $this->db->commit();
1182 return 1;
1183 }
1184 }
1185
1199 public function verifDateHolidayCP($fk_user, $dateStart, $dateEnd, $halfday = 0)
1200 {
1201 $this->fetchByUser($fk_user, '', '');
1202
1203 foreach ($this->holiday as $infos_CP) {
1204 if ($infos_CP['statut'] == Holiday::STATUS_CANCELED) {
1205 continue; // ignore not validated holidays
1206 }
1207 if ($infos_CP['statut'] == Holiday::STATUS_REFUSED) {
1208 continue; // ignore refused holidays
1209 }
1210 //var_dump("--");
1211 //var_dump("old: ".dol_print_date($infos_CP['date_debut'],'dayhour').' '.dol_print_date($infos_CP['date_fin'],'dayhour').' '.$infos_CP['halfday']);
1212 //var_dump("new: ".dol_print_date($dateStart,'dayhour').' '.dol_print_date($dateEnd,'dayhour').' '.$halfday);
1213
1214 if ($halfday == 0) {
1215 if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1216 return false;
1217 }
1218 if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1219 return false;
1220 }
1221 } elseif ($halfday == -1) {
1222 // new start afternoon, new end afternoon
1223 if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1224 if ($dateStart < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
1225 return false;
1226 }
1227 }
1228 if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1229 if ($dateStart < $dateEnd) {
1230 return false;
1231 }
1232 if ($dateEnd < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
1233 return false;
1234 }
1235 }
1236 } elseif ($halfday == 1) {
1237 // new start morning, new end morning
1238 if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1239 if ($dateStart < $dateEnd) {
1240 return false;
1241 }
1242 if ($dateStart > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
1243 return false;
1244 }
1245 }
1246 if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1247 if ($dateEnd > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
1248 return false;
1249 }
1250 }
1251 } elseif ($halfday == 2) {
1252 // new start afternoon, new end morning
1253 if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1254 if ($dateStart < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
1255 return false;
1256 }
1257 }
1258 if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1259 if ($dateEnd > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
1260 return false;
1261 }
1262 }
1263 } else {
1264 dol_print_error(null, 'Bad value of parameter halfday when calling function verifDateHolidayCP');
1265 }
1266 }
1267
1268 return true;
1269 }
1270
1271
1281 public function verifDateHolidayForTimestamp($fk_user, $timestamp, $status = '-1')
1282 {
1283 $isavailablemorning = true;
1284 $isavailableafternoon = true;
1285
1286 // Check into leave requests
1287 $sql = "SELECT cp.rowid, cp.date_debut as date_start, cp.date_fin as date_end, cp.halfday, cp.statut as status";
1288 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp";
1289 $sql .= " WHERE cp.entity IN (".getEntity('holiday').")";
1290 $sql .= " AND cp.fk_user = ".(int) $fk_user;
1291 $sql .= " AND cp.date_debut <= '".$this->db->idate($timestamp)."' AND cp.date_fin >= '".$this->db->idate($timestamp)."'";
1292 if ($status != '-1') {
1293 $sql .= " AND cp.statut IN (".$this->db->sanitize($status).")";
1294 }
1295
1296 $resql = $this->db->query($sql);
1297 if ($resql) {
1298 $num_rows = $this->db->num_rows($resql); // Note, we can have 2 records if on is morning and the other one is afternoon
1299 if ($num_rows > 0) {
1300 $arrayofrecord = array();
1301 $i = 0;
1302 while ($i < $num_rows) {
1303 $obj = $this->db->fetch_object($resql);
1304
1305 // Note: $obj->halfday is 0:Full days, 2:Start afternoon end morning, -1:Start afternoon, 1:End morning
1306 $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);
1307 $i++;
1308 }
1309
1310 // We found a record, user is on holiday by default, so is not available is true.
1311 $isavailablemorning = true;
1312 foreach ($arrayofrecord as $record) {
1313 if ($timestamp == $record['date_start'] && $record['halfday'] == 2) {
1314 continue;
1315 }
1316 if ($timestamp == $record['date_start'] && $record['halfday'] == -1) {
1317 continue;
1318 }
1319 $isavailablemorning = false;
1320 break;
1321 }
1322 $isavailableafternoon = true;
1323 foreach ($arrayofrecord as $record) {
1324 if ($timestamp == $record['date_end'] && $record['halfday'] == 2) {
1325 continue;
1326 }
1327 if ($timestamp == $record['date_end'] && $record['halfday'] == 1) {
1328 continue;
1329 }
1330 $isavailableafternoon = false;
1331 break;
1332 }
1333 }
1334 } else {
1335 dol_print_error($this->db);
1336 }
1337
1338 $result = array('morning' => $isavailablemorning, 'afternoon' => $isavailableafternoon);
1339 if (!$isavailablemorning) {
1340 $result['morning_reason'] = 'leave_request';
1341 }
1342 if (!$isavailableafternoon) {
1343 $result['afternoon_reason'] = 'leave_request';
1344 }
1345 return $result;
1346 }
1347
1355 public function getTooltipContentArray($params)
1356 {
1357 global $langs;
1358
1359 $langs->load('holiday');
1360 $nofetch = !empty($params['nofetch']);
1361
1362 $datas = array();
1363 $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Holiday").'</u>';
1364 if (isset($this->status)) {
1365 $datas['picto'] .= ' '.$this->getLibStatut(5);
1366 }
1367 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
1368 // show type for this record only in ajax to not overload lists
1369 if (!$nofetch && !empty($this->fk_type)) {
1370 $typeleaves = $this->getTypes(1, -1);
1371 if (empty($typeleaves[$this->fk_type])) {
1372 $labeltoshow = $langs->trans("TypeWasDisabledOrRemoved", $this->fk_type);
1373 } else {
1374 $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']);
1375 }
1376 $datas['type'] = '<br><b>'.$langs->trans("Type") . ':</b> ' . $labeltoshow;
1377 }
1378 if (isset($this->halfday) && !empty($this->date_debut) && !empty($this->date_fin)) {
1379 $listhalfday = array(
1380 'morning' => $langs->trans("Morning"),
1381 "afternoon" => $langs->trans("Afternoon")
1382 );
1383 $starthalfday = ($this->halfday == -1 || $this->halfday == 2) ? 'afternoon' : 'morning';
1384 $endhalfday = ($this->halfday == 1 || $this->halfday == 2) ? 'morning' : 'afternoon';
1385 $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>';
1386 $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>';
1387 }
1388
1389
1390 return $datas;
1391 }
1392
1402 public function getNomUrl($withpicto = 0, $save_lastsearch_value = -1, $notooltip = 0, $morecss = '')
1403 {
1404 global $conf, $langs, $hookmanager;
1405
1406 if (!empty($conf->dol_no_mouse_hover)) {
1407 $notooltip = 1; // Force disable tooltips
1408 }
1409
1410 $result = '';
1411 $params = [
1412 'id' => $this->id,
1413 'objecttype' => $this->element,
1414 'nofetch' => 1,
1415 ];
1416 $classfortooltip = 'classfortooltip';
1417 $dataparams = '';
1418 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1419 $classfortooltip = 'classforajaxtooltip';
1420 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1421 $label = '';
1422 } else {
1423 $label = implode($this->getTooltipContentArray($params));
1424 }
1425
1426 $url = DOL_URL_ROOT.'/holiday/card.php?id='.$this->id;
1427
1428 //if ($option != 'nolink')
1429 //{
1430 // Add param to save lastsearch_values or not
1431 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1432 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1433 $add_save_lastsearch_values = 1;
1434 }
1435 if ($add_save_lastsearch_values) {
1436 $url .= '&save_lastsearch_values=1';
1437 }
1438 //}
1439
1440 $linkclose = '';
1441 if (empty($notooltip)) {
1442 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1443 $label = $langs->trans("ShowMyObject");
1444 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
1445 }
1446 $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
1447 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
1448 } else {
1449 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1450 }
1451
1452 $linkstart = '<a href="'.$url.'"';
1453 $linkstart .= $linkclose.'>';
1454 $linkend = '</a>';
1455
1456 $result .= $linkstart;
1457
1458 if ($withpicto) {
1459 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
1460 }
1461 if ($withpicto != 2) {
1462 $result .= $this->ref;
1463 }
1464 $result .= $linkend;
1465
1466 global $action;
1467 $hookmanager->initHooks(array($this->element . 'dao'));
1468 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1469 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1470 if ($reshook > 0) {
1471 $result = $hookmanager->resPrint;
1472 } else {
1473 $result .= $hookmanager->resPrint;
1474 }
1475 return $result;
1476 }
1477
1478
1485 public function getLibStatut($mode = 0)
1486 {
1487 return $this->LibStatut($this->status, $mode, $this->date_debut);
1488 }
1489
1490 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1499 public function LibStatut($status, $mode = 0, $startdate = '')
1500 {
1501 // phpcs:enable
1502 global $langs;
1503
1504 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
1505 global $langs;
1506 //$langs->load("mymodule");
1507 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP');
1508 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP');
1509 $this->labelStatus[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP');
1510 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP');
1511 $this->labelStatus[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP');
1512 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP');
1513 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP');
1514 $this->labelStatusShort[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP');
1515 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP');
1516 $this->labelStatusShort[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP');
1517 }
1518
1519 $params = array();
1520 $statusType = 'status6';
1521 if (!empty($startdate) && $startdate >= dol_now()) { // If not yet passed, we use a green "in live" color
1522 $statusType = 'status4';
1523 $params = array('tooltip' => $this->labelStatus[$status].' - '.$langs->trans("Forthcoming"));
1524 }
1525 if ($status == self::STATUS_DRAFT) {
1526 $statusType = 'status0';
1527 }
1528 if ($status == self::STATUS_VALIDATED) {
1529 $statusType = 'status1';
1530 }
1531 if ($status == self::STATUS_CANCELED) {
1532 $statusType = 'status9';
1533 }
1534 if ($status == self::STATUS_REFUSED) {
1535 $statusType = 'status9';
1536 }
1537
1538 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode, '', $params);
1539 }
1540
1541
1550 public function selectStatutCP($selected = 0, $htmlname = 'select_statut', $morecss = 'minwidth125')
1551 {
1552 global $langs;
1553
1554 // List of status label
1555 $name = array('DraftCP', 'ToReviewCP', 'ApprovedCP', 'CancelCP', 'RefuseCP');
1556 $nb = count($name) + 1;
1557
1558 // Select HTML
1559 $out = '<select name="'.$htmlname.'" id="'.$htmlname.'" class="flat'.($morecss ? ' '.$morecss : '').'">'."\n";
1560 $out .= '<option value="-1">&nbsp;</option>'."\n";
1561
1562 // Loop on status
1563 for ($i = 1; $i < $nb; $i++) {
1564 if ($i == $selected) {
1565 $out .= '<option value="'.$i.'" selected>'.$langs->trans($name[$i - 1]).'</option>'."\n";
1566 } else {
1567 $out .= '<option value="'.$i.'">'.$langs->trans($name[$i - 1]).'</option>'."\n";
1568 }
1569 }
1570
1571 $out .= "</select>\n";
1572
1573 $showempty = 0;
1574 $out .= ajax_combobox($htmlname, array(), 0, 0, 'resolve', ($showempty < 0 ? (string) $showempty : '-1'), $morecss);
1575
1576 return $out;
1577 }
1578
1586 public function updateConfCP($name, $value)
1587 {
1588 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
1589 $sql .= " value = '".$this->db->escape($value)."'";
1590 $sql .= " WHERE name = '".$this->db->escape($name)."'";
1591
1592 dol_syslog(get_class($this).'::updateConfCP name='.$name, LOG_DEBUG);
1593 $result = $this->db->query($sql);
1594 if ($result) {
1595 return true;
1596 }
1597
1598 return false;
1599 }
1600
1609 public function getConfCP($name, $createifnotfound = '')
1610 {
1611 $sql = "SELECT value";
1612 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_config";
1613 $sql .= " WHERE name = '".$this->db->escape($name)."'";
1614
1615 dol_syslog(get_class($this).'::getConfCP name='.$name.' createifnotfound='.$createifnotfound, LOG_DEBUG);
1616 $result = $this->db->query($sql);
1617
1618 if ($result) {
1619 $obj = $this->db->fetch_object($result);
1620 // Return value
1621 if (empty($obj)) {
1622 if ($createifnotfound) {
1623 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_config(name, value)";
1624 $sql .= " VALUES('".$this->db->escape($name)."', '".$this->db->escape($createifnotfound)."')";
1625 $result = $this->db->query($sql);
1626 if ($result) {
1627 return $createifnotfound;
1628 } else {
1629 $this->error = $this->db->lasterror();
1630 return -2;
1631 }
1632 } else {
1633 return '';
1634 }
1635 } else {
1636 return $obj->value;
1637 }
1638 } else {
1639 // Erreur SQL
1640 $this->error = $this->db->lasterror();
1641 return -1;
1642 }
1643 }
1644
1653 public function updateSoldeCP($userID = 0, $nbHoliday = 0, $fk_type = 0)
1654 {
1655 global $user, $langs;
1656
1657 $error = 0;
1658
1659 if (empty($userID) && empty($nbHoliday) && empty($fk_type)) {
1660 $langs->load("holiday");
1661
1662 // Si mise à jour pour tout le monde en début de mois
1663 $now = dol_now();
1664
1665 $month = date('m', $now);
1666 $newdateforlastupdate = dol_print_date($now, '%Y%m%d%H%M%S');
1667
1668 // Get month of last update
1669 $lastUpdate = $this->getConfCP('lastUpdate', $newdateforlastupdate);
1670 $monthLastUpdate = $lastUpdate[4].$lastUpdate[5];
1671 //print 'month: '.$month.' lastUpdate:'.$lastUpdate.' monthLastUpdate:'.$monthLastUpdate;exit;
1672
1673 // 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.
1674 if ($month != $monthLastUpdate) {
1675 $this->db->begin();
1676
1677 $users = $this->fetchUsers(false, false, ' AND u.statut > 0');
1678 $nbUser = count($users);
1679
1680 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
1681 $sql .= " value = '".$this->db->escape($newdateforlastupdate)."'";
1682 $sql .= " WHERE name = 'lastUpdate'";
1683 $result = $this->db->query($sql);
1684
1685 $typeleaves = $this->getTypes(1, 1);
1686
1687 // Update each user counter
1688 foreach ($users as $userCounter) {
1689 $nbDaysToAdd = (isset($typeleaves[$userCounter['type']]['newbymonth']) ? $typeleaves[$userCounter['type']]['newbymonth'] : 0);
1690 if (empty($nbDaysToAdd)) {
1691 continue;
1692 }
1693
1694 dol_syslog("We update leave type id ".$userCounter['type']." for user id ".$userCounter['rowid'], LOG_DEBUG);
1695
1696 $nowHoliday = $userCounter['nb_holiday'];
1697 $newSolde = $nowHoliday + $nbDaysToAdd;
1698
1699 // We add a log for each user
1700 $this->addLogCP($user->id, $userCounter['rowid'], $langs->trans('HolidaysMonthlyUpdate'), $newSolde, $userCounter['type']);
1701
1702 $result = $this->updateSoldeCP($userCounter['rowid'], $newSolde, $userCounter['type']);
1703
1704 if ($result < 0) {
1705 $error++;
1706 break;
1707 }
1708 }
1709
1710 if (!$error) {
1711 $this->db->commit();
1712 return 1;
1713 } else {
1714 $this->db->rollback();
1715 return -1;
1716 }
1717 }
1718
1719 return 0;
1720 } else {
1721 // Mise à jour pour un utilisateur
1722 $nbHoliday = price2num($nbHoliday, 5);
1723
1724 $sql = "SELECT nb_holiday FROM ".MAIN_DB_PREFIX."holiday_users";
1725 $sql .= " WHERE fk_user = ".(int) $userID." AND fk_type = ".(int) $fk_type;
1726 $resql = $this->db->query($sql);
1727 if ($resql) {
1728 $num = $this->db->num_rows($resql);
1729
1730 if ($num > 0) {
1731 // Update for user
1732 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_users SET";
1733 $sql .= " nb_holiday = ".((float) $nbHoliday);
1734 $sql .= " WHERE fk_user = ".(int) $userID." AND fk_type = ".(int) $fk_type;
1735 $result = $this->db->query($sql);
1736 if (!$result) {
1737 $error++;
1738 $this->errors[] = $this->db->lasterror();
1739 }
1740 } else {
1741 // Insert for user
1742 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users(nb_holiday, fk_user, fk_type) VALUES (";
1743 $sql .= ((float) $nbHoliday);
1744 $sql .= ", ".(int) $userID.", ".(int) $fk_type.")";
1745 $result = $this->db->query($sql);
1746 if (!$result) {
1747 $error++;
1748 $this->errors[] = $this->db->lasterror();
1749 }
1750 }
1751 } else {
1752 $this->errors[] = $this->db->lasterror();
1753 $error++;
1754 }
1755
1756 if (!$error) {
1757 return 1;
1758 } else {
1759 return -1;
1760 }
1761 }
1762 }
1763
1771 public function createCPusers($single = false, $userid = 0)
1772 {
1773 // do we have to add balance for all users ?
1774 if (!$single) {
1775 dol_syslog(get_class($this).'::createCPusers');
1776 $arrayofusers = $this->fetchUsers(false, true);
1777
1778 foreach ($arrayofusers as $users) {
1779 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users";
1780 $sql .= " (fk_user, nb_holiday)";
1781 $sql .= " VALUES (".((int) $users['rowid'])."', '0')";
1782
1783 $resql = $this->db->query($sql);
1784 if (!$resql) {
1785 dol_print_error($this->db);
1786 }
1787 }
1788 } else {
1789 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users";
1790 $sql .= " (fk_user, nb_holiday)";
1791 $sql .= " VALUES (".((int) $userid)."', '0')";
1792
1793 $resql = $this->db->query($sql);
1794 if (!$resql) {
1795 dol_print_error($this->db);
1796 }
1797 }
1798 }
1799
1807 public function getCPforUser($user_id, $fk_type = 0)
1808 {
1809 $sql = "SELECT nb_holiday";
1810 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users";
1811 $sql .= " WHERE fk_user = ".(int) $user_id;
1812 if ($fk_type > 0) {
1813 $sql .= " AND fk_type = ".(int) $fk_type;
1814 }
1815
1816 dol_syslog(get_class($this).'::getCPforUser user_id='.$user_id.' type_id='.$fk_type, LOG_DEBUG);
1817 $result = $this->db->query($sql);
1818 if ($result) {
1819 $obj = $this->db->fetch_object($result);
1820 //return number_format($obj->nb_holiday,2);
1821 if ($obj) {
1822 return $obj->nb_holiday;
1823 } else {
1824 return null;
1825 }
1826 } else {
1827 return null;
1828 }
1829 }
1830
1839 public function fetchUsers($stringlist = true, $type = true, $filters = '')
1840 {
1841 global $conf;
1842
1843 dol_syslog(get_class($this)."::fetchUsers", LOG_DEBUG);
1844
1845 if ($stringlist) {
1846 if ($type) {
1847 // If user of Dolibarr
1848 $sql = "SELECT";
1849 if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
1850 $sql .= " DISTINCT";
1851 }
1852 $sql .= " u.rowid";
1853 $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
1854
1855 if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
1856 $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
1857 $sql .= " WHERE ((ug.fk_user = u.rowid";
1858 $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
1859 $sql .= " OR u.entity = 0)"; // Show always superadmin
1860 } else {
1861 $sql .= " WHERE u.entity IN (".getEntity('user').")";
1862 }
1863 $sql .= " AND u.statut > 0";
1864 $sql .= " AND u.employee = 1"; // We only want employee users for holidays
1865 if ($filters) {
1866 $sql .= $filters;
1867 }
1868
1869 $resql = $this->db->query($sql);
1870
1871 // Si pas d'erreur SQL
1872 if ($resql) {
1873 $i = 0;
1874 $num = $this->db->num_rows($resql);
1875 $stringlist = '';
1876
1877 // Boucles du listage des utilisateurs
1878 while ($i < $num) {
1879 $obj = $this->db->fetch_object($resql);
1880
1881 if ($i == 0) {
1882 $stringlist .= $obj->rowid;
1883 } else {
1884 $stringlist .= ', '.$obj->rowid;
1885 }
1886
1887 $i++;
1888 }
1889 // Retoune le tableau des utilisateurs
1890 return $stringlist;
1891 } else {
1892 // Erreur SQL
1893 $this->error = "Error ".$this->db->lasterror();
1894 return -1;
1895 }
1896 } else {
1897 // We want only list of vacation balance for user ids
1898 $sql = "SELECT DISTINCT cpu.fk_user";
1899 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u";
1900 $sql .= " WHERE cpu.fk_user = u.rowid";
1901 if ($filters) {
1902 $sql .= $filters;
1903 }
1904
1905 $resql = $this->db->query($sql);
1906
1907 // Si pas d'erreur SQL
1908 if ($resql) {
1909 $i = 0;
1910 $num = $this->db->num_rows($resql);
1911 $stringlist = '';
1912
1913 // Boucles du listage des utilisateurs
1914 while ($i < $num) {
1915 $obj = $this->db->fetch_object($resql);
1916
1917 if ($i == 0) {
1918 $stringlist .= $obj->fk_user;
1919 } else {
1920 $stringlist .= ', '.$obj->fk_user;
1921 }
1922
1923 $i++;
1924 }
1925 // Retoune le tableau des utilisateurs
1926 return $stringlist;
1927 } else {
1928 // Erreur SQL
1929 $this->error = "Error ".$this->db->lasterror();
1930 return -1;
1931 }
1932 }
1933 } else {
1934 // Si faux donc return array
1935 // List for Dolibarr users
1936 if ($type) {
1937 // If we need users of Dolibarr
1938 $sql = "SELECT";
1939 if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
1940 $sql .= " DISTINCT";
1941 }
1942 $sql .= " u.rowid, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut as status, u.fk_user";
1943 $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
1944
1945 if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
1946 $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
1947 $sql .= " WHERE ((ug.fk_user = u.rowid";
1948 $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
1949 $sql .= " OR u.entity = 0)"; // Show always superadmin
1950 } else {
1951 $sql .= " WHERE u.entity IN (".getEntity('user').")";
1952 }
1953
1954 $sql .= " AND u.statut > 0";
1955 $sql .= " AND u.employee = 1"; // We only want employee users for holidays
1956 if ($filters) {
1957 $sql .= $filters;
1958 }
1959
1960 $resql = $this->db->query($sql);
1961
1962 // Si pas d'erreur SQL
1963 if ($resql) {
1964 $i = 0;
1965 $tab_result = $this->holiday;
1966 $num = $this->db->num_rows($resql);
1967
1968 // Boucles du listage des utilisateurs
1969 while ($i < $num) {
1970 $obj = $this->db->fetch_object($resql);
1971
1972 $tab_result[$i]['rowid'] = $obj->rowid; // rowid of user
1973 $tab_result[$i]['id'] = $obj->rowid; // id of user
1974 $tab_result[$i]['name'] = $obj->lastname; // deprecated
1975 $tab_result[$i]['lastname'] = $obj->lastname;
1976 $tab_result[$i]['firstname'] = $obj->firstname;
1977 $tab_result[$i]['gender'] = $obj->gender;
1978 $tab_result[$i]['status'] = $obj->status;
1979 $tab_result[$i]['employee'] = $obj->employee;
1980 $tab_result[$i]['photo'] = $obj->photo;
1981 $tab_result[$i]['fk_user'] = $obj->fk_user; // rowid of manager
1982 //$tab_result[$i]['type'] = $obj->type;
1983 //$tab_result[$i]['nb_holiday'] = $obj->nb_holiday;
1984
1985 $i++;
1986 }
1987 // Retoune le tableau des utilisateurs
1988 return $tab_result;
1989 } else {
1990 // Erreur SQL
1991 $this->errors[] = "Error ".$this->db->lasterror();
1992 return -1;
1993 }
1994 } else {
1995 // List of vacation balance users
1996 $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";
1997 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u";
1998 $sql .= " WHERE cpu.fk_user = u.rowid";
1999 if ($filters) {
2000 $sql .= $filters;
2001 }
2002
2003 $resql = $this->db->query($sql);
2004
2005 // Si pas d'erreur SQL
2006 if ($resql) {
2007 $i = 0;
2008 $tab_result = $this->holiday;
2009 $num = $this->db->num_rows($resql);
2010
2011 // Boucles du listage des utilisateurs
2012 while ($i < $num) {
2013 $obj = $this->db->fetch_object($resql);
2014
2015 $tab_result[$i]['rowid'] = $obj->rowid; // rowid of user
2016 $tab_result[$i]['id'] = $obj->rowid; // id of user
2017 $tab_result[$i]['name'] = $obj->lastname; // deprecated
2018 $tab_result[$i]['lastname'] = $obj->lastname;
2019 $tab_result[$i]['firstname'] = $obj->firstname;
2020 $tab_result[$i]['gender'] = $obj->gender;
2021 $tab_result[$i]['status'] = $obj->status;
2022 $tab_result[$i]['employee'] = $obj->employee;
2023 $tab_result[$i]['photo'] = $obj->photo;
2024 $tab_result[$i]['fk_user'] = $obj->fk_user; // rowid of manager
2025
2026 $tab_result[$i]['type'] = $obj->fk_type;
2027 $tab_result[$i]['nb_holiday'] = $obj->nb_holiday;
2028
2029 $i++;
2030 }
2031 // Retoune le tableau des utilisateurs
2032 return $tab_result;
2033 } else {
2034 // Erreur SQL
2035 $this->error = "Error ".$this->db->lasterror();
2036 return -1;
2037 }
2038 }
2039 }
2040 }
2041
2042
2043 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2051 {
2052 // phpcs:enable
2053 $users_validator = array();
2054
2055 $sql = "SELECT DISTINCT ur.fk_user";
2056 $sql .= " FROM ".MAIN_DB_PREFIX."user_rights as ur, ".MAIN_DB_PREFIX."rights_def as rd";
2057 $sql .= " WHERE ur.fk_id = rd.id and rd.module = 'holiday' AND rd.perms = 'approve'"; // Permission 'Approve';
2058 $sql .= "UNION";
2059 $sql .= " SELECT DISTINCT ugu.fk_user";
2060 $sql .= " FROM ".MAIN_DB_PREFIX."usergroup_user as ugu, ".MAIN_DB_PREFIX."usergroup_rights as ur, ".MAIN_DB_PREFIX."rights_def as rd";
2061 $sql .= " WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'holiday' AND rd.perms = 'approve'"; // Permission 'Approve';
2062 //print $sql;
2063
2064 dol_syslog(get_class($this)."::fetch_users_approver_holiday sql=".$sql);
2065 $result = $this->db->query($sql);
2066 if ($result) {
2067 $num_rows = $this->db->num_rows($result);
2068 $i = 0;
2069 while ($i < $num_rows) {
2070 $objp = $this->db->fetch_object($result);
2071 array_push($users_validator, $objp->fk_user);
2072 $i++;
2073 }
2074 return $users_validator;
2075 } else {
2076 $this->error = $this->db->lasterror();
2077 dol_syslog(get_class($this)."::fetch_users_approver_holiday Error ".$this->error, LOG_ERR);
2078 return -1;
2079 }
2080 }
2081
2082
2088 public function countActiveUsers()
2089 {
2090 $sql = "SELECT count(u.rowid) as compteur";
2091 $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
2092 $sql .= " WHERE u.statut > 0";
2093
2094 $result = $this->db->query($sql);
2095 $object = $this->db->fetch_object($result);
2096
2097 return $object->compteur;
2098 }
2105 {
2106 $sql = "SELECT count(u.rowid) as compteur";
2107 $sql .= " FROM ".MAIN_DB_PREFIX."user as u LEFT OUTER JOIN ".MAIN_DB_PREFIX."holiday_users hu ON (hu.fk_user=u.rowid)";
2108 $sql .= " WHERE u.statut > 0 AND hu.fk_user IS NULL";
2109
2110 $result = $this->db->query($sql);
2111 $object = $this->db->fetch_object($result);
2112
2113 return $object->compteur;
2114 }
2115
2123 public function verifNbUsers($userDolibarrWithoutCP, $userCP)
2124 {
2125 if (empty($userCP)) {
2126 $userCP = 0;
2127 }
2128 dol_syslog(get_class($this).'::verifNbUsers userDolibarr='.$userDolibarrWithoutCP.' userCP='.$userCP);
2129 return 1;
2130 }
2131
2132
2143 public function addLogCP($fk_user_action, $fk_user_update, $label, $new_solde, $fk_type)
2144 {
2145 global $conf, $langs;
2146
2147 $error = 0;
2148
2149 $prev_solde = price2num($this->getCPforUser($fk_user_update, $fk_type), 5);
2150 $new_solde = price2num($new_solde, 5);
2151 //print "$prev_solde == $new_solde";
2152
2153 if ($prev_solde == $new_solde) {
2154 return 0;
2155 }
2156
2157 $this->db->begin();
2158
2159 // Insert request
2160 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_logs (";
2161 $sql .= "date_action,";
2162 $sql .= "fk_user_action,";
2163 $sql .= "fk_user_update,";
2164 $sql .= "type_action,";
2165 $sql .= "prev_solde,";
2166 $sql .= "new_solde,";
2167 $sql .= "fk_type";
2168 $sql .= ") VALUES (";
2169 $sql .= " '".$this->db->idate(dol_now())."',";
2170 $sql .= " ".((int) $fk_user_action).",";
2171 $sql .= " ".((int) $fk_user_update).",";
2172 $sql .= " '".$this->db->escape($label)."',";
2173 $sql .= " ".((float) $prev_solde).",";
2174 $sql .= " ".((float) $new_solde).",";
2175 $sql .= " ".((int) $fk_type);
2176 $sql .= ")";
2177
2178 $resql = $this->db->query($sql);
2179 if (!$resql) {
2180 $error++;
2181 $this->errors[] = "Error ".$this->db->lasterror();
2182 }
2183
2184 if (!$error) {
2185 $this->optRowid = $this->db->last_insert_id(MAIN_DB_PREFIX."holiday_logs");
2186 }
2187
2188 // Commit or rollback
2189 if ($error) {
2190 foreach ($this->errors as $errmsg) {
2191 dol_syslog(get_class($this)."::addLogCP ".$errmsg, LOG_ERR);
2192 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
2193 }
2194 $this->db->rollback();
2195 return -1 * $error;
2196 } else {
2197 $this->db->commit();
2198 return $this->optRowid;
2199 }
2200 }
2201
2209 public function fetchLog($order, $filter)
2210 {
2211 $sql = "SELECT";
2212 $sql .= " cpl.rowid,";
2213 $sql .= " cpl.date_action,";
2214 $sql .= " cpl.fk_user_action,";
2215 $sql .= " cpl.fk_user_update,";
2216 $sql .= " cpl.type_action,";
2217 $sql .= " cpl.prev_solde,";
2218 $sql .= " cpl.new_solde,";
2219 $sql .= " cpl.fk_type";
2220 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_logs as cpl";
2221 $sql .= " WHERE cpl.rowid > 0"; // To avoid error with other search and criteria
2222
2223 // Filtrage de séléction
2224 if (!empty($filter)) {
2225 $sql .= " ".$filter;
2226 }
2227
2228 // Ordre d'affichage
2229 if (!empty($order)) {
2230 $sql .= " ".$order;
2231 }
2232
2233 dol_syslog(get_class($this)."::fetchLog", LOG_DEBUG);
2234 $resql = $this->db->query($sql);
2235
2236 // Si pas d'erreur SQL
2237 if ($resql) {
2238 $i = 0;
2239 $tab_result = $this->logs;
2240 $num = $this->db->num_rows($resql);
2241
2242 // Si pas d'enregistrement
2243 if (!$num) {
2244 return 2;
2245 }
2246
2247 // On liste les résultats et on les ajoutent dans le tableau
2248 while ($i < $num) {
2249 $obj = $this->db->fetch_object($resql);
2250
2251 $tab_result[$i]['rowid'] = $obj->rowid;
2252 $tab_result[$i]['id'] = $obj->rowid;
2253 $tab_result[$i]['date_action'] = $obj->date_action;
2254 $tab_result[$i]['fk_user_action'] = $obj->fk_user_action;
2255 $tab_result[$i]['fk_user_update'] = $obj->fk_user_update;
2256 $tab_result[$i]['type_action'] = $obj->type_action;
2257 $tab_result[$i]['prev_solde'] = $obj->prev_solde;
2258 $tab_result[$i]['new_solde'] = $obj->new_solde;
2259 $tab_result[$i]['fk_type'] = $obj->fk_type;
2260
2261 $i++;
2262 }
2263 // Retourne 1 et ajoute le tableau à la variable
2264 $this->logs = $tab_result;
2265 return 1;
2266 } else {
2267 // Erreur SQL
2268 $this->error = "Error ".$this->db->lasterror();
2269 return -1;
2270 }
2271 }
2272
2273
2281 public function getTypes($active = -1, $affect = -1)
2282 {
2283 global $mysoc;
2284
2285 $sql = "SELECT rowid, code, label, affect, delay, newbymonth";
2286 $sql .= " FROM ".MAIN_DB_PREFIX."c_holiday_types";
2287 $sql .= " WHERE (fk_country IS NULL OR fk_country = ".((int) $mysoc->country_id).')';
2288 $sql .= " AND entity IN (".getEntity('c_holiday_types').")";
2289 if ($active >= 0) {
2290 $sql .= " AND active = ".((int) $active);
2291 }
2292 if ($affect >= 0) {
2293 $sql .= " AND affect = ".((int) $affect);
2294 }
2295 $sql .= " ORDER BY sortorder";
2296
2297 $result = $this->db->query($sql);
2298 if ($result) {
2299 $num = $this->db->num_rows($result);
2300 if ($num) {
2301 $types = array();
2302 while ($obj = $this->db->fetch_object($result)) {
2303 $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);
2304 }
2305
2306 return $types;
2307 }
2308 } else {
2309 dol_print_error($this->db);
2310 }
2311
2312 return array();
2313 }
2314
2315
2322 public function info($id)
2323 {
2324 global $conf;
2325
2326 $sql = "SELECT f.rowid, f.statut as status,";
2327 $sql .= " f.date_create as datec,";
2328 $sql .= " f.tms as date_modification,";
2329 $sql .= " f.date_valid as datev,";
2330 $sql .= " f.date_approval as datea,";
2331 $sql .= " f.date_refuse as dater,";
2332 $sql .= " f.fk_user_create as fk_user_creation,";
2333 $sql .= " f.fk_user_modif as fk_user_modification,";
2334 $sql .= " f.fk_user_valid as fk_user_validation,";
2335 $sql .= " f.fk_user_approve as fk_user_approval_done,";
2336 $sql .= " f.fk_validator as fk_user_approval_expected,";
2337 $sql .= " f.fk_user_refuse as fk_user_refuse";
2338 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as f";
2339 $sql .= " WHERE f.rowid = ".((int) $id);
2340 $sql .= " AND f.entity = ".$conf->entity;
2341
2342 $resql = $this->db->query($sql);
2343 if ($resql) {
2344 if ($this->db->num_rows($resql)) {
2345 $obj = $this->db->fetch_object($resql);
2346
2347 $this->id = $obj->rowid;
2348
2349 $this->date_creation = $this->db->jdate($obj->datec);
2350 $this->date_modification = $this->db->jdate($obj->date_modification);
2351 $this->date_validation = $this->db->jdate($obj->datev);
2352 $this->date_approval = $this->db->jdate($obj->datea);
2353
2354 $this->user_creation_id = $obj->fk_user_creation;
2355 $this->user_validation_id = $obj->fk_user_validation;
2356 $this->user_modification_id = $obj->fk_user_modification;
2357
2358 if ($obj->status == Holiday::STATUS_APPROVED || $obj->status == Holiday::STATUS_CANCELED) {
2359 if ($obj->fk_user_approval_done) {
2360 $this->fk_user_approve = $obj->fk_user_approval_done;
2361 }
2362 }
2363 }
2364 $this->db->free($resql);
2365 } else {
2366 dol_print_error($this->db);
2367 }
2368 }
2369
2370
2378 public function initAsSpecimen()
2379 {
2380 global $user, $langs;
2381
2382 // Initialise parameters
2383 $this->id = 0;
2384 $this->specimen = 1;
2385
2386 $this->fk_user = $user->id;
2387 $this->description = 'SPECIMEN description';
2388 $this->date_debut = dol_now();
2389 $this->date_fin = dol_now() + (24 * 3600);
2390 $this->date_valid = dol_now();
2391 $this->fk_validator = $user->id;
2392 $this->halfday = 0;
2393 $this->fk_type = 1;
2395
2396 return 1;
2397 }
2398
2404 public function loadStateBoard()
2405 {
2406 global $user;
2407
2408 $this->nb = array();
2409
2410 $sql = "SELECT count(h.rowid) as nb";
2411 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
2412 $sql .= " WHERE h.statut > 1";
2413 $sql .= " AND h.entity IN (".getEntity('holiday').")";
2414 if (!$user->hasRight('expensereport', 'readall')) {
2415 $userchildids = $user->getAllChildIds(1);
2416 $sql .= " AND (h.fk_user IN (".$this->db->sanitize(implode(',', $userchildids)).")";
2417 $sql .= " OR h.fk_validator IN (".$this->db->sanitize(implode(',', $userchildids))."))";
2418 }
2419
2420 $resql = $this->db->query($sql);
2421 if ($resql) {
2422 while ($obj = $this->db->fetch_object($resql)) {
2423 $this->nb["holidays"] = $obj->nb;
2424 }
2425 $this->db->free($resql);
2426 return 1;
2427 } else {
2428 dol_print_error($this->db);
2429 $this->error = $this->db->error();
2430 return -1;
2431 }
2432 }
2433
2434 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2441 public function load_board($user)
2442 {
2443 // phpcs:enable
2444 global $conf, $langs;
2445
2446 if ($user->socid) {
2447 return -1; // protection pour eviter appel par utilisateur externe
2448 }
2449
2450 $now = dol_now();
2451
2452 $sql = "SELECT h.rowid, h.date_debut";
2453 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
2454 $sql .= " WHERE h.statut = 2";
2455 $sql .= " AND h.entity IN (".getEntity('holiday').")";
2456 if (!$user->hasRight('expensereport', 'read_all')) {
2457 $userchildids = $user->getAllChildIds(1);
2458 $sql .= " AND (h.fk_user IN (".$this->db->sanitize(implode(',', $userchildids)).")";
2459 $sql .= " OR h.fk_validator IN (".$this->db->sanitize(implode(',', $userchildids))."))";
2460 }
2461
2462 $resql = $this->db->query($sql);
2463 if ($resql) {
2464 $langs->load("members");
2465
2466 $response = new WorkboardResponse();
2467 $response->warning_delay = $conf->holiday->approve->warning_delay / 60 / 60 / 24;
2468 $response->label = $langs->trans("HolidaysToApprove");
2469 $response->labelShort = $langs->trans("ToApprove");
2470 $response->url = DOL_URL_ROOT.'/holiday/list.php?search_status=2&amp;mainmenu=hrm&amp;leftmenu=holiday';
2471 $response->img = img_object('', "holiday");
2472
2473 while ($obj = $this->db->fetch_object($resql)) {
2474 $response->nbtodo++;
2475
2476 if ($this->db->jdate($obj->date_debut) < ($now - $conf->holiday->approve->warning_delay)) {
2477 $response->nbtodolate++;
2478 }
2479 }
2480
2481 return $response;
2482 } else {
2483 dol_print_error($this->db);
2484 $this->error = $this->db->error();
2485 return -1;
2486 }
2487 }
2495 public function getKanbanView($option = '', $arraydata = null)
2496 {
2497 global $langs;
2498
2499 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
2500
2501 $return = '<div class="box-flex-item box-flex-grow-zero">';
2502 $return .= '<div class="info-box info-box-sm">';
2503 $return .= '<span class="info-box-icon bg-infobox-action">';
2504 $return .= img_picto('', $this->picto);
2505 $return .= '</span>';
2506 $return .= '<div class="info-box-content">';
2507 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.$arraydata['user']->getNomUrl(-1).'</span>';
2508 if ($selected >= 0) {
2509 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
2510 }
2511 if (property_exists($this, 'fk_type')) {
2512 $return .= '<br>';
2513 //$return .= '<span class="opacitymedium">'.$langs->trans("Type").'</span> : ';
2514 $return .= '<div class="info_box-label tdoverflowmax100" title="'.dol_escape_htmltag($arraydata['labeltype']).'">'.dol_escape_htmltag($arraydata['labeltype']).'</div>';
2515 }
2516 if (property_exists($this, 'date_debut') && property_exists($this, 'date_fin')) {
2517 $return .= '<span class="info-box-label small">'.dol_print_date($this->date_debut, 'day').'</span>';
2518 $return .= ' <span class="opacitymedium small">'.$langs->trans("To").'</span> ';
2519 $return .= '<span class="info-box-label small">'.dol_print_date($this->date_fin, 'day').'</span>';
2520 if (!empty($arraydata['nbopenedday'])) {
2521 $return .= ' ('.$arraydata['nbopenedday'].')';
2522 }
2523 }
2524 if (method_exists($this, 'getLibStatut')) {
2525 $return .= '<div class="info-box-status">'.$this->getLibStatut(3).'</div>';
2526 }
2527 $return .= '</div>';
2528 $return .= '</div>';
2529 $return .= '</div>';
2530 return $return;
2531 }
2532}
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:637
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:456
$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 clicable 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 clicable link of object (with eventually picto)
LibStatut($status, $mode=0, $startdate='')
Returns the label of a status.
num_open_day($timestampStart, $timestampEnd, $inhour=0, $lastday=0, $halfday=0, $country_code='')
Function to return number of working days (and text of units) between two dates (working days)
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 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...
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall TAKEPOS_SHOW_SUBPRICE right right right takeposterminal SELECT e e e e e statut
Definition invoice.php:2043