dolibarr 23.0.4
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-2025 Frédéric France <frederic.france@free.fr>
8 * Copyright (C) 2024-2025 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
46 public $TRIGGER_PREFIX = 'HOLIDAY';
47
51 public $table_element = 'holiday';
52
56 public $fk_element = 'fk_holiday';
57
61 public $picto = 'holiday';
62
66 public $fk_user;
67
71 public $date_create = '';
72
76 public $description;
77
81 public $date_debut = '';
82
86 public $date_fin = '';
87
91 public $date_debut_gmt = '';
92
96 public $date_fin_gmt = '';
97
101 public $halfday = '';
102
107 public $statut = 0;
108
112 public $fk_validator;
113
117 public $date_valid = 0;
118
122 public $fk_user_valid;
123
127 public $date_approval;
128
132 public $fk_user_approve;
133
137 public $date_refuse = 0;
138
142 public $fk_user_refuse;
143
147 public $date_cancel = 0;
148
152 public $fk_user_cancel;
153
157 public $fk_user_create;
158
162 public $detail_refuse = '';
163
167 public $fk_type;
168
169 public $holiday = array();
170 public $events = array();
171
175 public $logs = array();
176
177
181 const STATUS_DRAFT = 1;
197 const STATUS_REFUSED = 5;
198
199
205 public function __construct($db)
206 {
207 $this->db = $db;
208
209 $this->ismultientitymanaged = 0;
210 }
211
212
220 public function getNextNumRef($objsoc)
221 {
222 global $langs, $conf;
223 $langs->load("order");
224
225 if (!getDolGlobalString('HOLIDAY_ADDON')) {
226 $conf->global->HOLIDAY_ADDON = 'mod_holiday_madonna';
227 }
228
229 if (getDolGlobalString('HOLIDAY_ADDON')) {
230 $mybool = false;
231
232 $file = getDolGlobalString('HOLIDAY_ADDON') . ".php";
233 $classname = getDolGlobalString('HOLIDAY_ADDON');
234
235 // Include file with class
236 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
237 foreach ($dirmodels as $reldir) {
238 $dir = dol_buildpath($reldir."core/modules/holiday/");
239
240 // Load file with numbering class (if found)
241 $mybool = ((bool) @include_once $dir.$file) || $mybool;
242 }
243
244 if (!$mybool) {
245 dol_print_error(null, "Failed to include file ".$file);
246 return '';
247 }
248
249 $obj = new $classname();
250 '@phan-var-force ModelNumRefHolidays $obj';
251 $numref = $obj->getNextValue($objsoc, $this);
252
253 if ($numref != "") {
254 return $numref;
255 } else {
256 $this->error = $obj->error;
257 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
258 return "";
259 }
260 } else {
261 print $langs->trans("Error")." ".$langs->trans("Error_HOLIDAY_ADDON_NotDefined");
262 return "";
263 }
264 }
265
271 public function updateBalance()
272 {
273 $this->db->begin();
274
275 // Update sold of vocations
276 $result = $this->updateSoldeCP();
277
278 // Check nb of users into table llx_holiday_users and update with empty lines
279 //if ($result > 0) $result = $this->verifNbUsers($this->countActiveUsersWithoutCP(), $this->getConfCP('nbUser'));
280
281 if ($result >= 0) {
282 $this->db->commit();
283 return 0; // for cronjob use (0 is OK, any other value is an error code)
284 } else {
285 $this->db->rollback();
286 return -1;
287 }
288 }
289
297 public function create($user, $notrigger = 0)
298 {
299 global $conf;
300 $error = 0;
301
302 $now = dol_now();
303
304 // Check parameters
305 if (empty($this->fk_user) || !is_numeric($this->fk_user) || $this->fk_user < 0) {
306 $this->error = "ErrorBadParameterFkUser";
307 return -1;
308 }
309 if (empty($this->fk_validator) || !is_numeric($this->fk_validator) || $this->fk_validator < 0) {
310 $this->error = "ErrorBadParameterFkValidator";
311 return -1;
312 }
313 if (empty($this->fk_type) || !is_numeric($this->fk_type) || $this->fk_type < 0) {
314 $this->error = "ErrorBadParameterFkType";
315 return -1;
316 }
317
318 // Insert request
319 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday(";
320 $sql .= "ref,";
321 $sql .= "fk_user,";
322 $sql .= "date_create,";
323 $sql .= "description,";
324 $sql .= "date_debut,";
325 $sql .= "date_fin,";
326 $sql .= "halfday,";
327 $sql .= "statut,";
328 $sql .= "fk_validator,";
329 $sql .= "fk_type,";
330 $sql .= "fk_user_create,";
331 $sql .= "entity";
332 $sql .= ") VALUES (";
333 $sql .= "'(PROV)',";
334 $sql .= " ".((int) $this->fk_user).",";
335 $sql .= " '".$this->db->idate($now)."',";
336 $sql .= " '".$this->db->escape($this->description)."',";
337 $sql .= " '".$this->db->idate($this->date_debut)."',";
338 $sql .= " '".$this->db->idate($this->date_fin)."',";
339 $sql .= " ".((int) $this->halfday).",";
340 $sql .= " '1',";
341 $sql .= " ".((int) $this->fk_validator).",";
342 $sql .= " ".((int) $this->fk_type).",";
343 $sql .= " ".((int) $user->id).",";
344 $sql .= " ".((int) $conf->entity);
345 $sql .= ")";
346
347 $this->db->begin();
348
349 dol_syslog(get_class($this)."::create", LOG_DEBUG);
350 $resql = $this->db->query($sql);
351 if (!$resql) {
352 $error++;
353 $this->errors[] = "Error ".$this->db->lasterror();
354 }
355
356 if (!$error) {
357 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."holiday");
358
359 if ($this->id) {
360 // update ref
361 $initialref = '(PROV'.$this->id.')';
362 if (!empty($this->ref)) {
363 $initialref = $this->ref;
364 }
365
366 $sql = 'UPDATE '.MAIN_DB_PREFIX."holiday SET ref='".$this->db->escape($initialref)."' WHERE rowid=".((int) $this->id);
367 if ($this->db->query($sql)) {
368 $this->ref = $initialref;
369
370 if (!$error) {
371 $result = $this->insertExtraFields();
372 if ($result < 0) {
373 $error++;
374 }
375 }
376
377 if (!$error && !$notrigger) {
378 // Call trigger
379 $result = $this->call_trigger('HOLIDAY_CREATE', $user);
380 if ($result < 0) {
381 $error++;
382 }
383 // End call triggers
384 }
385 }
386 }
387 }
388
389 // Commit or rollback
390 if ($error) {
391 foreach ($this->errors as $errmsg) {
392 dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR);
393 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
394 }
395 $this->db->rollback();
396 return -1 * $error;
397 } else {
398 $this->db->commit();
399 return $this->id;
400 }
401 }
402
403
411 public function fetch($id, $ref = '')
412 {
413 $sql = "SELECT";
414 $sql .= " cp.rowid,";
415 $sql .= " cp.ref,";
416 $sql .= " cp.fk_user,";
417 $sql .= " cp.date_create,";
418 $sql .= " cp.description,";
419 $sql .= " cp.date_debut,";
420 $sql .= " cp.date_fin,";
421 $sql .= " cp.halfday,";
422 $sql .= " cp.statut as status,";
423 $sql .= " cp.fk_validator,";
424 $sql .= " cp.date_valid,";
425 $sql .= " cp.fk_user_valid,";
426 $sql .= " cp.date_approval,";
427 $sql .= " cp.fk_user_approve,";
428 $sql .= " cp.date_refuse,";
429 $sql .= " cp.fk_user_refuse,";
430 $sql .= " cp.date_cancel,";
431 $sql .= " cp.fk_user_cancel,";
432 $sql .= " cp.detail_refuse,";
433 $sql .= " cp.note_private,";
434 $sql .= " cp.note_public,";
435 $sql .= " cp.fk_user_create,";
436 $sql .= " cp.fk_type,";
437 $sql .= " cp.entity";
438 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp";
439 if ($id > 0) {
440 $sql .= " WHERE cp.rowid = ".((int) $id);
441 } else {
442 $sql .= " WHERE cp.ref = '".$this->db->escape($ref)."'";
443 }
444
445 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
446 $resql = $this->db->query($sql);
447 if ($resql) {
448 if ($this->db->num_rows($resql)) {
449 $obj = $this->db->fetch_object($resql);
450
451 $this->id = $obj->rowid;
452 $this->ref = ($obj->ref ? $obj->ref : $obj->rowid);
453 $this->fk_user = $obj->fk_user;
454 $this->date_create = $this->db->jdate($obj->date_create);
455 $this->description = $obj->description;
456 $this->date_debut = $this->db->jdate($obj->date_debut);
457 $this->date_fin = $this->db->jdate($obj->date_fin);
458 $this->date_debut_gmt = $this->db->jdate($obj->date_debut, 1);
459 $this->date_fin_gmt = $this->db->jdate($obj->date_fin, 1);
460 $this->halfday = $obj->halfday;
461 $this->status = $obj->status;
462 $this->statut = $obj->status; // deprecated
463 $this->fk_validator = $obj->fk_validator;
464 $this->date_valid = $this->db->jdate($obj->date_valid);
465 $this->fk_user_valid = $obj->fk_user_valid;
466 $this->user_validation_id = $obj->fk_user_valid;
467 $this->date_approval = $this->db->jdate($obj->date_approval);
468 $this->fk_user_approve = $obj->fk_user_approve;
469 $this->date_refuse = $this->db->jdate($obj->date_refuse);
470 $this->fk_user_refuse = $obj->fk_user_refuse;
471 $this->date_cancel = $this->db->jdate($obj->date_cancel);
472 $this->fk_user_cancel = $obj->fk_user_cancel;
473 $this->detail_refuse = $obj->detail_refuse;
474 $this->note_private = $obj->note_private;
475 $this->note_public = $obj->note_public;
476 $this->fk_user_create = $obj->fk_user_create;
477 $this->fk_type = $obj->fk_type;
478 $this->entity = $obj->entity;
479
480 $this->fetch_optionals();
481
482 $result = 1;
483 } else {
484 $result = 0;
485 }
486 $this->db->free($resql);
487
488 return $result;
489 } else {
490 $this->error = "Error ".$this->db->lasterror();
491 return -1;
492 }
493 }
494
503 public function fetchByUser($user_id, $order = '', $filter = '')
504 {
505 $this->holiday = [];
506 $sql = "SELECT";
507 $sql .= " cp.rowid,";
508 $sql .= " cp.ref,";
509
510 $sql .= " cp.fk_user,";
511 $sql .= " cp.fk_type,";
512 $sql .= " cp.date_create,";
513 $sql .= " cp.description,";
514 $sql .= " cp.date_debut,";
515 $sql .= " cp.date_fin,";
516 $sql .= " cp.halfday,";
517 $sql .= " cp.statut as status,";
518 $sql .= " cp.fk_validator,";
519 $sql .= " cp.date_valid,";
520 $sql .= " cp.fk_user_valid,";
521 $sql .= " cp.date_approval,";
522 $sql .= " cp.fk_user_approve,";
523 $sql .= " cp.date_refuse,";
524 $sql .= " cp.fk_user_refuse,";
525 $sql .= " cp.date_cancel,";
526 $sql .= " cp.fk_user_cancel,";
527 $sql .= " cp.detail_refuse,";
528
529 $sql .= " uu.lastname as user_lastname,";
530 $sql .= " uu.firstname as user_firstname,";
531 $sql .= " uu.login as user_login,";
532 $sql .= " uu.statut as user_status,";
533 $sql .= " uu.photo as user_photo,";
534 $sql .= " uu.fk_country as country_id,";
535
536 $sql .= " ua.lastname as validator_lastname,";
537 $sql .= " ua.firstname as validator_firstname,";
538 $sql .= " ua.login as validator_login,";
539 $sql .= " ua.statut as validator_status,";
540 $sql .= " ua.photo as validator_photo";
541
542 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp, ".MAIN_DB_PREFIX."user as uu, ".MAIN_DB_PREFIX."user as ua";
543 $sql .= " WHERE cp.entity IN (".getEntity('holiday').")";
544 $sql .= " AND cp.fk_user = uu.rowid AND cp.fk_validator = ua.rowid"; // Hack pour la recherche sur le tableau
545 $sql .= " AND cp.fk_user IN (".$this->db->sanitize($user_id).")";
546
547 // Selection filter
548 if (!empty($filter)) {
549 $sql .= $filter;
550 }
551
552 // Order of display of the result
553 if (!empty($order)) {
554 $sql .= $order;
555 }
556
557 dol_syslog(get_class($this)."::fetchByUser", LOG_DEBUG);
558 $resql = $this->db->query($sql);
559
560 // If no SQL error
561 if ($resql) {
562 $i = 0;
563 $tab_result = $this->holiday;
564 $num = $this->db->num_rows($resql);
565
566 // If no registration
567 if (!$num) {
568 return 2;
569 }
570
571 // List the records and add them to the table
572 while ($i < $num) {
573 $obj = $this->db->fetch_object($resql);
574
575 $tab_result[$i]['rowid'] = $obj->rowid;
576 $tab_result[$i]['id'] = $obj->rowid;
577 $tab_result[$i]['ref'] = ($obj->ref ? $obj->ref : $obj->rowid);
578
579 $tab_result[$i]['fk_user'] = $obj->fk_user;
580 $tab_result[$i]['fk_type'] = $obj->fk_type;
581 $tab_result[$i]['date_create'] = $this->db->jdate($obj->date_create);
582 $tab_result[$i]['description'] = $obj->description;
583 $tab_result[$i]['date_debut'] = $this->db->jdate($obj->date_debut);
584 $tab_result[$i]['date_fin'] = $this->db->jdate($obj->date_fin);
585 $tab_result[$i]['date_debut_gmt'] = $this->db->jdate($obj->date_debut, 1);
586 $tab_result[$i]['date_fin_gmt'] = $this->db->jdate($obj->date_fin, 1);
587 $tab_result[$i]['halfday'] = $obj->halfday;
588 $tab_result[$i]['statut'] = $obj->status;
589 $tab_result[$i]['status'] = $obj->status;
590 $tab_result[$i]['fk_validator'] = $obj->fk_validator;
591 $tab_result[$i]['date_valid'] = $this->db->jdate($obj->date_valid);
592 $tab_result[$i]['fk_user_valid'] = $obj->fk_user_valid;
593 $tab_result[$i]['date_approval'] = $this->db->jdate($obj->date_approval);
594 $tab_result[$i]['fk_user_approve'] = $obj->fk_user_approve;
595 $tab_result[$i]['date_refuse'] = $this->db->jdate($obj->date_refuse);
596 $tab_result[$i]['fk_user_refuse'] = $obj->fk_user_refuse;
597 $tab_result[$i]['date_cancel'] = $this->db->jdate($obj->date_cancel);
598 $tab_result[$i]['fk_user_cancel'] = $obj->fk_user_cancel;
599 $tab_result[$i]['detail_refuse'] = $obj->detail_refuse;
600
601 $tab_result[$i]['user_firstname'] = $obj->user_firstname;
602 $tab_result[$i]['user_lastname'] = $obj->user_lastname;
603 $tab_result[$i]['user_login'] = $obj->user_login;
604 $tab_result[$i]['user_statut'] = $obj->user_status;
605 $tab_result[$i]['user_status'] = $obj->user_status;
606 $tab_result[$i]['user_photo'] = $obj->user_photo;
607
608 $tab_result[$i]['validator_firstname'] = $obj->validator_firstname;
609 $tab_result[$i]['validator_lastname'] = $obj->validator_lastname;
610 $tab_result[$i]['validator_login'] = $obj->validator_login;
611 $tab_result[$i]['validator_statut'] = $obj->validator_status;
612 $tab_result[$i]['validator_status'] = $obj->validator_status;
613 $tab_result[$i]['validator_photo'] = $obj->validator_photo;
614
615 $tab_result[$i]['country_id'] = (int) $obj->country_id; // id of country of user
616
617 $i++;
618 }
619
620 // Returns 1 with the filled array
621 $this->holiday = $tab_result;
622 return 1;
623 } else {
624 // SQL Error
625 $this->error = "Error ".$this->db->lasterror();
626 return -1;
627 }
628 }
629
637 public function fetchAll($order, $filter)
638 {
639 $sql = "SELECT";
640 $sql .= " cp.rowid,";
641 $sql .= " cp.ref,";
642 $sql .= " cp.fk_user,";
643 $sql .= " cp.fk_type,";
644 $sql .= " cp.date_create,";
645 $sql .= " cp.tms as date_modification,";
646 $sql .= " cp.description,";
647 $sql .= " cp.date_debut,";
648 $sql .= " cp.date_fin,";
649 $sql .= " cp.halfday,";
650 $sql .= " cp.statut as status,";
651 $sql .= " cp.fk_validator,";
652 $sql .= " cp.date_valid,";
653 $sql .= " cp.fk_user_valid,";
654 $sql .= " cp.date_approval,";
655 $sql .= " cp.fk_user_approve,";
656 $sql .= " cp.date_refuse,";
657 $sql .= " cp.fk_user_refuse,";
658 $sql .= " cp.date_cancel,";
659 $sql .= " cp.fk_user_cancel,";
660 $sql .= " cp.detail_refuse,";
661
662 $sql .= " uu.lastname as user_lastname,";
663 $sql .= " uu.firstname as user_firstname,";
664 $sql .= " uu.login as user_login,";
665 $sql .= " uu.statut as user_status,";
666 $sql .= " uu.photo as user_photo,";
667
668 $sql .= " ua.lastname as validator_lastname,";
669 $sql .= " ua.firstname as validator_firstname,";
670 $sql .= " ua.login as validator_login,";
671 $sql .= " ua.statut as validator_status,";
672 $sql .= " ua.photo as validator_photo";
673
674 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp, ".MAIN_DB_PREFIX."user as uu, ".MAIN_DB_PREFIX."user as ua";
675 $sql .= " WHERE cp.entity IN (".getEntity('holiday').")";
676 $sql .= " AND cp.fk_user = uu.rowid AND cp.fk_validator = ua.rowid "; // Hack pour la recherche sur le tableau
677
678 // Selection filtering
679 if (!empty($filter)) {
680 $sql .= $filter;
681 }
682
683 // order of display
684 if (!empty($order)) {
685 $sql .= $order;
686 }
687
688 dol_syslog(get_class($this)."::fetchAll", LOG_DEBUG);
689 $resql = $this->db->query($sql);
690
691 // If no SQL error
692 if ($resql) {
693 $i = 0;
694 $tab_result = $this->holiday;
695 $num = $this->db->num_rows($resql);
696
697 // If no registration
698 if (!$num) {
699 return 2;
700 }
701
702 // List the records and add them to the table
703 while ($i < $num) {
704 $obj = $this->db->fetch_object($resql);
705
706 $tab_result[$i]['rowid'] = $obj->rowid;
707 $tab_result[$i]['id'] = $obj->rowid;
708 $tab_result[$i]['ref'] = ($obj->ref ? $obj->ref : $obj->rowid);
709
710 $tab_result[$i]['fk_user'] = $obj->fk_user;
711 $tab_result[$i]['fk_type'] = $obj->fk_type;
712 $tab_result[$i]['date_create'] = $this->db->jdate($obj->date_create);
713 $tab_result[$i]['date_modification'] = $this->db->jdate($obj->date_modification);
714 $tab_result[$i]['description'] = $obj->description;
715 $tab_result[$i]['date_debut'] = $this->db->jdate($obj->date_debut);
716 $tab_result[$i]['date_fin'] = $this->db->jdate($obj->date_fin);
717 $tab_result[$i]['date_debut_gmt'] = $this->db->jdate($obj->date_debut, 1);
718 $tab_result[$i]['date_fin_gmt'] = $this->db->jdate($obj->date_fin, 1);
719 $tab_result[$i]['halfday'] = $obj->halfday;
720 $tab_result[$i]['statut'] = $obj->status;
721 $tab_result[$i]['status'] = $obj->status;
722 $tab_result[$i]['fk_validator'] = $obj->fk_validator;
723 $tab_result[$i]['date_valid'] = $this->db->jdate($obj->date_valid);
724 $tab_result[$i]['fk_user_valid'] = $obj->fk_user_valid;
725 $tab_result[$i]['date_approval'] = $this->db->jdate($obj->date_approval);
726 $tab_result[$i]['fk_user_approve'] = $obj->fk_user_approve;
727 $tab_result[$i]['date_refuse'] = $obj->date_refuse;
728 $tab_result[$i]['fk_user_refuse'] = $obj->fk_user_refuse;
729 $tab_result[$i]['date_cancel'] = $obj->date_cancel;
730 $tab_result[$i]['fk_user_cancel'] = $obj->fk_user_cancel;
731 $tab_result[$i]['detail_refuse'] = $obj->detail_refuse;
732
733 $tab_result[$i]['user_firstname'] = $obj->user_firstname;
734 $tab_result[$i]['user_lastname'] = $obj->user_lastname;
735 $tab_result[$i]['user_login'] = $obj->user_login;
736 $tab_result[$i]['user_statut'] = $obj->user_status;
737 $tab_result[$i]['user_status'] = $obj->user_status;
738 $tab_result[$i]['user_photo'] = $obj->user_photo;
739
740 $tab_result[$i]['validator_firstname'] = $obj->validator_firstname;
741 $tab_result[$i]['validator_lastname'] = $obj->validator_lastname;
742 $tab_result[$i]['validator_login'] = $obj->validator_login;
743 $tab_result[$i]['validator_statut'] = $obj->validator_status;
744 $tab_result[$i]['validator_status'] = $obj->validator_status;
745 $tab_result[$i]['validator_photo'] = $obj->validator_photo;
746
747 $i++;
748 }
749 // Returns 1 and adds the array to the variable
750 $this->holiday = $tab_result;
751 return 1;
752 } else {
753 // SQL Error
754 $this->error = "Error ".$this->db->lasterror();
755 return -1;
756 }
757 }
758
759
767 public function validate($user = null, $notrigger = 0)
768 {
769 global $conf, $langs;
770 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
771 $error = 0;
772
773
774 $checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type, true);
775
776 if ($checkBalance > 0) {
777 $balance = $this->getCPforUser($this->fk_user, $this->fk_type);
778 // Use the GMT variants: num_public_holiday(), called by num_open_day(), refuses a range whose
779 // length is not a whole number of days, and a range spanning a DST transition is 23h or 25h
780 // long in the server timezone. It then returns a string and the subtraction fatals.
781 $datedebutforcount = !empty($this->date_debut_gmt) ? $this->date_debut_gmt : $this->date_debut;
782 $datefinforcount = !empty($this->date_fin_gmt) ? $this->date_fin_gmt : $this->date_fin;
783 $daysAsked = num_open_day($datedebutforcount, $datefinforcount, 0, 1, (int) $this->halfday);
784
785 if (($balance - $daysAsked) < 0) {
786 $this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
787 return -1;
788 }
789 }
790
791 // Define new ref
792 if (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref) || $this->ref == $this->id) {
793 $num = $this->getNextNumRef(null);
794 } else {
795 $num = (string) $this->ref;
796 }
797 $this->newref = dol_sanitizeFileName($num);
798
799 // Update status
800 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
801 $sql .= " fk_user_valid = ".((int) $user->id).",";
802 $sql .= " date_valid = '".$this->db->idate(dol_now())."',";
803 if (!empty($this->status) && is_numeric($this->status)) {
804 $sql .= " statut = ".((int) $this->status).",";
805 } else {
806 $this->error = 'Property status must be a numeric value';
807 $error++;
808 }
809 $sql .= " ref = '".$this->db->escape($num)."'";
810 $sql .= " WHERE rowid = ".((int) $this->id);
811
812 $this->db->begin();
813
814 dol_syslog(get_class($this)."::validate", LOG_DEBUG);
815 $resql = $this->db->query($sql);
816 if (!$resql) {
817 $error++;
818 $this->errors[] = "Error ".$this->db->lasterror();
819 }
820
821 if (!$error) {
822 if (!$notrigger) {
823 // Call trigger
824 $result = $this->call_trigger('HOLIDAY_VALIDATE', $user);
825 if ($result < 0) {
826 $error++;
827 }
828 // End call triggers
829 }
830 }
831
832 if (!$error) {
833 $this->oldref = $this->ref;
834
835 // Rename directory if dir was a temporary ref
836 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
837 // Now we rename also files into index
838 $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) . "'";
839 $sql .= " WHERE filename LIKE '" . $this->db->escape($this->ref) . "%' AND filepath = 'holiday/" . $this->db->escape($this->ref) . "' and entity = " . ((int) $conf->entity);
840 $resql = $this->db->query($sql);
841 if (!$resql) {
842 $error++;
843 $this->error = $this->db->lasterror();
844 }
845 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'holiday/".$this->db->escape($this->newref)."'";
846 $sql .= " WHERE filepath = 'holiday/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
847 $resql = $this->db->query($sql);
848 if (!$resql) {
849 $error++;
850 $this->error = $this->db->lasterror();
851 }
852
853 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
854 $oldref = dol_sanitizeFileName($this->ref);
855 $newref = dol_sanitizeFileName($num);
856 $dirsource = $conf->holiday->multidir_output[$this->entity] . '/' . $oldref;
857 $dirdest = $conf->holiday->multidir_output[$this->entity] . '/' . $newref;
858 if (!$error && file_exists($dirsource)) {
859 dol_syslog(get_class($this) . "::validate rename dir " . $dirsource . " into " . $dirdest);
860 if (@rename($dirsource, $dirdest)) {
861 dol_syslog("Rename ok");
862 // Rename docs starting with $oldref with $newref
863 $listoffiles = dol_dir_list($dirdest, 'files', 1, '^' . preg_quote($oldref, '/'));
864 foreach ($listoffiles as $fileentry) {
865 $dirsource = $fileentry['name'];
866 $dirdest = preg_replace('/^' . preg_quote($oldref, '/') . '/', $newref, $dirsource);
867 $dirsource = $fileentry['path'] . '/' . $dirsource;
868 $dirdest = $fileentry['path'] . '/' . $dirdest;
869 @rename($dirsource, $dirdest);
870 }
871 }
872 }
873 }
874 }
875
876
877 // Commit or rollback
878 if ($error) {
879 foreach ($this->errors as $errmsg) {
880 dol_syslog(get_class($this)."::validate ".$errmsg, LOG_ERR);
881 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
882 }
883 $this->db->rollback();
884 return -1 * $error;
885 } else {
886 $this->db->commit();
887 return 1;
888 }
889 }
890
891
899 public function approve($user = null, $notrigger = 0)
900 {
901 $error = 0;
902
903 $checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type, true);
904
905 if ($checkBalance > 0) {
906 $balance = $this->getCPforUser($this->fk_user, $this->fk_type);
907 // Use the GMT variants: num_public_holiday(), called by num_open_day(), refuses a range whose
908 // length is not a whole number of days, and a range spanning a DST transition is 23h or 25h
909 // long in the server timezone. It then returns a string and the subtraction fatals.
910 $datedebutforcount = !empty($this->date_debut_gmt) ? $this->date_debut_gmt : $this->date_debut;
911 $datefinforcount = !empty($this->date_fin_gmt) ? $this->date_fin_gmt : $this->date_fin;
912 $daysAsked = num_open_day($datedebutforcount, $datefinforcount, 0, 1, (int) $this->halfday);
913
914 if (($balance - $daysAsked) < 0) {
915 $this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
916 return -1;
917 }
918 }
919
920 // Update request
921 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
922 $sql .= " description= '".$this->db->escape($this->description)."',";
923 if (!empty($this->date_debut)) {
924 $sql .= " date_debut = '".$this->db->idate($this->date_debut)."',";
925 } else {
926 $error++;
927 }
928 if (!empty($this->date_fin)) {
929 $sql .= " date_fin = '".$this->db->idate($this->date_fin)."',";
930 } else {
931 $error++;
932 }
933 $sql .= " halfday = ".((int) $this->halfday).",";
934 if (!empty($this->status) && is_numeric($this->status)) {
935 $sql .= " statut = ".((int) $this->status).",";
936 } else {
937 $error++;
938 }
939 if (!empty($this->fk_validator)) {
940 $sql .= " fk_validator = ".((int) $this->fk_validator).",";
941 } else {
942 $error++;
943 }
944 if (!empty($this->date_valid)) {
945 $sql .= " date_valid = '".$this->db->idate($this->date_valid)."',";
946 } else {
947 $sql .= " date_valid = NULL,";
948 }
949 if (!empty($this->fk_user_valid)) {
950 $sql .= " fk_user_valid = ".((int) $this->fk_user_valid).",";
951 } else {
952 $sql .= " fk_user_valid = NULL,";
953 }
954 if (!empty($this->date_approval)) {
955 $sql .= " date_approval = '".$this->db->idate($this->date_approval)."',";
956 } else {
957 $sql .= " date_approval = NULL,";
958 }
959 if (!empty($this->fk_user_approve)) {
960 $sql .= " fk_user_approve = ".((int) $this->fk_user_approve).",";
961 } else {
962 $sql .= " fk_user_approve = NULL,";
963 }
964 if (!empty($this->date_refuse)) {
965 $sql .= " date_refuse = '".$this->db->idate($this->date_refuse)."',";
966 } else {
967 $sql .= " date_refuse = NULL,";
968 }
969 if (!empty($this->fk_user_refuse)) {
970 $sql .= " fk_user_refuse = ".((int) $this->fk_user_refuse).",";
971 } else {
972 $sql .= " fk_user_refuse = NULL,";
973 }
974 if (!empty($this->date_cancel)) {
975 $sql .= " date_cancel = '".$this->db->idate($this->date_cancel)."',";
976 } else {
977 $sql .= " date_cancel = NULL,";
978 }
979 if (!empty($this->fk_user_cancel)) {
980 $sql .= " fk_user_cancel = ".((int) $this->fk_user_cancel).",";
981 } else {
982 $sql .= " fk_user_cancel = NULL,";
983 }
984 if (!empty($this->detail_refuse)) {
985 $sql .= " detail_refuse = '".$this->db->escape($this->detail_refuse)."'";
986 } else {
987 $sql .= " detail_refuse = NULL";
988 }
989 $sql .= " WHERE rowid = ".((int) $this->id);
990
991 $this->db->begin();
992
993 dol_syslog(get_class($this)."::approve", LOG_DEBUG);
994 $resql = $this->db->query($sql);
995 if (!$resql) {
996 $error++;
997 $this->errors[] = "Error ".$this->db->lasterror();
998 }
999
1000 if (!$error) {
1001 if (!$notrigger) {
1002 // Call trigger
1003 $result = $this->call_trigger('HOLIDAY_APPROVE', $user);
1004 if ($result < 0) {
1005 $error++;
1006 }
1007 // End call triggers
1008 }
1009 }
1010
1011 // Commit or rollback
1012 if ($error) {
1013 foreach ($this->errors as $errmsg) {
1014 dol_syslog(get_class($this)."::approve ".$errmsg, LOG_ERR);
1015 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1016 }
1017 $this->db->rollback();
1018 return -1 * $error;
1019 } else {
1020 $this->db->commit();
1021 return 1;
1022 }
1023 }
1024
1032 public function update($user = null, $notrigger = 0)
1033 {
1034 global $conf, $langs;
1035 $error = 0;
1036
1037 $checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type, true);
1038 if ($this->status == self::STATUS_REFUSED || $this->status == self::STATUS_APPROVED) {
1039 $checkBalance = 0; // No balance check to refuse a request, nor on an approved request (its days are already debited)
1040 }
1041
1042 if ($checkBalance > 0 && $this->statut != self::STATUS_DRAFT && $this->statut != self::STATUS_CANCELED) {
1043 $balance = $this->getCPforUser($this->fk_user, $this->fk_type);
1044 // Use the GMT variants: num_public_holiday(), called by num_open_day(), refuses a range whose
1045 // length is not a whole number of days, and a range spanning a DST transition is 23h or 25h
1046 // long in the server timezone. It then returns a string and the subtraction fatals.
1047 $datedebutforcount = !empty($this->date_debut_gmt) ? $this->date_debut_gmt : $this->date_debut;
1048 $datefinforcount = !empty($this->date_fin_gmt) ? $this->date_fin_gmt : $this->date_fin;
1049 $daysAsked = num_open_day($datedebutforcount, $datefinforcount, 0, 1, (int) $this->halfday);
1050
1051 if (($balance - $daysAsked) < 0) {
1052 $this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
1053 return -1;
1054 }
1055 }
1056
1057 // Update request
1058 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
1059
1060 $sql .= " description= '".$this->db->escape($this->description)."',";
1061
1062 if (!empty($this->date_debut)) {
1063 $sql .= " date_debut = '".$this->db->idate($this->date_debut)."',";
1064 } else {
1065 $error++;
1066 }
1067 if (!empty($this->date_fin)) {
1068 $sql .= " date_fin = '".$this->db->idate($this->date_fin)."',";
1069 } else {
1070 $error++;
1071 }
1072 $sql .= " halfday = ".((int) $this->halfday).",";
1073 if (!empty($this->status) && is_numeric($this->status)) {
1074 $sql .= " statut = ".((int) $this->status).",";
1075 } else {
1076 $error++;
1077 }
1078 if (!empty($this->fk_validator)) {
1079 $sql .= " fk_validator = ".((int) $this->fk_validator).",";
1080 } else {
1081 $error++;
1082 }
1083 if (!empty($this->date_valid)) {
1084 $sql .= " date_valid = '".$this->db->idate($this->date_valid)."',";
1085 } else {
1086 $sql .= " date_valid = NULL,";
1087 }
1088 if (!empty($this->fk_user_valid)) {
1089 $sql .= " fk_user_valid = ".((int) $this->fk_user_valid).",";
1090 } else {
1091 $sql .= " fk_user_valid = NULL,";
1092 }
1093 if (!empty($this->date_approval)) {
1094 $sql .= " date_approval = '".$this->db->idate($this->date_approval)."',";
1095 } else {
1096 $sql .= " date_approval = NULL,";
1097 }
1098 if (!empty($this->fk_user_approve)) {
1099 $sql .= " fk_user_approve = ".((int) $this->fk_user_approve).",";
1100 } else {
1101 $sql .= " fk_user_approve = NULL,";
1102 }
1103 if (!empty($this->date_refuse)) {
1104 $sql .= " date_refuse = '".$this->db->idate($this->date_refuse)."',";
1105 } else {
1106 $sql .= " date_refuse = NULL,";
1107 }
1108 if (!empty($this->fk_user_refuse)) {
1109 $sql .= " fk_user_refuse = ".((int) $this->fk_user_refuse).",";
1110 } else {
1111 $sql .= " fk_user_refuse = NULL,";
1112 }
1113 if (!empty($this->date_cancel)) {
1114 $sql .= " date_cancel = '".$this->db->idate($this->date_cancel)."',";
1115 } else {
1116 $sql .= " date_cancel = NULL,";
1117 }
1118 if (!empty($this->fk_user_cancel)) {
1119 $sql .= " fk_user_cancel = ".((int) $this->fk_user_cancel).",";
1120 } else {
1121 $sql .= " fk_user_cancel = NULL,";
1122 }
1123 if (!empty($this->detail_refuse)) {
1124 $sql .= " detail_refuse = '".$this->db->escape($this->detail_refuse)."'";
1125 } else {
1126 $sql .= " detail_refuse = NULL";
1127 }
1128
1129 $sql .= " WHERE rowid = ".((int) $this->id);
1130
1131 $this->db->begin();
1132
1133 dol_syslog(get_class($this)."::update", LOG_DEBUG);
1134 $resql = $this->db->query($sql);
1135 if (!$resql) {
1136 $error++;
1137 $this->errors[] = "Error ".$this->db->lasterror();
1138 }
1139
1140 if (!$error) {
1141 $result = $this->insertExtraFields();
1142 if ($result < 0) {
1143 $error++;
1144 }
1145 }
1146
1147 if (!$error) {
1148 if (!$notrigger && $user !== null) {
1149 // Call trigger
1150 $result = $this->call_trigger('HOLIDAY_MODIFY', $user);
1151 if ($result < 0) {
1152 $error++;
1153 }
1154 // End call triggers
1155 }
1156 }
1157
1158 // Commit or rollback
1159 if ($error) {
1160 foreach ($this->errors as $errmsg) {
1161 dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
1162 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1163 }
1164 $this->db->rollback();
1165 return -1 * $error;
1166 } else {
1167 $this->db->commit();
1168 return 1;
1169 }
1170 }
1171
1172
1180 public function delete($user, $notrigger = 0)
1181 {
1182 global $conf, $langs;
1183 $error = 0;
1184
1185 $sql = "DELETE FROM ".MAIN_DB_PREFIX."holiday";
1186 $sql .= " WHERE rowid=".((int) $this->id);
1187
1188 $this->db->begin();
1189
1190 // Delete extrafields before the leave request
1191 $result = $this->deleteExtraFields();
1192 if ($result < 0) {
1193 $error++;
1194 }
1195
1196 if (!$error) {
1197 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1198 $resql = $this->db->query($sql);
1199 if (!$resql) {
1200 $error++;
1201 $this->errors[] = "Error ".$this->db->lasterror();
1202 }
1203 }
1204
1205 if (!$error) {
1206 if (!$notrigger) {
1207 // Call trigger
1208 $result = $this->call_trigger('HOLIDAY_DELETE', $user);
1209 if ($result < 0) {
1210 $error++;
1211 }
1212 // End call triggers
1213 }
1214 }
1215
1216 // Commit or rollback
1217 if ($error) {
1218 foreach ($this->errors as $errmsg) {
1219 dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
1220 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1221 }
1222 $this->db->rollback();
1223 return -1 * $error;
1224 } else {
1225 $this->db->commit();
1226 return 1;
1227 }
1228 }
1229
1243 public function verifDateHolidayCP($fk_user, $dateStart, $dateEnd, $halfday = 0)
1244 {
1245 $this->fetchByUser($fk_user, '', '');
1246
1247 foreach ($this->holiday as $infos_CP) {
1248 if ($infos_CP['statut'] == Holiday::STATUS_CANCELED) {
1249 continue; // ignore not validated holidays
1250 }
1251 if ($infos_CP['statut'] == Holiday::STATUS_REFUSED) {
1252 continue; // ignore refused holidays
1253 }
1254 //var_dump("--");
1255 //var_dump("old: ".dol_print_date($infos_CP['date_debut'],'dayhour').' '.dol_print_date($infos_CP['date_fin'],'dayhour').' '.$infos_CP['halfday']);
1256 //var_dump("new: ".dol_print_date($dateStart,'dayhour').' '.dol_print_date($dateEnd,'dayhour').' '.$halfday);
1257
1258 if ($halfday == 0) {
1259 if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1260 return false;
1261 }
1262 if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1263 return false;
1264 }
1265 } elseif ($halfday == -1) {
1266 // new start afternoon, new end afternoon
1267 if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1268 if ($dateStart < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
1269 return false;
1270 }
1271 }
1272 if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1273 if ($dateStart < $dateEnd) {
1274 return false;
1275 }
1276 if ($dateEnd < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
1277 return false;
1278 }
1279 }
1280 } elseif ($halfday == 1) {
1281 // new start morning, new end morning
1282 if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1283 if ($dateStart < $dateEnd) {
1284 return false;
1285 }
1286 if ($dateStart > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
1287 return false;
1288 }
1289 }
1290 if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1291 if ($dateEnd > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
1292 return false;
1293 }
1294 }
1295 } elseif ($halfday == 2) {
1296 // new start afternoon, new end morning
1297 if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1298 if ($dateStart < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
1299 return false;
1300 }
1301 }
1302 if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1303 if ($dateEnd > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
1304 return false;
1305 }
1306 }
1307 } else {
1308 dol_print_error(null, 'Bad value of parameter halfday when calling function verifDateHolidayCP');
1309 }
1310 }
1311
1312 return true;
1313 }
1314
1315
1325 public function verifDateHolidayForTimestamp($fk_user, $timestamp, $status = '-1')
1326 {
1327 $isavailablemorning = true;
1328 $isavailableafternoon = true;
1329
1330 // Check into leave requests
1331 $sql = "SELECT cp.rowid, cp.date_debut as date_start, cp.date_fin as date_end, cp.halfday, cp.statut as status";
1332 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp";
1333 $sql .= " WHERE cp.entity IN (".getEntity('holiday').")";
1334 $sql .= " AND cp.fk_user = ".(int) $fk_user;
1335 $sql .= " AND cp.date_debut <= '".$this->db->idate($timestamp)."' AND cp.date_fin >= '".$this->db->idate($timestamp)."'";
1336 if ($status != '-1') {
1337 $sql .= " AND cp.statut IN (".$this->db->sanitize($status).")";
1338 }
1339
1340 $resql = $this->db->query($sql);
1341 if ($resql) {
1342 $num_rows = $this->db->num_rows($resql); // Note, we can have 2 records if on is morning and the other one is afternoon
1343 if ($num_rows > 0) {
1344 $arrayofrecord = array();
1345 $i = 0;
1346 while ($i < $num_rows) {
1347 $obj = $this->db->fetch_object($resql);
1348
1349 // Note: $obj->halfday is 0:Full days, 2:Start afternoon end morning, -1:Start afternoon, 1:End morning
1350 $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);
1351 $i++;
1352 }
1353
1354 // We found a record, user is on holiday by default, so is not available is true.
1355 $isavailablemorning = true;
1356 foreach ($arrayofrecord as $record) {
1357 if ($timestamp == $record['date_start'] && $record['halfday'] == 2) {
1358 continue;
1359 }
1360 if ($timestamp == $record['date_start'] && $record['halfday'] == -1) {
1361 continue;
1362 }
1363 $isavailablemorning = false;
1364 break;
1365 }
1366 $isavailableafternoon = true;
1367 foreach ($arrayofrecord as $record) {
1368 if ($timestamp == $record['date_end'] && $record['halfday'] == 2) {
1369 continue;
1370 }
1371 if ($timestamp == $record['date_end'] && $record['halfday'] == 1) {
1372 continue;
1373 }
1374 $isavailableafternoon = false;
1375 break;
1376 }
1377 }
1378 } else {
1379 dol_print_error($this->db);
1380 }
1381
1382 $result = array('morning' => (int) $isavailablemorning, 'afternoon' => (int) $isavailableafternoon);
1383 if (!$isavailablemorning) {
1384 $result['morning_reason'] = 'leave_request';
1385 }
1386 if (!$isavailableafternoon) {
1387 $result['afternoon_reason'] = 'leave_request';
1388 }
1389 return $result;
1390 }
1391
1398 public function getTooltipContentArray($params)
1399 {
1400 global $langs;
1401
1402 $langs->load('holiday');
1403 $nofetch = !empty($params['nofetch']);
1404
1405 $datas = array();
1406 $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Holiday").'</u>';
1407 if (isset($this->status)) {
1408 $datas['picto'] .= ' '.$this->getLibStatut(5);
1409 }
1410 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
1411 // show type for this record only in ajax to not overload lists
1412 if (!$nofetch && !empty($this->fk_type)) {
1413 $typeleaves = $this->getTypes(1, -1);
1414 if (empty($typeleaves[$this->fk_type])) {
1415 $labeltoshow = $langs->trans("TypeWasDisabledOrRemoved", $this->fk_type);
1416 } else {
1417 $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']);
1418 }
1419 $datas['type'] = '<br><b>'.$langs->trans("Type") . ':</b> ' . $labeltoshow;
1420 }
1421 if (isset($this->halfday) && !empty($this->date_debut) && !empty($this->date_fin)) {
1422 $listhalfday = array(
1423 'morning' => $langs->trans("Morning"),
1424 "afternoon" => $langs->trans("Afternoon")
1425 );
1426 $starthalfday = ($this->halfday == -1 || $this->halfday == 2) ? 'afternoon' : 'morning';
1427 $endhalfday = ($this->halfday == 1 || $this->halfday == 2) ? 'morning' : 'afternoon';
1428 $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>';
1429 $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>';
1430 }
1431
1432
1433 return $datas;
1434 }
1435
1445 public function getNomUrl($withpicto = 0, $save_lastsearch_value = -1, $notooltip = 0, $morecss = '')
1446 {
1447 global $conf, $langs, $hookmanager;
1448
1449 if (!empty($conf->dol_no_mouse_hover)) {
1450 $notooltip = 1; // Force disable tooltips
1451 }
1452
1453 $result = '';
1454 $params = [
1455 'id' => $this->id,
1456 'objecttype' => $this->element,
1457 'nofetch' => 1,
1458 ];
1459 $classfortooltip = 'classfortooltip';
1460 $dataparams = '';
1461 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1462 $classfortooltip = 'classforajaxtooltip';
1463 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1464 $label = '';
1465 } else {
1466 $label = implode($this->getTooltipContentArray($params));
1467 }
1468
1469 $url = DOL_URL_ROOT.'/holiday/card.php?id='.$this->id;
1470
1471 //if ($option != 'nolink')
1472 //{
1473 // Add param to save lastsearch_values or not
1474 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1475 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1476 $add_save_lastsearch_values = 1;
1477 }
1478 if ($add_save_lastsearch_values) {
1479 $url .= '&save_lastsearch_values=1';
1480 }
1481 //}
1482
1483 $linkclose = '';
1484 if (empty($notooltip)) {
1485 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1486 $label = $langs->trans("ShowMyObject");
1487 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
1488 }
1489 $linkclose .= ($label ? ' title="'.dolPrintHTMLForAttribute($label).'"' : ' title="tocomplete"');
1490 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
1491 } else {
1492 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1493 }
1494
1495 $linkstart = '<a href="'.$url.'"';
1496 $linkstart .= $linkclose.'>';
1497 $linkend = '</a>';
1498
1499 $result .= $linkstart;
1500
1501 if ($withpicto) {
1502 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
1503 }
1504 if ($withpicto != 2) {
1505 $result .= $this->ref;
1506 }
1507 $result .= $linkend;
1508
1509 global $action;
1510 $hookmanager->initHooks(array($this->element . 'dao'));
1511 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1512 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1513 if ($reshook > 0) {
1514 $result = $hookmanager->resPrint;
1515 } else {
1516 $result .= $hookmanager->resPrint;
1517 }
1518 return $result;
1519 }
1520
1521
1528 public function getLibStatut($mode = 0)
1529 {
1530 return $this->LibStatut($this->status, $mode, $this->date_debut);
1531 }
1532
1533 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1542 public function LibStatut($status, $mode = 0, $startdate = '')
1543 {
1544 // phpcs:enable
1545 global $langs;
1546
1547 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
1548 global $langs;
1549 //$langs->load("mymodule");
1550 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP');
1551 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP');
1552 $this->labelStatus[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP');
1553 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP');
1554 $this->labelStatus[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP');
1555 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP');
1556 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP');
1557 $this->labelStatusShort[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP');
1558 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP');
1559 $this->labelStatusShort[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP');
1560 }
1561
1562 $params = array();
1563 $statusType = 'status6';
1564 if (!empty($startdate) && $startdate >= dol_now()) { // If not yet passed, we use a green "in live" color
1565 $statusType = 'status4';
1566 $params = array('tooltip' => $this->labelStatus[$status].' - '.$langs->trans("Forthcoming"));
1567 }
1568 if ($status == self::STATUS_DRAFT) {
1569 $statusType = 'status0';
1570 }
1571 if ($status == self::STATUS_VALIDATED) {
1572 $statusType = 'status1';
1573 }
1574 if ($status == self::STATUS_CANCELED) {
1575 $statusType = 'status9';
1576 }
1577 if ($status == self::STATUS_REFUSED) {
1578 $statusType = 'status9';
1579 }
1580
1581 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode, '', $params);
1582 }
1583
1584
1593 public function selectStatutCP($selected = 0, $htmlname = 'select_statut', $morecss = 'minwidth125')
1594 {
1595 global $langs;
1596
1597 // List of status label
1598 $name = array('DraftCP', 'ToReviewCP', 'ApprovedCP', 'CancelCP', 'RefuseCP');
1599 $nb = count($name) + 1;
1600
1601 // Select HTML
1602 $out = '<select name="'.$htmlname.'" id="'.$htmlname.'" class="flat'.($morecss ? ' '.$morecss : '').'">'."\n";
1603 $out .= '<option value="-1">&nbsp;</option>'."\n";
1604
1605 // Loop on status
1606 for ($i = 1; $i < $nb; $i++) {
1607 if ($i == $selected) {
1608 $out .= '<option value="'.$i.'" selected>'.$langs->trans($name[$i - 1]).'</option>'."\n";
1609 } else {
1610 $out .= '<option value="'.$i.'">'.$langs->trans($name[$i - 1]).'</option>'."\n";
1611 }
1612 }
1613
1614 $out .= "</select>\n";
1615
1616 $showempty = 0;
1617 $out .= ajax_combobox($htmlname, array(), 0, 0, 'resolve', ($showempty < 0 ? (string) $showempty : '-1'), $morecss);
1618
1619 return $out;
1620 }
1621
1629 public function updateConfCP($name, $value)
1630 {
1631 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
1632 $sql .= " value = '".$this->db->escape($value)."'";
1633 $sql .= " WHERE name = '".$this->db->escape($name)."'";
1634
1635 dol_syslog(get_class($this).'::updateConfCP name='.$name, LOG_DEBUG);
1636 $result = $this->db->query($sql);
1637 if ($result) {
1638 return true;
1639 }
1640
1641 return false;
1642 }
1643
1652 public function getConfCP($name, $createifnotfound = '')
1653 {
1654 $sql = "SELECT value";
1655 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_config";
1656 $sql .= " WHERE name = '".$this->db->escape($name)."'";
1657
1658 dol_syslog(get_class($this).'::getConfCP name='.$name.' createifnotfound='.$createifnotfound, LOG_DEBUG);
1659 $result = $this->db->query($sql);
1660
1661 if ($result) {
1662 $obj = $this->db->fetch_object($result);
1663 // Return value
1664 if (empty($obj)) {
1665 if ($createifnotfound) {
1666 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_config(name, value)";
1667 $sql .= " VALUES('".$this->db->escape($name)."', '".$this->db->escape($createifnotfound)."')";
1668 $result = $this->db->query($sql);
1669 if ($result) {
1670 return $createifnotfound;
1671 } else {
1672 $this->error = $this->db->lasterror();
1673 return -2;
1674 }
1675 } else {
1676 return '';
1677 }
1678 } else {
1679 return $obj->value;
1680 }
1681 } else {
1682 // Erreur SQL
1683 $this->error = $this->db->lasterror();
1684 return -1;
1685 }
1686 }
1687
1696 public function updateSoldeCP($userID = 0, $nbHoliday = 0, $fk_type = 0)
1697 {
1698 global $user, $langs;
1699
1700 $error = 0;
1701
1702 if (empty($userID) && empty($nbHoliday) && empty($fk_type)) {
1703 $langs->load("holiday");
1704
1705 $decrease = getDolGlobalInt('HOLIDAY_DECREASE_AT_END_OF_MONTH');
1706
1707 // Si mise à jour pour tout le monde en début de mois
1708 $now = dol_now();
1709
1710 // Get month of last update
1711 $stringInDBForLastUpdate = $this->getConfCP('lastUpdate', dol_print_date($now, '%Y%m%d%H%M%S')); // Example '20200101120000'
1712 // The lastUpdate config row is created empty (value NULL) at install, so getConfCP() returns an empty value
1713 // the first time. Treat an empty value as "start from now" instead of a very old date, otherwise the catch-up
1714 // loop below would credit every user with years of monthly accrual at once. Store it, because the loop is the
1715 // only other place that writes it: an empty value would stay empty and no month would ever be credited.
1716 if (empty($stringInDBForLastUpdate)) {
1717 $stringInDBForLastUpdate = dol_print_date($now, '%Y%m%d%H%M%S');
1718
1719 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
1720 $sql .= " value = '".$this->db->escape($stringInDBForLastUpdate)."'";
1721 $sql .= " WHERE name = 'lastUpdate'";
1722 $result = $this->db->query($sql);
1723 if (!$result) {
1724 $this->error = $this->db->lasterror();
1725 return -1;
1726 }
1727 }
1728 // Protection when $lastUpdate has a not valid value
1729 if ($stringInDBForLastUpdate < '20000101000000') {
1730 $stringInDBForLastUpdate = '20000101000000';
1731 }
1732 $lastUpdate = dol_stringtotime($stringInDBForLastUpdate);
1733 //print 'lastUpdate:'.$lastUpdate;exit;
1734
1735 $yearMonthLastUpdate = dol_print_date($lastUpdate, '%Y%m');
1736 $yearMonthNow = dol_print_date($now, '%Y%m');
1737 //print 'yearMonthLastUpdate='.$yearMonthLastUpdate.' yearMonthNow='.$yearMonthNow;
1738
1739 // 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,
1740 // catching up to the current month if a gap is detected
1741 while ($yearMonthLastUpdate < $yearMonthNow) {
1742 $this->db->begin();
1743
1744 $year = dol_print_date($lastUpdate, '%Y');
1745 $month = dol_print_date($lastUpdate, '%m');
1746
1747 $users = $this->fetchUsers(false, false, ' AND u.statut > 0');
1748 $nbUser = count($users);
1749
1750 $typeleaves = $this->getTypes(1, 1);
1751
1752 // Update each user counter
1753 foreach ($users as $userCounter) {
1754 $nbDaysToAdd = (isset($typeleaves[$userCounter['type']]['newbymonth']) ? $typeleaves[$userCounter['type']]['newbymonth'] : 0);
1755 if (empty($nbDaysToAdd)) {
1756 continue;
1757 }
1758
1759 dol_syslog("We update leave type id ".$userCounter['type']." for user id ".$userCounter['rowid'], LOG_DEBUG);
1760
1761 $nowHoliday = (float) $userCounter['nb_holiday'];
1762 $newSolde = $nowHoliday + $nbDaysToAdd;
1763
1764 // We add a log for each user when its balance gets increased
1765 $this->addLogCP($user->id, $userCounter['rowid'], $langs->trans('HolidayMonthlyCredit'), $newSolde, $userCounter['type']);
1766
1767 $result = $this->updateSoldeCP($userCounter['rowid'], $newSolde, $userCounter['type']);
1768
1769 if ($result < 0) {
1770 $this->db->rollback();
1771 return -1;
1772 }
1773
1774 if (empty($decrease)) {
1775 continue;
1776 }
1777
1778 // We fetch a user's holiday in the current month and then calculate the number of days to deduct if he has at least one registered
1779 $filter = " AND cp.statut = ".((int) self::STATUS_APPROVED);
1780 $filter .= " AND cp.date_fin >= '".$this->db->idate(dol_stringtotime(dol_print_date($lastUpdate, '%Y-%m-01')))."'";
1781 $filter .= " AND cp.date_debut <= '".$this->db->idate(dol_stringtotime(dol_print_date($lastUpdate, '%Y-%m-t')))."'";
1782 $filter .= " AND cp.fk_type = ".((int) $userCounter['type']);
1783 $this->fetchByUser($userCounter['id'], '', $filter);
1784
1785 if (empty($this->holiday)) {
1786 continue;
1787 }
1788
1789 $startOfMonth = dol_mktime(0, 0, 0, (int) $month, 1, (int) $year, 1);
1790 $endOfMonth = dol_mktime(0, 0, 0, (int) $month, (int) dol_print_date($lastUpdate, 't'), (int) $year, 1);
1791
1792 foreach ($this->holiday as $obj) {
1793 $startDate = $obj['date_debut_gmt'];
1794 $endDate = $obj['date_fin_gmt'];
1795
1796 if ($startDate <= $endOfMonth && $startDate < $startOfMonth) {
1797 $startDate = $startOfMonth;
1798 }
1799
1800 if ($startOfMonth <= $endDate && $endDate > $endOfMonth) {
1801 $endDate = $endOfMonth;
1802 }
1803
1804 $nbDaysToDeduct = (float) num_open_day($startDate, $endDate, 0, 1, $obj['halfday'], $obj['country_id']);
1805
1806 if ($nbDaysToDeduct <= 0) {
1807 continue;
1808 }
1809
1810 $newSolde -= $nbDaysToDeduct;
1811
1812 // We add a log for each user when its balance gets decreased
1813 $this->addLogCP($user->id, $userCounter['rowid'], $obj['ref'].' - '.$langs->trans('HolidayConsumption'), $newSolde, $userCounter['type']);
1814
1815 $result = $this->updateSoldeCP($userCounter['rowid'], $newSolde, $userCounter['type']);
1816
1817 if ($result < 0) {
1818 $this->db->rollback();
1819 return -1;
1820 }
1821 }
1822 }
1823
1824 //updating the date of the last monthly balance update
1825 $newMonth = dol_get_next_month((int) dol_print_date($lastUpdate, '%m'), (int) dol_print_date($lastUpdate, '%Y'));
1826 $lastUpdate = dol_mktime(0, 0, 0, (int) $newMonth['month'], 1, (int) $newMonth['year']);
1827
1828 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
1829 $sql .= " value = '".$this->db->escape(dol_print_date($lastUpdate, '%Y%m%d%H%M%S'))."'";
1830 $sql .= " WHERE name = 'lastUpdate'";
1831 $result = $this->db->query($sql);
1832
1833 if (!$result) {
1834 $this->db->rollback();
1835 return -1;
1836 }
1837
1838 $this->db->commit();
1839
1840 $yearMonthLastUpdate = dol_print_date($lastUpdate, '%Y%m');
1841 }
1842
1843 if (!$error) {
1844 return 1;
1845 } else {
1846 return 0;
1847 }
1848 } else {
1849 // Mise à jour pour un utilisateur
1850 $nbHoliday = price2num($nbHoliday, 5);
1851
1852 $sql = "SELECT nb_holiday FROM ".MAIN_DB_PREFIX."holiday_users";
1853 $sql .= " WHERE fk_user = ".(int) $userID." AND fk_type = ".(int) $fk_type;
1854 $resql = $this->db->query($sql);
1855 if ($resql) {
1856 $num = $this->db->num_rows($resql);
1857
1858 if ($num > 0) {
1859 // Update for user
1860 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_users SET";
1861 $sql .= " nb_holiday = ".((float) $nbHoliday);
1862 $sql .= " WHERE fk_user = ".(int) $userID." AND fk_type = ".(int) $fk_type;
1863 $result = $this->db->query($sql);
1864 if (!$result) {
1865 $error++;
1866 $this->errors[] = $this->db->lasterror();
1867 }
1868 } else {
1869 // Insert for user
1870 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users(nb_holiday, fk_user, fk_type) VALUES (";
1871 $sql .= ((float) $nbHoliday);
1872 $sql .= ", ".(int) $userID.", ".(int) $fk_type.")";
1873 $result = $this->db->query($sql);
1874 if (!$result) {
1875 $error++;
1876 $this->errors[] = $this->db->lasterror();
1877 }
1878 }
1879 } else {
1880 $this->errors[] = $this->db->lasterror();
1881 $error++;
1882 }
1883
1884 if (!$error) {
1885 return 1;
1886 } else {
1887 return -1;
1888 }
1889 }
1890 }
1891
1899 public function createCPusers($single = false, $userid = 0)
1900 {
1901 // do we have to add balance for all users ?
1902 if (!$single) {
1903 dol_syslog(get_class($this).'::createCPusers');
1904 $arrayofusers = $this->fetchUsers(false, true);
1905
1906 foreach ($arrayofusers as $users) {
1907 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users";
1908 $sql .= " (fk_user, nb_holiday)";
1909 $sql .= " VALUES (".((int) $users['rowid'])."', '0')";
1910
1911 $resql = $this->db->query($sql);
1912 if (!$resql) {
1913 dol_print_error($this->db);
1914 }
1915 }
1916 } else {
1917 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users";
1918 $sql .= " (fk_user, nb_holiday)";
1919 $sql .= " VALUES (".((int) $userid)."', '0')";
1920
1921 $resql = $this->db->query($sql);
1922 if (!$resql) {
1923 dol_print_error($this->db);
1924 }
1925 }
1926 }
1927
1935 public function getCPforUser($user_id, $fk_type = 0)
1936 {
1937 $sql = "SELECT nb_holiday";
1938 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users";
1939 $sql .= " WHERE fk_user = ".(int) $user_id;
1940 if ($fk_type > 0) {
1941 $sql .= " AND fk_type = ".(int) $fk_type;
1942 }
1943
1944 dol_syslog(get_class($this).'::getCPforUser user_id='.$user_id.' type_id='.$fk_type, LOG_DEBUG);
1945 $result = $this->db->query($sql);
1946 if ($result) {
1947 $obj = $this->db->fetch_object($result);
1948 //return number_format($obj->nb_holiday,2);
1949 if ($obj) {
1950 return $obj->nb_holiday;
1951 } else {
1952 return null;
1953 }
1954 } else {
1955 return null;
1956 }
1957 }
1958
1967 public function fetchUsers($stringlist = true, $type = true, $filters = '')
1968 {
1969 dol_syslog(get_class($this)."::fetchUsers", LOG_DEBUG);
1970
1971 if ($stringlist) {
1972 if ($type) {
1973 // If user of Dolibarr
1974 $sql = "SELECT";
1975 if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
1976 $sql .= " DISTINCT";
1977 }
1978 $sql .= " u.rowid";
1979 $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
1980
1981 if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
1982 $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
1983 $sql .= " WHERE ((ug.fk_user = u.rowid";
1984 $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
1985 $sql .= " OR u.entity = 0)"; // Show always superadmin
1986 } else {
1987 $sql .= " WHERE u.entity IN (".getEntity('user').")";
1988 }
1989 $sql .= " AND u.statut > 0";
1990 $sql .= " AND u.employee = 1"; // We only want employee users for holidays
1991 if ($filters) {
1992 $sql .= $filters;
1993 }
1994
1995 $resql = $this->db->query($sql);
1996
1997 // Si pas d'erreur SQL
1998 if ($resql) {
1999 $i = 0;
2000 $num = $this->db->num_rows($resql);
2001 $stringlist = '';
2002
2003 // Boucles du listage des utilisateurs
2004 while ($i < $num) {
2005 $obj = $this->db->fetch_object($resql);
2006
2007 if ($i == 0) {
2008 $stringlist .= $obj->rowid;
2009 } else {
2010 $stringlist .= ', '.$obj->rowid;
2011 }
2012
2013 $i++;
2014 }
2015 // Retoune le tableau des utilisateurs
2016 return $stringlist;
2017 } else {
2018 // Erreur SQL
2019 $this->error = "Error ".$this->db->lasterror();
2020 return -1;
2021 }
2022 } else {
2023 // We want only list of vacation balance for user ids
2024 $sql = "SELECT DISTINCT cpu.fk_user";
2025 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u";
2026 $sql .= " WHERE cpu.fk_user = u.rowid";
2027 if ($filters) {
2028 $sql .= $filters;
2029 }
2030
2031 $resql = $this->db->query($sql);
2032
2033 // Si pas d'erreur SQL
2034 if ($resql) {
2035 $i = 0;
2036 $num = $this->db->num_rows($resql);
2037 $stringlist = '';
2038
2039 // Boucles du listage des utilisateurs
2040 while ($i < $num) {
2041 $obj = $this->db->fetch_object($resql);
2042
2043 if ($i == 0) {
2044 $stringlist .= $obj->fk_user;
2045 } else {
2046 $stringlist .= ', '.$obj->fk_user;
2047 }
2048
2049 $i++;
2050 }
2051 // Retoune le tableau des utilisateurs
2052 return $stringlist;
2053 } else {
2054 // Erreur SQL
2055 $this->error = "Error ".$this->db->lasterror();
2056 return -1;
2057 }
2058 }
2059 } else {
2060 // Si faux donc return array
2061 // List for Dolibarr users
2062 if ($type) {
2063 // If we need users of Dolibarr
2064 $sql = "SELECT";
2065 if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
2066 $sql .= " DISTINCT";
2067 }
2068 $sql .= " u.rowid, u.lastname, u.firstname, u.gender, u.fk_country as country_id, u.photo, u.employee, u.statut as status, u.fk_user";
2069 $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
2070
2071 if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
2072 $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
2073 $sql .= " WHERE ((ug.fk_user = u.rowid";
2074 $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
2075 $sql .= " OR u.entity = 0)"; // Show always superadmin
2076 } else {
2077 $sql .= " WHERE u.entity IN (".getEntity('user').")";
2078 }
2079
2080 $sql .= " AND u.statut > 0";
2081 $sql .= " AND u.employee = 1"; // We only want employee users for holidays
2082 if ($filters) {
2083 $sql .= $filters;
2084 }
2085
2086 $resql = $this->db->query($sql);
2087
2088 // Si pas d'erreur SQL
2089 if ($resql) {
2090 $i = 0;
2091 $tab_result = $this->holiday;
2092 $num = $this->db->num_rows($resql);
2093
2094 // Boucles du listage des utilisateurs
2095 while ($i < $num) {
2096 $obj = $this->db->fetch_object($resql);
2097
2098 $tab_result[$i]['rowid'] = (int) $obj->rowid; // rowid of user
2099 $tab_result[$i]['id'] = (int) $obj->rowid; // id of user
2100 $tab_result[$i]['name'] = $obj->lastname; // deprecated
2101 $tab_result[$i]['lastname'] = $obj->lastname;
2102 $tab_result[$i]['firstname'] = $obj->firstname;
2103 $tab_result[$i]['gender'] = $obj->gender;
2104 $tab_result[$i]['status'] = (int) $obj->status;
2105 $tab_result[$i]['employee'] = (int) $obj->employee;
2106 $tab_result[$i]['photo'] = $obj->photo;
2107 $tab_result[$i]['fk_user'] = (int) $obj->fk_user; // rowid of manager
2108 $tab_result[$i]['country_id'] = (int) $obj->country_id; // id of country of user
2109 //$tab_result[$i]['type'] = $obj->type;
2110 //$tab_result[$i]['nb_holiday'] = $obj->nb_holiday;
2111
2112 $i++;
2113 }
2114 // Retoune le tableau des utilisateurs
2115 return $tab_result;
2116 } else {
2117 // Erreur SQL
2118 $this->errors[] = "Error ".$this->db->lasterror();
2119 return -1;
2120 }
2121 } else {
2122 // List of vacation balance users
2123 $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";
2124 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u";
2125 $sql .= " WHERE cpu.fk_user = u.rowid";
2126 if ($filters) {
2127 $sql .= $filters;
2128 }
2129
2130 $resql = $this->db->query($sql);
2131
2132 // Si pas d'erreur SQL
2133 if ($resql) {
2134 $i = 0;
2135 $tab_result = $this->holiday;
2136 $num = $this->db->num_rows($resql);
2137
2138 // Boucles du listage des utilisateurs
2139 while ($i < $num) {
2140 $obj = $this->db->fetch_object($resql);
2141
2142 $tab_result[$i]['rowid'] = $obj->rowid; // rowid of user
2143 $tab_result[$i]['id'] = $obj->rowid; // id of user
2144 $tab_result[$i]['name'] = $obj->lastname; // deprecated
2145 $tab_result[$i]['lastname'] = $obj->lastname;
2146 $tab_result[$i]['firstname'] = $obj->firstname;
2147 $tab_result[$i]['gender'] = $obj->gender;
2148 $tab_result[$i]['status'] = $obj->status;
2149 $tab_result[$i]['employee'] = $obj->employee;
2150 $tab_result[$i]['photo'] = $obj->photo;
2151 $tab_result[$i]['fk_user'] = $obj->fk_user; // rowid of manager
2152
2153 $tab_result[$i]['type'] = $obj->fk_type;
2154 $tab_result[$i]['nb_holiday'] = $obj->nb_holiday;
2155
2156 $i++;
2157 }
2158 // Retoune le tableau des utilisateurs
2159 return $tab_result;
2160 } else {
2161 // Erreur SQL
2162 $this->error = "Error ".$this->db->lasterror();
2163 return -1;
2164 }
2165 }
2166 }
2167 }
2168
2169
2170 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2178 {
2179 // phpcs:enable
2180 $users_validator = array();
2181
2182 $sql = "SELECT DISTINCT ur.fk_user";
2183 $sql .= " FROM ".MAIN_DB_PREFIX."user_rights as ur, ".MAIN_DB_PREFIX."rights_def as rd";
2184 $sql .= " WHERE ur.fk_id = rd.id and rd.module = 'holiday' AND rd.perms = 'approve'"; // Permission 'Approve';
2185 $sql .= "UNION";
2186 $sql .= " SELECT DISTINCT ugu.fk_user";
2187 $sql .= " FROM ".MAIN_DB_PREFIX."usergroup_user as ugu, ".MAIN_DB_PREFIX."usergroup_rights as ur, ".MAIN_DB_PREFIX."rights_def as rd";
2188 $sql .= " WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'holiday' AND rd.perms = 'approve'"; // Permission 'Approve';
2189 //print $sql;
2190
2191 dol_syslog(get_class($this)."::fetch_users_approver_holiday sql=".$sql);
2192 $result = $this->db->query($sql);
2193 if ($result) {
2194 $num_rows = $this->db->num_rows($result);
2195 $i = 0;
2196 while ($i < $num_rows) {
2197 $objp = $this->db->fetch_object($result);
2198 array_push($users_validator, $objp->fk_user);
2199 $i++;
2200 }
2201 return $users_validator;
2202 } else {
2203 $this->error = $this->db->lasterror();
2204 dol_syslog(get_class($this)."::fetch_users_approver_holiday Error ".$this->error, LOG_ERR);
2205 return -1;
2206 }
2207 }
2208
2209
2215 public function countActiveUsers()
2216 {
2217 $sql = "SELECT count(u.rowid) as compteur";
2218 $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
2219 $sql .= " WHERE u.statut > 0";
2220
2221 $result = $this->db->query($sql);
2222 $object = $this->db->fetch_object($result);
2223
2224 return $object->compteur;
2225 }
2232 {
2233 $sql = "SELECT count(u.rowid) as compteur";
2234 $sql .= " FROM ".MAIN_DB_PREFIX."user as u LEFT JOIN ".MAIN_DB_PREFIX."holiday_users hu ON (hu.fk_user=u.rowid)";
2235 $sql .= " WHERE u.statut > 0 AND hu.fk_user IS NULL";
2236
2237 $result = $this->db->query($sql);
2238 $object = $this->db->fetch_object($result);
2239
2240 return $object->compteur;
2241 }
2242
2250 public function verifNbUsers($userDolibarrWithoutCP, $userCP)
2251 {
2252 if (empty($userCP)) {
2253 $userCP = 0;
2254 }
2255 dol_syslog(get_class($this).'::verifNbUsers userDolibarr='.$userDolibarrWithoutCP.' userCP='.$userCP);
2256 return 1;
2257 }
2258
2259
2270 public function addLogCP($fk_user_action, $fk_user_update, $label, $new_solde, $fk_type)
2271 {
2272 $error = 0;
2273
2274 $prev_solde = price2num((float) $this->getCPforUser($fk_user_update, $fk_type), 5);
2275 $new_solde = price2num($new_solde, 5);
2276 //print "$prev_solde == $new_solde";
2277
2278 if ($prev_solde == $new_solde) {
2279 return 0;
2280 }
2281
2282 $this->db->begin();
2283
2284 // Insert request
2285 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_logs (";
2286 $sql .= "date_action,";
2287 $sql .= "fk_user_action,";
2288 $sql .= "fk_user_update,";
2289 $sql .= "type_action,";
2290 $sql .= "prev_solde,";
2291 $sql .= "new_solde,";
2292 $sql .= "fk_type";
2293 $sql .= ") VALUES (";
2294 $sql .= " '".$this->db->idate(dol_now())."',";
2295 $sql .= " ".((int) $fk_user_action).",";
2296 $sql .= " ".((int) $fk_user_update).",";
2297 $sql .= " '".$this->db->escape($label)."',";
2298 $sql .= " ".((float) $prev_solde).",";
2299 $sql .= " ".((float) $new_solde).",";
2300 $sql .= " ".((int) $fk_type);
2301 $sql .= ")";
2302
2303 $resql = $this->db->query($sql);
2304 if (!$resql) {
2305 $error++;
2306 $this->errors[] = "Error ".$this->db->lasterror();
2307 }
2308
2309 $optRowid = 0;
2310 if (!$error) {
2311 $optRowid = $this->db->last_insert_id(MAIN_DB_PREFIX."holiday_logs");
2312 }
2313
2314 // Commit or rollback
2315 if ($error) {
2316 foreach ($this->errors as $errmsg) {
2317 dol_syslog(get_class($this)."::addLogCP ".$errmsg, LOG_ERR);
2318 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
2319 }
2320 $this->db->rollback();
2321 return -1 * $error;
2322 } else {
2323 $this->db->commit();
2324 return $optRowid;
2325 }
2326 }
2327
2335 public function fetchLog($sqlorder, $sqlwhere)
2336 {
2337 $sql = "SELECT";
2338 $sql .= " cpl.rowid,";
2339 $sql .= " cpl.date_action,";
2340 $sql .= " cpl.fk_user_action,";
2341 $sql .= " cpl.fk_user_update,";
2342 $sql .= " cpl.type_action,";
2343 $sql .= " cpl.prev_solde,";
2344 $sql .= " cpl.new_solde,";
2345 $sql .= " cpl.fk_type";
2346 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_logs as cpl";
2347 $sql .= " WHERE cpl.rowid > 0"; // To avoid error with other search and criteria
2348
2349 // Filter
2350 if (!empty($sqlwhere)) {
2351 $sql .= " ".$sqlwhere;
2352 }
2353
2354 // Order
2355 if (!empty($sqlorder)) {
2356 $sql .= " ".$sqlorder;
2357 }
2358
2359 dol_syslog(get_class($this)."::fetchLog", LOG_DEBUG);
2360 $resql = $this->db->query($sql);
2361
2362 // If no error SQL
2363 if ($resql) {
2364 $i = 0;
2365 $tab_result = $this->logs;
2366 $num = $this->db->num_rows($resql);
2367
2368 // If no record
2369 if (!$num) {
2370 return 2;
2371 }
2372
2373 // Loop on result to fill the array
2374 while ($i < $num) {
2375 $obj = $this->db->fetch_object($resql);
2376
2377 $tab_result[$i]['rowid'] = (int) $obj->rowid;
2378 $tab_result[$i]['id'] = (int) $obj->rowid;
2379 $tab_result[$i]['date_action'] = (string) $obj->date_action;
2380 $tab_result[$i]['fk_user_action'] = (int) $obj->fk_user_action;
2381 $tab_result[$i]['fk_user_update'] = (int) $obj->fk_user_update;
2382 $tab_result[$i]['type_action'] = (string) $obj->type_action;
2383 $tab_result[$i]['prev_solde'] = (float) $obj->prev_solde;
2384 $tab_result[$i]['new_solde'] = (float) $obj->new_solde;
2385 $tab_result[$i]['fk_type'] = (int) $obj->fk_type;
2386
2387 $i++;
2388 }
2389 // Retourne 1 et ajoute le tableau à la variable
2390 $this->logs = $tab_result;
2391 return 1;
2392 } else {
2393 // Erreur SQL
2394 $this->error = "Error ".$this->db->lasterror();
2395 return -1;
2396 }
2397 }
2398
2399
2407 public function getTypes($active = -1, $affect = -1)
2408 {
2409 global $mysoc;
2410
2411 $sql = "SELECT rowid, code, label, affect, delay, newbymonth";
2412 $sql .= " FROM ".MAIN_DB_PREFIX."c_holiday_types";
2413 $sql .= " WHERE (fk_country IS NULL OR fk_country = ".((int) $mysoc->country_id).')';
2414 $sql .= " AND entity IN (0, ".getEntity('c_holiday_types').")"; // Need entity 0 (holiday types common to all countries= + current entity).
2415 if ($active >= 0) {
2416 $sql .= " AND active = ".((int) $active);
2417 }
2418 if ($affect >= 0) {
2419 $sql .= " AND affect = ".((int) $affect);
2420 }
2421 $sql .= " ORDER BY sortorder";
2422
2423 $result = $this->db->query($sql);
2424 if ($result) {
2425 $num = $this->db->num_rows($result);
2426 if ($num) {
2427 $types = array();
2428 while ($obj = $this->db->fetch_object($result)) {
2429 $types[$obj->rowid] = array(
2430 'id' => $obj->rowid,
2431 'rowid' => $obj->rowid,
2432 'code' => $obj->code,
2433 'label' => $obj->label,
2434 'affect' => $obj->affect,
2435 'delay' => $obj->delay,
2436 'newbymonth' => $obj->newbymonth
2437 );
2438 }
2439
2440 return $types;
2441 }
2442 } else {
2443 dol_print_error($this->db);
2444 }
2445
2446 return array();
2447 }
2448
2449
2456 public function info($id)
2457 {
2458 global $conf;
2459
2460 $sql = "SELECT f.rowid, f.statut as status,";
2461 $sql .= " f.date_create as datec,";
2462 $sql .= " f.tms as date_modification,";
2463 $sql .= " f.date_valid as datev,";
2464 $sql .= " f.date_approval as datea,";
2465 $sql .= " f.date_refuse as dater,";
2466 $sql .= " f.fk_user_create as fk_user_creation,";
2467 $sql .= " f.fk_user_modif as fk_user_modification,";
2468 $sql .= " f.fk_user_valid as fk_user_validation,";
2469 $sql .= " f.fk_user_approve as fk_user_approval_done,";
2470 $sql .= " f.fk_validator as fk_user_approval_expected,";
2471 $sql .= " f.fk_user_refuse as fk_user_refuse";
2472 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as f";
2473 $sql .= " WHERE f.rowid = ".((int) $id);
2474 $sql .= " AND f.entity = ".$conf->entity;
2475
2476 $resql = $this->db->query($sql);
2477 if ($resql) {
2478 if ($this->db->num_rows($resql)) {
2479 $obj = $this->db->fetch_object($resql);
2480
2481 $this->id = $obj->rowid;
2482
2483 $this->date_creation = $this->db->jdate($obj->datec);
2484 $this->date_modification = $this->db->jdate($obj->date_modification);
2485 $this->date_validation = $this->db->jdate($obj->datev);
2486 $this->date_approval = $this->db->jdate($obj->datea);
2487
2488 $this->user_creation_id = $obj->fk_user_creation;
2489 $this->user_validation_id = $obj->fk_user_validation;
2490 $this->user_modification_id = $obj->fk_user_modification;
2491
2492 if ($obj->status == Holiday::STATUS_APPROVED || $obj->status == Holiday::STATUS_CANCELED) {
2493 if ($obj->fk_user_approval_done) {
2494 $this->fk_user_approve = $obj->fk_user_approval_done;
2495 }
2496 }
2497 }
2498 $this->db->free($resql);
2499 } else {
2500 dol_print_error($this->db);
2501 }
2502 }
2503
2504
2512 public function initAsSpecimen()
2513 {
2514 global $user, $langs;
2515
2516 // Initialise parameters
2517 $this->id = 0;
2518 $this->specimen = 1;
2519
2520 $this->fk_user = $user->id;
2521 $this->description = 'SPECIMEN description';
2522 $this->date_debut = dol_now();
2523 $this->date_fin = dol_now() + (24 * 3600);
2524 $this->date_valid = dol_now();
2525 $this->fk_validator = $user->id;
2526 $this->halfday = 0;
2527 $this->fk_type = 1;
2529
2530 return 1;
2531 }
2532
2538 public function loadStateBoard()
2539 {
2540 global $user;
2541
2542 $this->nb = array();
2543
2544 $sql = "SELECT count(h.rowid) as nb";
2545 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
2546 $sql .= " WHERE h.statut > 1";
2547 $sql .= " AND h.entity IN (".getEntity('holiday').")";
2548 if (!$user->hasRight('holiday', 'readall')) {
2549 $userchildids = $user->getAllChildIds(1);
2550 $sql .= " AND (h.fk_user IN (".$this->db->sanitize(implode(',', $userchildids)).")";
2551 $sql .= " OR h.fk_validator IN (".$this->db->sanitize(implode(',', $userchildids))."))";
2552 }
2553
2554 $resql = $this->db->query($sql);
2555 if ($resql) {
2556 while ($obj = $this->db->fetch_object($resql)) {
2557 $this->nb["holidays"] = $obj->nb;
2558 }
2559 $this->db->free($resql);
2560 return 1;
2561 } else {
2562 dol_print_error($this->db);
2563 $this->error = $this->db->error();
2564 return -1;
2565 }
2566 }
2567
2568 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2575 public function load_board($user)
2576 {
2577 // phpcs:enable
2578 global $conf, $langs;
2579
2580 if ($user->socid) {
2581 return -1; // protection pour eviter appel par utilisateur externe
2582 }
2583
2584 $now = dol_now();
2585
2586 $sql = "SELECT h.rowid, h.date_debut";
2587 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
2588 $sql .= " WHERE h.statut = 2";
2589 $sql .= " AND h.entity IN (".getEntity('holiday').")";
2590 if (!$user->hasRight('holiday', 'read_all')) {
2591 $userchildids = $user->getAllChildIds(1);
2592 $sql .= " AND (h.fk_user IN (".$this->db->sanitize(implode(',', $userchildids)).")";
2593 $sql .= " OR h.fk_validator IN (".$this->db->sanitize(implode(',', $userchildids))."))";
2594 }
2595
2596 $resql = $this->db->query($sql);
2597 if ($resql) {
2598 $langs->load("members");
2599
2600 $response = new WorkboardResponse();
2601 $response->warning_delay = $conf->holiday->approve->warning_delay / 60 / 60 / 24;
2602 $response->label = $langs->trans("HolidaysToApprove");
2603 $response->labelShort = $langs->trans("ToApprove");
2604 $response->url = DOL_URL_ROOT.'/holiday/list.php?search_status=2&amp;mainmenu=hrm&amp;leftmenu=holiday';
2605 $response->img = img_object('', "holiday");
2606
2607 while ($obj = $this->db->fetch_object($resql)) {
2608 $response->nbtodo++;
2609
2610 if ($this->db->jdate($obj->date_debut) < ($now - $conf->holiday->approve->warning_delay)) {
2611 $response->nbtodolate++;
2612 }
2613 }
2614
2615 return $response;
2616 } else {
2617 dol_print_error($this->db);
2618 $this->error = $this->db->error();
2619 return -1;
2620 }
2621 }
2629 public function getKanbanView($option = '', $arraydata = null)
2630 {
2631 global $langs;
2632
2633 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
2634
2635 $return = '<div class="box-flex-item box-flex-grow-zero">';
2636 $return .= '<div class="info-box info-box-sm">';
2637 $return .= '<span class="info-box-icon bg-infobox-action">';
2638 $return .= img_picto('', $this->picto);
2639 $return .= '</span>';
2640 $return .= '<div class="info-box-content">';
2641 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.$this->getNomUrl().'</span>';
2642 if ($selected >= 0) {
2643 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
2644 }
2645 if (property_exists($this, 'fk_type')) {
2646 $return .= '<br>';
2647 //$return .= '<span class="opacitymedium">'.$langs->trans("Type").'</span> : ';
2648 $return .= '<div class="info_box-label tdoverflowmax100" title="'.dol_escape_htmltag($arraydata['labeltype']).'">'.dol_escape_htmltag($arraydata['labeltype']).'</div>';
2649 }
2650 if (property_exists($this, 'date_debut') && property_exists($this, 'date_fin')) {
2651 $return .= '<span class="info-box-label small">'.dol_print_date($this->date_debut, 'day').'</span>';
2652 $return .= ' <span class="opacitymedium small">'.$langs->trans("To").'</span> ';
2653 $return .= '<span class="info-box-label small">'.dol_print_date($this->date_fin, 'day').'</span>';
2654 if (!empty($arraydata['nbopenedday'])) {
2655 $return .= ' ('.$arraydata['nbopenedday'].')';
2656 }
2657 }
2658 if (method_exists($this, 'getLibStatut')) {
2659 $return .= '<div class="info-box-status">'.$this->getLibStatut(3).'</div>';
2660 }
2661 $return .= '</div>';
2662 $return .= '</div>';
2663 $return .= '</div>';
2664 return $return;
2665 }
2666}
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
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:475
$object ref
Definition info.php:90
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...
deleteExtraFields()
Delete all extra fields values for the current object.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
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.
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.
fetchLog($sqlorder, $sqlwhere)
List log of leaves.
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 $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:171
global $mysoc
dol_get_next_month($month, $year)
Return next month.
Definition date.lib.php:556
num_open_day($timestampStart, $timestampEnd, $inhour=0, $lastday=0, $halfday=0, $countryCodeOrId='')
Function to return number of working days (and text of units) between two dates (working days)
dol_stringtotime($string, $gm=1)
Convert a string date into a GM Timestamps date Warning: YYYY-MM-DDTHH:MM:SS+02:00 (RFC3339) is not s...
Definition date.lib.php:449
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:64
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
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 '.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
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.
isModEnabled($module)
Is Dolibarr module enabled.
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...