dolibarr 19.0.3
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-2023 Frédéric France <frederic.france@netlogic.fr>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
28require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
29
30
34class Holiday extends CommonObject
35{
39 public $element = 'holiday';
40
44 public $table_element = 'holiday';
45
50 public $ismultientitymanaged = 0;
51
55 public $fk_element = 'fk_holiday';
56
60 public $picto = 'holiday';
61
65 public $fk_user;
66
67 public $date_create = '';
68
72 public $description;
73
74 public $date_debut = ''; // Date start in PHP server TZ
75 public $date_fin = ''; // Date end in PHP server TZ
76 public $date_debut_gmt = ''; // Date start in GMT
77 public $date_fin_gmt = ''; // Date end in GMT
78 public $halfday = ''; // 0:Full days, 2:Start afternoon end morning, -1:Start afternoon end afternoon, 1:Start morning end morning
79 public $statut = ''; // 1=draft, 2=validated, 3=approved
80
84 public $fk_validator;
85
89 public $date_valid = '';
90
94 public $fk_user_valid;
95
99 public $date_approval;
100
104 public $fk_user_approve;
105
109 public $date_refuse = '';
110
114 public $fk_user_refuse;
115
119 public $date_cancel = '';
120
124 public $fk_user_cancel;
125
129 public $fk_user_create;
130
131
132 public $detail_refuse = '';
133
137 public $fk_type;
138
139 public $holiday = array();
140 public $events = array();
141 public $logs = array();
142
143 public $optName = '';
144 public $optValue = '';
145 public $optRowid = '';
146
150 const STATUS_DRAFT = 1;
166 const STATUS_REFUSED = 5;
167
168
174 public function __construct($db)
175 {
176 $this->db = $db;
177 }
178
179
187 public function getNextNumRef($objsoc)
188 {
189 global $langs, $conf;
190 $langs->load("order");
191
192 if (!getDolGlobalString('HOLIDAY_ADDON')) {
193 $conf->global->HOLIDAY_ADDON = 'mod_holiday_madonna';
194 }
195
196 if (getDolGlobalString('HOLIDAY_ADDON')) {
197 $mybool = false;
198
199 $file = getDolGlobalString('HOLIDAY_ADDON') . ".php";
200 $classname = $conf->global->HOLIDAY_ADDON;
201
202 // Include file with class
203 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
204 foreach ($dirmodels as $reldir) {
205 $dir = dol_buildpath($reldir."core/modules/holiday/");
206
207 // Load file with numbering class (if found)
208 $mybool |= @include_once $dir.$file;
209 }
210
211 if ($mybool === false) {
212 dol_print_error('', "Failed to include file ".$file);
213 return '';
214 }
215
216 $obj = new $classname();
217 $numref = $obj->getNextValue($objsoc, $this);
218
219 if ($numref != "") {
220 return $numref;
221 } else {
222 $this->error = $obj->error;
223 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
224 return "";
225 }
226 } else {
227 print $langs->trans("Error")." ".$langs->trans("Error_HOLIDAY_ADDON_NotDefined");
228 return "";
229 }
230 }
231
237 public function updateBalance()
238 {
239 $this->db->begin();
240
241 // Update sold of vocations
242 $result = $this->updateSoldeCP();
243
244 // Check nb of users into table llx_holiday_users and update with empty lines
245 //if ($result > 0) $result = $this->verifNbUsers($this->countActiveUsersWithoutCP(), $this->getConfCP('nbUser'));
246
247 if ($result >= 0) {
248 $this->db->commit();
249 return 0; // for cronjob use (0 is OK, any other value is an error code)
250 } else {
251 $this->db->rollback();
252 return -1;
253 }
254 }
255
263 public function create($user, $notrigger = 0)
264 {
265 global $conf;
266 $error = 0;
267
268 $now = dol_now();
269
270 // Check parameters
271 if (empty($this->fk_user) || !is_numeric($this->fk_user) || $this->fk_user < 0) {
272 $this->error = "ErrorBadParameterFkUser";
273 return -1;
274 }
275 if (empty($this->fk_validator) || !is_numeric($this->fk_validator) || $this->fk_validator < 0) {
276 $this->error = "ErrorBadParameterFkValidator";
277 return -1;
278 }
279 if (empty($this->fk_type) || !is_numeric($this->fk_type) || $this->fk_type < 0) {
280 $this->error = "ErrorBadParameterFkType";
281 return -1;
282 }
283
284 // Insert request
285 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday(";
286 $sql .= "ref,";
287 $sql .= "fk_user,";
288 $sql .= "date_create,";
289 $sql .= "description,";
290 $sql .= "date_debut,";
291 $sql .= "date_fin,";
292 $sql .= "halfday,";
293 $sql .= "statut,";
294 $sql .= "fk_validator,";
295 $sql .= "fk_type,";
296 $sql .= "fk_user_create,";
297 $sql .= "entity";
298 $sql .= ") VALUES (";
299 $sql .= "'(PROV)',";
300 $sql .= " ".((int) $this->fk_user).",";
301 $sql .= " '".$this->db->idate($now)."',";
302 $sql .= " '".$this->db->escape($this->description)."',";
303 $sql .= " '".$this->db->idate($this->date_debut)."',";
304 $sql .= " '".$this->db->idate($this->date_fin)."',";
305 $sql .= " ".((int) $this->halfday).",";
306 $sql .= " '1',";
307 $sql .= " ".((int) $this->fk_validator).",";
308 $sql .= " ".((int) $this->fk_type).",";
309 $sql .= " ".((int) $user->id).",";
310 $sql .= " ".((int) $conf->entity);
311 $sql .= ")";
312
313 $this->db->begin();
314
315 dol_syslog(get_class($this)."::create", LOG_DEBUG);
316 $resql = $this->db->query($sql);
317 if (!$resql) {
318 $error++;
319 $this->errors[] = "Error ".$this->db->lasterror();
320 }
321
322 if (!$error) {
323 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."holiday");
324
325 if ($this->id) {
326 // update ref
327 $initialref = '(PROV'.$this->id.')';
328 if (!empty($this->ref)) {
329 $initialref = $this->ref;
330 }
331
332 $sql = 'UPDATE '.MAIN_DB_PREFIX."holiday SET ref='".$this->db->escape($initialref)."' WHERE rowid=".((int) $this->id);
333 if ($this->db->query($sql)) {
334 $this->ref = $initialref;
335
336 if (!$error) {
337 $result = $this->insertExtraFields();
338 if ($result < 0) {
339 $error++;
340 }
341 }
342
343 if (!$error && !$notrigger) {
344 // Call trigger
345 $result = $this->call_trigger('HOLIDAY_CREATE', $user);
346 if ($result < 0) {
347 $error++;
348 }
349 // End call triggers
350 }
351 }
352 }
353 }
354
355 // Commit or rollback
356 if ($error) {
357 foreach ($this->errors as $errmsg) {
358 dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR);
359 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
360 }
361 $this->db->rollback();
362 return -1 * $error;
363 } else {
364 $this->db->commit();
365 return $this->id;
366 }
367 }
368
369
377 public function fetch($id, $ref = '')
378 {
379 global $langs;
380
381 $sql = "SELECT";
382 $sql .= " cp.rowid,";
383 $sql .= " cp.ref,";
384 $sql .= " cp.fk_user,";
385 $sql .= " cp.date_create,";
386 $sql .= " cp.description,";
387 $sql .= " cp.date_debut,";
388 $sql .= " cp.date_fin,";
389 $sql .= " cp.halfday,";
390 $sql .= " cp.statut,";
391 $sql .= " cp.fk_validator,";
392 $sql .= " cp.date_valid,";
393 $sql .= " cp.fk_user_valid,";
394 $sql .= " cp.date_approval,";
395 $sql .= " cp.fk_user_approve,";
396 $sql .= " cp.date_refuse,";
397 $sql .= " cp.fk_user_refuse,";
398 $sql .= " cp.date_cancel,";
399 $sql .= " cp.fk_user_cancel,";
400 $sql .= " cp.detail_refuse,";
401 $sql .= " cp.note_private,";
402 $sql .= " cp.note_public,";
403 $sql .= " cp.fk_user_create,";
404 $sql .= " cp.fk_type,";
405 $sql .= " cp.entity";
406 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp";
407 if ($id > 0) {
408 $sql .= " WHERE cp.rowid = ".((int) $id);
409 } else {
410 $sql .= " WHERE cp.ref = '".$this->db->escape($ref)."'";
411 }
412
413 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
414 $resql = $this->db->query($sql);
415 if ($resql) {
416 if ($this->db->num_rows($resql)) {
417 $obj = $this->db->fetch_object($resql);
418
419 $this->id = $obj->rowid;
420 $this->ref = ($obj->ref ? $obj->ref : $obj->rowid);
421 $this->fk_user = $obj->fk_user;
422 $this->date_create = $this->db->jdate($obj->date_create);
423 $this->description = $obj->description;
424 $this->date_debut = $this->db->jdate($obj->date_debut);
425 $this->date_fin = $this->db->jdate($obj->date_fin);
426 $this->date_debut_gmt = $this->db->jdate($obj->date_debut, 1);
427 $this->date_fin_gmt = $this->db->jdate($obj->date_fin, 1);
428 $this->halfday = $obj->halfday;
429 $this->statut = $obj->statut;
430 $this->fk_validator = $obj->fk_validator;
431 $this->date_valid = $this->db->jdate($obj->date_valid);
432 $this->fk_user_valid = $obj->fk_user_valid;
433 $this->user_validation_id = $obj->fk_user_valid;
434 $this->date_approval = $this->db->jdate($obj->date_approval);
435 $this->fk_user_approve = $obj->fk_user_approve;
436 $this->date_refuse = $this->db->jdate($obj->date_refuse);
437 $this->fk_user_refuse = $obj->fk_user_refuse;
438 $this->date_cancel = $this->db->jdate($obj->date_cancel);
439 $this->fk_user_cancel = $obj->fk_user_cancel;
440 $this->detail_refuse = $obj->detail_refuse;
441 $this->note_private = $obj->note_private;
442 $this->note_public = $obj->note_public;
443 $this->fk_user_create = $obj->fk_user_create;
444 $this->fk_type = $obj->fk_type;
445 $this->entity = $obj->entity;
446
447 $this->fetch_optionals();
448
449 $result = 1;
450 } else {
451 $result = 0;
452 }
453 $this->db->free($resql);
454
455 return $result;
456 } else {
457 $this->error = "Error ".$this->db->lasterror();
458 return -1;
459 }
460 }
461
470 public function fetchByUser($user_id, $order = '', $filter = '')
471 {
472 global $langs, $conf;
473
474 $sql = "SELECT";
475 $sql .= " cp.rowid,";
476 $sql .= " cp.ref,";
477
478 $sql .= " cp.fk_user,";
479 $sql .= " cp.fk_type,";
480 $sql .= " cp.date_create,";
481 $sql .= " cp.description,";
482 $sql .= " cp.date_debut,";
483 $sql .= " cp.date_fin,";
484 $sql .= " cp.halfday,";
485 $sql .= " cp.statut,";
486 $sql .= " cp.fk_validator,";
487 $sql .= " cp.date_valid,";
488 $sql .= " cp.fk_user_valid,";
489 $sql .= " cp.date_approval,";
490 $sql .= " cp.fk_user_approve,";
491 $sql .= " cp.date_refuse,";
492 $sql .= " cp.fk_user_refuse,";
493 $sql .= " cp.date_cancel,";
494 $sql .= " cp.fk_user_cancel,";
495 $sql .= " cp.detail_refuse,";
496
497 $sql .= " uu.lastname as user_lastname,";
498 $sql .= " uu.firstname as user_firstname,";
499 $sql .= " uu.login as user_login,";
500 $sql .= " uu.statut as user_statut,";
501 $sql .= " uu.photo as user_photo,";
502
503 $sql .= " ua.lastname as validator_lastname,";
504 $sql .= " ua.firstname as validator_firstname,";
505 $sql .= " ua.login as validator_login,";
506 $sql .= " ua.statut as validator_statut,";
507 $sql .= " ua.photo as validator_photo";
508
509 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp, ".MAIN_DB_PREFIX."user as uu, ".MAIN_DB_PREFIX."user as ua";
510 $sql .= " WHERE cp.entity IN (".getEntity('holiday').")";
511 $sql .= " AND cp.fk_user = uu.rowid AND cp.fk_validator = ua.rowid"; // Hack pour la recherche sur le tableau
512 $sql .= " AND cp.fk_user IN (".$this->db->sanitize($user_id).")";
513
514 // Selection filter
515 if (!empty($filter)) {
516 $sql .= $filter;
517 }
518
519 // Order of display of the result
520 if (!empty($order)) {
521 $sql .= $order;
522 }
523
524 dol_syslog(get_class($this)."::fetchByUser", LOG_DEBUG);
525 $resql = $this->db->query($sql);
526
527 // If no SQL error
528 if ($resql) {
529 $i = 0;
530 $tab_result = $this->holiday;
531 $num = $this->db->num_rows($resql);
532
533 // If no registration
534 if (!$num) {
535 return 2;
536 }
537
538 // List the records and add them to the table
539 while ($i < $num) {
540 $obj = $this->db->fetch_object($resql);
541
542 $tab_result[$i]['rowid'] = $obj->rowid;
543 $tab_result[$i]['id'] = $obj->rowid;
544 $tab_result[$i]['ref'] = ($obj->ref ? $obj->ref : $obj->rowid);
545
546 $tab_result[$i]['fk_user'] = $obj->fk_user;
547 $tab_result[$i]['fk_type'] = $obj->fk_type;
548 $tab_result[$i]['date_create'] = $this->db->jdate($obj->date_create);
549 $tab_result[$i]['description'] = $obj->description;
550 $tab_result[$i]['date_debut'] = $this->db->jdate($obj->date_debut);
551 $tab_result[$i]['date_fin'] = $this->db->jdate($obj->date_fin);
552 $tab_result[$i]['date_debut_gmt'] = $this->db->jdate($obj->date_debut, 1);
553 $tab_result[$i]['date_fin_gmt'] = $this->db->jdate($obj->date_fin, 1);
554 $tab_result[$i]['halfday'] = $obj->halfday;
555 $tab_result[$i]['statut'] = $obj->statut;
556 $tab_result[$i]['fk_validator'] = $obj->fk_validator;
557 $tab_result[$i]['date_valid'] = $this->db->jdate($obj->date_valid);
558 $tab_result[$i]['fk_user_valid'] = $obj->fk_user_valid;
559 $tab_result[$i]['date_approval'] = $this->db->jdate($obj->date_approval);
560 $tab_result[$i]['fk_user_approve'] = $obj->fk_user_approve;
561 $tab_result[$i]['date_refuse'] = $this->db->jdate($obj->date_refuse);
562 $tab_result[$i]['fk_user_refuse'] = $obj->fk_user_refuse;
563 $tab_result[$i]['date_cancel'] = $this->db->jdate($obj->date_cancel);
564 $tab_result[$i]['fk_user_cancel'] = $obj->fk_user_cancel;
565 $tab_result[$i]['detail_refuse'] = $obj->detail_refuse;
566
567 $tab_result[$i]['user_firstname'] = $obj->user_firstname;
568 $tab_result[$i]['user_lastname'] = $obj->user_lastname;
569 $tab_result[$i]['user_login'] = $obj->user_login;
570 $tab_result[$i]['user_statut'] = $obj->user_statut;
571 $tab_result[$i]['user_photo'] = $obj->user_photo;
572
573 $tab_result[$i]['validator_firstname'] = $obj->validator_firstname;
574 $tab_result[$i]['validator_lastname'] = $obj->validator_lastname;
575 $tab_result[$i]['validator_login'] = $obj->validator_login;
576 $tab_result[$i]['validator_statut'] = $obj->validator_statut;
577 $tab_result[$i]['validator_photo'] = $obj->validator_photo;
578
579 $i++;
580 }
581
582 // Returns 1 with the filled array
583 $this->holiday = $tab_result;
584 return 1;
585 } else {
586 // SQL Error
587 $this->error = "Error ".$this->db->lasterror();
588 return -1;
589 }
590 }
591
599 public function fetchAll($order, $filter)
600 {
601 global $langs;
602
603 $sql = "SELECT";
604 $sql .= " cp.rowid,";
605 $sql .= " cp.ref,";
606
607 $sql .= " cp.fk_user,";
608 $sql .= " cp.fk_type,";
609 $sql .= " cp.date_create,";
610 $sql .= " cp.tms as date_update,";
611 $sql .= " cp.description,";
612 $sql .= " cp.date_debut,";
613 $sql .= " cp.date_fin,";
614 $sql .= " cp.halfday,";
615 $sql .= " cp.statut,";
616 $sql .= " cp.fk_validator,";
617 $sql .= " cp.date_valid,";
618 $sql .= " cp.fk_user_valid,";
619 $sql .= " cp.date_approval,";
620 $sql .= " cp.fk_user_approve,";
621 $sql .= " cp.date_refuse,";
622 $sql .= " cp.fk_user_refuse,";
623 $sql .= " cp.date_cancel,";
624 $sql .= " cp.fk_user_cancel,";
625 $sql .= " cp.detail_refuse,";
626
627 $sql .= " uu.lastname as user_lastname,";
628 $sql .= " uu.firstname as user_firstname,";
629 $sql .= " uu.login as user_login,";
630 $sql .= " uu.statut as user_statut,";
631 $sql .= " uu.photo as user_photo,";
632
633 $sql .= " ua.lastname as validator_lastname,";
634 $sql .= " ua.firstname as validator_firstname,";
635 $sql .= " ua.login as validator_login,";
636 $sql .= " ua.statut as validator_statut,";
637 $sql .= " ua.photo as validator_photo";
638
639 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp, ".MAIN_DB_PREFIX."user as uu, ".MAIN_DB_PREFIX."user as ua";
640 $sql .= " WHERE cp.entity IN (".getEntity('holiday').")";
641 $sql .= " AND cp.fk_user = uu.rowid AND cp.fk_validator = ua.rowid "; // Hack pour la recherche sur le tableau
642
643 // Selection filtering
644 if (!empty($filter)) {
645 $sql .= $filter;
646 }
647
648 // order of display
649 if (!empty($order)) {
650 $sql .= $order;
651 }
652
653 dol_syslog(get_class($this)."::fetchAll", LOG_DEBUG);
654 $resql = $this->db->query($sql);
655
656 // If no SQL error
657 if ($resql) {
658 $i = 0;
659 $tab_result = $this->holiday;
660 $num = $this->db->num_rows($resql);
661
662 // If no registration
663 if (!$num) {
664 return 2;
665 }
666
667 // List the records and add them to the table
668 while ($i < $num) {
669 $obj = $this->db->fetch_object($resql);
670
671 $tab_result[$i]['rowid'] = $obj->rowid;
672 $tab_result[$i]['id'] = $obj->rowid;
673 $tab_result[$i]['ref'] = ($obj->ref ? $obj->ref : $obj->rowid);
674
675 $tab_result[$i]['fk_user'] = $obj->fk_user;
676 $tab_result[$i]['fk_type'] = $obj->fk_type;
677 $tab_result[$i]['date_create'] = $this->db->jdate($obj->date_create);
678 $tab_result[$i]['date_update'] = $this->db->jdate($obj->date_update);
679 $tab_result[$i]['description'] = $obj->description;
680 $tab_result[$i]['date_debut'] = $this->db->jdate($obj->date_debut);
681 $tab_result[$i]['date_fin'] = $this->db->jdate($obj->date_fin);
682 $tab_result[$i]['date_debut_gmt'] = $this->db->jdate($obj->date_debut, 1);
683 $tab_result[$i]['date_fin_gmt'] = $this->db->jdate($obj->date_fin, 1);
684 $tab_result[$i]['halfday'] = $obj->halfday;
685 $tab_result[$i]['statut'] = $obj->statut;
686 $tab_result[$i]['fk_validator'] = $obj->fk_validator;
687 $tab_result[$i]['date_valid'] = $this->db->jdate($obj->date_valid);
688 $tab_result[$i]['fk_user_valid'] = $obj->fk_user_valid;
689 $tab_result[$i]['date_approval'] = $this->db->jdate($obj->date_approval);
690 $tab_result[$i]['fk_user_approve'] = $obj->fk_user_approve;
691 $tab_result[$i]['date_refuse'] = $obj->date_refuse;
692 $tab_result[$i]['fk_user_refuse'] = $obj->fk_user_refuse;
693 $tab_result[$i]['date_cancel'] = $obj->date_cancel;
694 $tab_result[$i]['fk_user_cancel'] = $obj->fk_user_cancel;
695 $tab_result[$i]['detail_refuse'] = $obj->detail_refuse;
696
697 $tab_result[$i]['user_firstname'] = $obj->user_firstname;
698 $tab_result[$i]['user_lastname'] = $obj->user_lastname;
699 $tab_result[$i]['user_login'] = $obj->user_login;
700 $tab_result[$i]['user_statut'] = $obj->user_statut;
701 $tab_result[$i]['user_photo'] = $obj->user_photo;
702
703 $tab_result[$i]['validator_firstname'] = $obj->validator_firstname;
704 $tab_result[$i]['validator_lastname'] = $obj->validator_lastname;
705 $tab_result[$i]['validator_login'] = $obj->validator_login;
706 $tab_result[$i]['validator_statut'] = $obj->validator_statut;
707 $tab_result[$i]['validator_photo'] = $obj->validator_photo;
708
709 $i++;
710 }
711 // Returns 1 and adds the array to the variable
712 $this->holiday = $tab_result;
713 return 1;
714 } else {
715 // SQL Error
716 $this->error = "Error ".$this->db->lasterror();
717 return -1;
718 }
719 }
720
721
729 public function validate($user = null, $notrigger = 0)
730 {
731 global $conf, $langs;
732 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
733 $error = 0;
734
735 $checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type);
736
737 if ($checkBalance > 0) {
738 $balance = $this->getCPforUser($this->fk_user, $this->fk_type);
739
740 if ($balance < 0) {
741 $this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
742 return -1;
743 }
744 }
745
746 // Define new ref
747 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref) || $this->ref == $this->id)) {
748 $num = $this->getNextNumRef(null);
749 } else {
750 $num = $this->ref;
751 }
752 $this->newref = dol_sanitizeFileName($num);
753
754 // Update status
755 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
756 $sql .= " fk_user_valid = ".((int) $user->id).",";
757 $sql .= " date_valid = '".$this->db->idate(dol_now())."',";
758 if (!empty($this->statut) && is_numeric($this->statut)) {
759 $sql .= " statut = ".((int) $this->statut).",";
760 } else {
761 $this->error = 'Property status must be a numeric value';
762 $error++;
763 }
764 $sql .= " ref = '".$this->db->escape($num)."'";
765 $sql .= " WHERE rowid = ".((int) $this->id);
766
767 $this->db->begin();
768
769 dol_syslog(get_class($this)."::validate", LOG_DEBUG);
770 $resql = $this->db->query($sql);
771 if (!$resql) {
772 $error++;
773 $this->errors[] = "Error ".$this->db->lasterror();
774 }
775
776 if (!$error) {
777 if (!$notrigger) {
778 // Call trigger
779 $result = $this->call_trigger('HOLIDAY_VALIDATE', $user);
780 if ($result < 0) {
781 $error++;
782 }
783 // End call triggers
784 }
785 }
786
787 if (!$error) {
788 $this->oldref = $this->ref;
789
790 // Rename directory if dir was a temporary ref
791 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
792 // Now we rename also files into index
793 $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) . "'";
794 $sql .= " WHERE filename LIKE '" . $this->db->escape($this->ref) . "%' AND filepath = 'holiday/" . $this->db->escape($this->ref) . "' and entity = " . ((int) $conf->entity);
795 $resql = $this->db->query($sql);
796 if (!$resql) {
797 $error++;
798 $this->error = $this->db->lasterror();
799 }
800 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'holiday/".$this->db->escape($this->newref)."'";
801 $sql .= " WHERE filepath = 'holiday/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
802 $resql = $this->db->query($sql);
803 if (!$resql) {
804 $error++;
805 $this->error = $this->db->lasterror();
806 }
807
808 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
809 $oldref = dol_sanitizeFileName($this->ref);
810 $newref = dol_sanitizeFileName($num);
811 $dirsource = $conf->holiday->multidir_output[$this->entity] . '/' . $oldref;
812 $dirdest = $conf->holiday->multidir_output[$this->entity] . '/' . $newref;
813 if (!$error && file_exists($dirsource)) {
814 dol_syslog(get_class($this) . "::validate rename dir " . $dirsource . " into " . $dirdest);
815 if (@rename($dirsource, $dirdest)) {
816 dol_syslog("Rename ok");
817 // Rename docs starting with $oldref with $newref
818 $listoffiles = dol_dir_list($dirdest, 'files', 1, '^' . preg_quote($oldref, '/'));
819 foreach ($listoffiles as $fileentry) {
820 $dirsource = $fileentry['name'];
821 $dirdest = preg_replace('/^' . preg_quote($oldref, '/') . '/', $newref, $dirsource);
822 $dirsource = $fileentry['path'] . '/' . $dirsource;
823 $dirdest = $fileentry['path'] . '/' . $dirdest;
824 @rename($dirsource, $dirdest);
825 }
826 }
827 }
828 }
829 }
830
831
832 // Commit or rollback
833 if ($error) {
834 foreach ($this->errors as $errmsg) {
835 dol_syslog(get_class($this)."::validate ".$errmsg, LOG_ERR);
836 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
837 }
838 $this->db->rollback();
839 return -1 * $error;
840 } else {
841 $this->db->commit();
842 return 1;
843 }
844 }
845
846
854 public function approve($user = null, $notrigger = 0)
855 {
856 global $conf, $langs;
857 $error = 0;
858
859 $checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type);
860
861 if ($checkBalance > 0) {
862 $balance = $this->getCPforUser($this->fk_user, $this->fk_type);
863
864 if ($balance < 0) {
865 $this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
866 return -1;
867 }
868 }
869
870 // Update request
871 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
872
873 $sql .= " description= '".$this->db->escape($this->description)."',";
874
875 if (!empty($this->date_debut)) {
876 $sql .= " date_debut = '".$this->db->idate($this->date_debut)."',";
877 } else {
878 $error++;
879 }
880 if (!empty($this->date_fin)) {
881 $sql .= " date_fin = '".$this->db->idate($this->date_fin)."',";
882 } else {
883 $error++;
884 }
885 $sql .= " halfday = ".((int) $this->halfday).",";
886 if (!empty($this->statut) && is_numeric($this->statut)) {
887 $sql .= " statut = ".((int) $this->statut).",";
888 } else {
889 $error++;
890 }
891 if (!empty($this->fk_validator)) {
892 $sql .= " fk_validator = ".((int) $this->fk_validator).",";
893 } else {
894 $error++;
895 }
896 if (!empty($this->date_valid)) {
897 $sql .= " date_valid = '".$this->db->idate($this->date_valid)."',";
898 } else {
899 $sql .= " date_valid = NULL,";
900 }
901 if (!empty($this->fk_user_valid)) {
902 $sql .= " fk_user_valid = ".((int) $this->fk_user_valid).",";
903 } else {
904 $sql .= " fk_user_valid = NULL,";
905 }
906 if (!empty($this->date_approval)) {
907 $sql .= " date_approval = '".$this->db->idate($this->date_approval)."',";
908 } else {
909 $sql .= " date_approval = NULL,";
910 }
911 if (!empty($this->fk_user_approve)) {
912 $sql .= " fk_user_approve = ".((int) $this->fk_user_approve).",";
913 } else {
914 $sql .= " fk_user_approve = NULL,";
915 }
916 if (!empty($this->date_refuse)) {
917 $sql .= " date_refuse = '".$this->db->idate($this->date_refuse)."',";
918 } else {
919 $sql .= " date_refuse = NULL,";
920 }
921 if (!empty($this->fk_user_refuse)) {
922 $sql .= " fk_user_refuse = ".((int) $this->fk_user_refuse).",";
923 } else {
924 $sql .= " fk_user_refuse = NULL,";
925 }
926 if (!empty($this->date_cancel)) {
927 $sql .= " date_cancel = '".$this->db->idate($this->date_cancel)."',";
928 } else {
929 $sql .= " date_cancel = NULL,";
930 }
931 if (!empty($this->fk_user_cancel)) {
932 $sql .= " fk_user_cancel = ".((int) $this->fk_user_cancel).",";
933 } else {
934 $sql .= " fk_user_cancel = NULL,";
935 }
936 if (!empty($this->detail_refuse)) {
937 $sql .= " detail_refuse = '".$this->db->escape($this->detail_refuse)."'";
938 } else {
939 $sql .= " detail_refuse = NULL";
940 }
941 $sql .= " WHERE rowid = ".((int) $this->id);
942
943 $this->db->begin();
944
945 dol_syslog(get_class($this)."::approve", LOG_DEBUG);
946 $resql = $this->db->query($sql);
947 if (!$resql) {
948 $error++;
949 $this->errors[] = "Error ".$this->db->lasterror();
950 }
951
952 if (!$error) {
953 if (!$notrigger) {
954 // Call trigger
955 $result = $this->call_trigger('HOLIDAY_APPROVE', $user);
956 if ($result < 0) {
957 $error++;
958 }
959 // End call triggers
960 }
961 }
962
963 // Commit or rollback
964 if ($error) {
965 foreach ($this->errors as $errmsg) {
966 dol_syslog(get_class($this)."::approve ".$errmsg, LOG_ERR);
967 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
968 }
969 $this->db->rollback();
970 return -1 * $error;
971 } else {
972 $this->db->commit();
973 return 1;
974 }
975 }
976
984 public function update($user = null, $notrigger = 0)
985 {
986 global $conf, $langs;
987 $error = 0;
988
989 $checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type);
990
991 if ($checkBalance > 0 && $this->statut != self::STATUS_DRAFT) {
992 $balance = $this->getCPforUser($this->fk_user, $this->fk_type);
993
994 if ($balance < 0) {
995 $this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
996 return -1;
997 }
998 }
999
1000 // Update request
1001 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
1002
1003 $sql .= " description= '".$this->db->escape($this->description)."',";
1004
1005 if (!empty($this->date_debut)) {
1006 $sql .= " date_debut = '".$this->db->idate($this->date_debut)."',";
1007 } else {
1008 $error++;
1009 }
1010 if (!empty($this->date_fin)) {
1011 $sql .= " date_fin = '".$this->db->idate($this->date_fin)."',";
1012 } else {
1013 $error++;
1014 }
1015 $sql .= " halfday = ".$this->halfday.",";
1016 if (!empty($this->statut) && is_numeric($this->statut)) {
1017 $sql .= " statut = ".$this->statut.",";
1018 } else {
1019 $error++;
1020 }
1021 if (!empty($this->fk_validator)) {
1022 $sql .= " fk_validator = '".$this->db->escape($this->fk_validator)."',";
1023 } else {
1024 $error++;
1025 }
1026 if (!empty($this->date_valid)) {
1027 $sql .= " date_valid = '".$this->db->idate($this->date_valid)."',";
1028 } else {
1029 $sql .= " date_valid = NULL,";
1030 }
1031 if (!empty($this->fk_user_valid)) {
1032 $sql .= " fk_user_valid = ".((int) $this->fk_user_valid).",";
1033 } else {
1034 $sql .= " fk_user_valid = NULL,";
1035 }
1036 if (!empty($this->date_approval)) {
1037 $sql .= " date_approval = '".$this->db->idate($this->date_approval)."',";
1038 } else {
1039 $sql .= " date_approval = NULL,";
1040 }
1041 if (!empty($this->fk_user_approve)) {
1042 $sql .= " fk_user_approve = ".((int) $this->fk_user_approve).",";
1043 } else {
1044 $sql .= " fk_user_approve = NULL,";
1045 }
1046 if (!empty($this->date_refuse)) {
1047 $sql .= " date_refuse = '".$this->db->idate($this->date_refuse)."',";
1048 } else {
1049 $sql .= " date_refuse = NULL,";
1050 }
1051 if (!empty($this->fk_user_refuse)) {
1052 $sql .= " fk_user_refuse = ".((int) $this->fk_user_refuse).",";
1053 } else {
1054 $sql .= " fk_user_refuse = NULL,";
1055 }
1056 if (!empty($this->date_cancel)) {
1057 $sql .= " date_cancel = '".$this->db->idate($this->date_cancel)."',";
1058 } else {
1059 $sql .= " date_cancel = NULL,";
1060 }
1061 if (!empty($this->fk_user_cancel)) {
1062 $sql .= " fk_user_cancel = ".((int) $this->fk_user_cancel).",";
1063 } else {
1064 $sql .= " fk_user_cancel = NULL,";
1065 }
1066 if (!empty($this->detail_refuse)) {
1067 $sql .= " detail_refuse = '".$this->db->escape($this->detail_refuse)."'";
1068 } else {
1069 $sql .= " detail_refuse = NULL";
1070 }
1071
1072 $sql .= " WHERE rowid = ".((int) $this->id);
1073
1074 $this->db->begin();
1075
1076 dol_syslog(get_class($this)."::update", LOG_DEBUG);
1077 $resql = $this->db->query($sql);
1078 if (!$resql) {
1079 $error++;
1080 $this->errors[] = "Error ".$this->db->lasterror();
1081 }
1082
1083 if (!$error) {
1084 if (!$notrigger) {
1085 // Call trigger
1086 $result = $this->call_trigger('HOLIDAY_MODIFY', $user);
1087 if ($result < 0) {
1088 $error++;
1089 }
1090 // End call triggers
1091 }
1092 }
1093
1094 // Commit or rollback
1095 if ($error) {
1096 foreach ($this->errors as $errmsg) {
1097 dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
1098 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1099 }
1100 $this->db->rollback();
1101 return -1 * $error;
1102 } else {
1103 $this->db->commit();
1104 return 1;
1105 }
1106 }
1107
1108
1116 public function delete($user, $notrigger = 0)
1117 {
1118 global $conf, $langs;
1119 $error = 0;
1120
1121 $sql = "DELETE FROM ".MAIN_DB_PREFIX."holiday";
1122 $sql .= " WHERE rowid=".((int) $this->id);
1123
1124 $this->db->begin();
1125
1126 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1127 $resql = $this->db->query($sql);
1128 if (!$resql) {
1129 $error++;
1130 $this->errors[] = "Error ".$this->db->lasterror();
1131 }
1132
1133 if (!$error) {
1134 if (!$notrigger) {
1135 // Call trigger
1136 $result = $this->call_trigger('HOLIDAY_DELETE', $user);
1137 if ($result < 0) {
1138 $error++;
1139 }
1140 // End call triggers
1141 }
1142 }
1143
1144 // Commit or rollback
1145 if ($error) {
1146 foreach ($this->errors as $errmsg) {
1147 dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
1148 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1149 }
1150 $this->db->rollback();
1151 return -1 * $error;
1152 } else {
1153 $this->db->commit();
1154 return 1;
1155 }
1156 }
1157
1171 public function verifDateHolidayCP($fk_user, $dateStart, $dateEnd, $halfday = 0)
1172 {
1173 $this->fetchByUser($fk_user, '', '');
1174
1175 foreach ($this->holiday as $infos_CP) {
1176 if ($infos_CP['statut'] == Holiday::STATUS_CANCELED) {
1177 continue; // ignore not validated holidays
1178 }
1179 if ($infos_CP['statut'] == Holiday::STATUS_REFUSED) {
1180 continue; // ignore refused holidays
1181 }
1182 //var_dump("--");
1183 //var_dump("old: ".dol_print_date($infos_CP['date_debut'],'dayhour').' '.dol_print_date($infos_CP['date_fin'],'dayhour').' '.$infos_CP['halfday']);
1184 //var_dump("new: ".dol_print_date($dateStart,'dayhour').' '.dol_print_date($dateEnd,'dayhour').' '.$halfday);
1185
1186 if ($halfday == 0) {
1187 if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1188 return false;
1189 }
1190 if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1191 return false;
1192 }
1193 } elseif ($halfday == -1) {
1194 // new start afternoon, new end afternoon
1195 if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1196 if ($dateStart < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
1197 return false;
1198 }
1199 }
1200 if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1201 if ($dateStart < $dateEnd) {
1202 return false;
1203 }
1204 if ($dateEnd < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
1205 return false;
1206 }
1207 }
1208 } elseif ($halfday == 1) {
1209 // new start morning, new end morning
1210 if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1211 if ($dateStart < $dateEnd) {
1212 return false;
1213 }
1214 if ($dateStart > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
1215 return false;
1216 }
1217 }
1218 if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1219 if ($dateEnd > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
1220 return false;
1221 }
1222 }
1223 } elseif ($halfday == 2) {
1224 // new start afternoon, new end morning
1225 if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1226 if ($dateStart < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
1227 return false;
1228 }
1229 }
1230 if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1231 if ($dateEnd > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
1232 return false;
1233 }
1234 }
1235 } else {
1236 dol_print_error('', 'Bad value of parameter halfday when calling function verifDateHolidayCP');
1237 }
1238 }
1239
1240 return true;
1241 }
1242
1243
1253 public function verifDateHolidayForTimestamp($fk_user, $timestamp, $status = '-1')
1254 {
1255 global $langs, $conf;
1256
1257 $isavailablemorning = true;
1258 $isavailableafternoon = true;
1259
1260 // Check into leave requests
1261 $sql = "SELECT cp.rowid, cp.date_debut as date_start, cp.date_fin as date_end, cp.halfday, cp.statut";
1262 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp";
1263 $sql .= " WHERE cp.entity IN (".getEntity('holiday').")";
1264 $sql .= " AND cp.fk_user = ".(int) $fk_user;
1265 $sql .= " AND cp.date_debut <= '".$this->db->idate($timestamp)."' AND cp.date_fin >= '".$this->db->idate($timestamp)."'";
1266 if ($status != '-1') {
1267 $sql .= " AND cp.statut IN (".$this->db->sanitize($status).")";
1268 }
1269
1270 $resql = $this->db->query($sql);
1271 if ($resql) {
1272 $num_rows = $this->db->num_rows($resql); // Note, we can have 2 records if on is morning and the other one is afternoon
1273 if ($num_rows > 0) {
1274 $arrayofrecord = array();
1275 $i = 0;
1276 while ($i < $num_rows) {
1277 $obj = $this->db->fetch_object($resql);
1278
1279 // Note: $obj->halfday is 0:Full days, 2:Sart afternoon end morning, -1:Start afternoon, 1:End morning
1280 $arrayofrecord[$obj->rowid] = array('date_start'=>$this->db->jdate($obj->date_start), 'date_end'=>$this->db->jdate($obj->date_end), 'halfday'=>$obj->halfday);
1281 $i++;
1282 }
1283
1284 // We found a record, user is on holiday by default, so is not available is true.
1285 $isavailablemorning = true;
1286 foreach ($arrayofrecord as $record) {
1287 if ($timestamp == $record['date_start'] && $record['halfday'] == 2) {
1288 continue;
1289 }
1290 if ($timestamp == $record['date_start'] && $record['halfday'] == -1) {
1291 continue;
1292 }
1293 $isavailablemorning = false;
1294 break;
1295 }
1296 $isavailableafternoon = true;
1297 foreach ($arrayofrecord as $record) {
1298 if ($timestamp == $record['date_end'] && $record['halfday'] == 2) {
1299 continue;
1300 }
1301 if ($timestamp == $record['date_end'] && $record['halfday'] == 1) {
1302 continue;
1303 }
1304 $isavailableafternoon = false;
1305 break;
1306 }
1307 }
1308 } else {
1309 dol_print_error($this->db);
1310 }
1311
1312 $result = array('morning'=>$isavailablemorning, 'afternoon'=>$isavailableafternoon);
1313 if (!$isavailablemorning) {
1314 $result['morning_reason'] = 'leave_request';
1315 }
1316 if (!$isavailableafternoon) {
1317 $result['afternoon_reason'] = 'leave_request';
1318 }
1319 return $result;
1320 }
1321
1329 public function getTooltipContentArray($params)
1330 {
1331 global $conf, $langs;
1332
1333 $langs->load('holiday');
1334 $nofetch = !empty($params['nofetch']);
1335
1336 $datas = array();
1337 $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Holiday").'</u>';
1338 if (isset($this->statut)) {
1339 $datas['picto'] .= ' '.$this->getLibStatut(5);
1340 }
1341 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
1342 // show type for this record only in ajax to not overload lists
1343 if (!$nofetch && !empty($this->fk_type)) {
1344 $typeleaves = $this->getTypes(1, -1);
1345 $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']);
1346 $datas['type'] = '<br><b>'.$langs->trans("Type") . ':</b> ' . (empty($labeltoshow) ? $langs->trans("TypeWasDisabledOrRemoved", $this->fk_type) : $labeltoshow);
1347 }
1348 if (isset($this->halfday) && !empty($this->date_debut) && !empty($this->date_fin)) {
1349 $listhalfday = array(
1350 'morning' => $langs->trans("Morning"),
1351 "afternoon" => $langs->trans("Afternoon")
1352 );
1353 $starthalfday = ($this->halfday == -1 || $this->halfday == 2) ? 'afternoon' : 'morning';
1354 $endhalfday = ($this->halfday == 1 || $this->halfday == 2) ? 'morning' : 'afternoon';
1355 $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>';
1356 $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>';
1357 }
1358
1359
1360 return $datas;
1361 }
1362
1372 public function getNomUrl($withpicto = 0, $save_lastsearch_value = -1, $notooltip = 0, $morecss = '')
1373 {
1374 global $conf, $langs, $hookmanager;
1375
1376 if (!empty($conf->dol_no_mouse_hover)) {
1377 $notooltip = 1; // Force disable tooltips
1378 }
1379
1380 $result = '';
1381 $params = [
1382 'id' => $this->id,
1383 'objecttype' => $this->element,
1384 'nofetch' => 1,
1385 ];
1386 $classfortooltip = 'classfortooltip';
1387 $dataparams = '';
1388 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1389 $classfortooltip = 'classforajaxtooltip';
1390 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1391 $label = '';
1392 } else {
1393 $label = implode($this->getTooltipContentArray($params));
1394 }
1395
1396 $url = DOL_URL_ROOT.'/holiday/card.php?id='.$this->id;
1397
1398 //if ($option != 'nolink')
1399 //{
1400 // Add param to save lastsearch_values or not
1401 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1402 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1403 $add_save_lastsearch_values = 1;
1404 }
1405 if ($add_save_lastsearch_values) {
1406 $url .= '&save_lastsearch_values=1';
1407 }
1408 //}
1409
1410 $linkclose = '';
1411 if (empty($notooltip)) {
1412 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1413 $label = $langs->trans("ShowMyObject");
1414 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
1415 }
1416 $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
1417 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
1418 } else {
1419 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1420 }
1421
1422 $linkstart = '<a href="'.$url.'"';
1423 $linkstart .= $linkclose.'>';
1424 $linkend = '</a>';
1425
1426 $result .= $linkstart;
1427
1428 if ($withpicto) {
1429 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
1430 }
1431 if ($withpicto != 2) {
1432 $result .= $this->ref;
1433 }
1434 $result .= $linkend;
1435
1436 global $action;
1437 $hookmanager->initHooks(array($this->element . 'dao'));
1438 $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
1439 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1440 if ($reshook > 0) {
1441 $result = $hookmanager->resPrint;
1442 } else {
1443 $result .= $hookmanager->resPrint;
1444 }
1445 return $result;
1446 }
1447
1448
1455 public function getLibStatut($mode = 0)
1456 {
1457 return $this->LibStatut($this->statut, $mode, $this->date_debut);
1458 }
1459
1460 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1469 public function LibStatut($status, $mode = 0, $startdate = '')
1470 {
1471 // phpcs:enable
1472 global $langs;
1473
1474 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
1475 global $langs;
1476 //$langs->load("mymodule");
1477 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP');
1478 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP');
1479 $this->labelStatus[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP');
1480 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP');
1481 $this->labelStatus[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP');
1482 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP');
1483 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP');
1484 $this->labelStatusShort[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP');
1485 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP');
1486 $this->labelStatusShort[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP');
1487 }
1488
1489 $params = array();
1490 $statusType = 'status6';
1491 if (!empty($startdate) && $startdate >= dol_now()) { // If not yet passed, we use a green "in live" color
1492 $statusType = 'status4';
1493 $params = array('tooltip'=>$this->labelStatus[$status].' - '.$langs->trans("Forthcoming"));
1494 }
1495 if ($status == self::STATUS_DRAFT) {
1496 $statusType = 'status0';
1497 }
1498 if ($status == self::STATUS_VALIDATED) {
1499 $statusType = 'status1';
1500 }
1501 if ($status == self::STATUS_CANCELED) {
1502 $statusType = 'status9';
1503 }
1504 if ($status == self::STATUS_REFUSED) {
1505 $statusType = 'status9';
1506 }
1507
1508 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode, '', $params);
1509 }
1510
1511
1520 public function selectStatutCP($selected = '', $htmlname = 'select_statut', $morecss = 'minwidth125')
1521 {
1522 global $langs;
1523
1524 // List of status label
1525 $name = array('DraftCP', 'ToReviewCP', 'ApprovedCP', 'CancelCP', 'RefuseCP');
1526 $nb = count($name) + 1;
1527
1528 // Select HTML
1529 $out = '<select name="'.$htmlname.'" id="'.$htmlname.'" class="flat'.($morecss ? ' '.$morecss : '').'">'."\n";
1530 $out .= '<option value="-1">&nbsp;</option>'."\n";
1531
1532 // Loop on status
1533 for ($i = 1; $i < $nb; $i++) {
1534 if ($i == $selected) {
1535 $out .= '<option value="'.$i.'" selected>'.$langs->trans($name[$i - 1]).'</option>'."\n";
1536 } else {
1537 $out .= '<option value="'.$i.'">'.$langs->trans($name[$i - 1]).'</option>'."\n";
1538 }
1539 }
1540
1541 $out .= '</select>'."\n";
1542
1543 $showempty= 0;
1544 $out .= ajax_combobox($htmlname, array(), 0, 0, 'resolve', ($showempty < 0 ? (string) $showempty : '-1'), $morecss);
1545
1546 return $out;
1547 }
1548
1556 public function updateConfCP($name, $value)
1557 {
1558 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
1559 $sql .= " value = '".$this->db->escape($value)."'";
1560 $sql .= " WHERE name = '".$this->db->escape($name)."'";
1561
1562 dol_syslog(get_class($this).'::updateConfCP name='.$name, LOG_DEBUG);
1563 $result = $this->db->query($sql);
1564 if ($result) {
1565 return true;
1566 }
1567
1568 return false;
1569 }
1570
1579 public function getConfCP($name, $createifnotfound = '')
1580 {
1581 $sql = "SELECT value";
1582 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_config";
1583 $sql .= " WHERE name = '".$this->db->escape($name)."'";
1584
1585 dol_syslog(get_class($this).'::getConfCP name='.$name.' createifnotfound='.$createifnotfound, LOG_DEBUG);
1586 $result = $this->db->query($sql);
1587
1588 if ($result) {
1589 $obj = $this->db->fetch_object($result);
1590 // Return value
1591 if (empty($obj)) {
1592 if ($createifnotfound) {
1593 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_config(name, value)";
1594 $sql .= " VALUES('".$this->db->escape($name)."', '".$this->db->escape($createifnotfound)."')";
1595 $result = $this->db->query($sql);
1596 if ($result) {
1597 return $createifnotfound;
1598 } else {
1599 $this->error = $this->db->lasterror();
1600 return -2;
1601 }
1602 } else {
1603 return '';
1604 }
1605 } else {
1606 return $obj->value;
1607 }
1608 } else {
1609 // Erreur SQL
1610 $this->error = $this->db->lasterror();
1611 return -1;
1612 }
1613 }
1614
1623 public function updateSoldeCP($userID = '', $nbHoliday = '', $fk_type = '')
1624 {
1625 global $user, $langs;
1626
1627 $error = 0;
1628
1629 if (empty($userID) && empty($nbHoliday) && empty($fk_type)) {
1630 $langs->load("holiday");
1631
1632 // Si mise à jour pour tout le monde en début de mois
1633 $now = dol_now();
1634
1635 $month = date('m', $now);
1636 $newdateforlastupdate = dol_print_date($now, '%Y%m%d%H%M%S');
1637
1638 // Get month of last update
1639 $lastUpdate = $this->getConfCP('lastUpdate', $newdateforlastupdate);
1640 $monthLastUpdate = $lastUpdate[4].$lastUpdate[5];
1641 //print 'month: '.$month.' lastUpdate:'.$lastUpdate.' monthLastUpdate:'.$monthLastUpdate;exit;
1642
1643 // 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.
1644 if ($month != $monthLastUpdate) {
1645 $this->db->begin();
1646
1647 $users = $this->fetchUsers(false, false, ' AND u.statut > 0');
1648 $nbUser = count($users);
1649
1650 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
1651 $sql .= " value = '".$this->db->escape($newdateforlastupdate)."'";
1652 $sql .= " WHERE name = 'lastUpdate'";
1653 $result = $this->db->query($sql);
1654
1655 $typeleaves = $this->getTypes(1, 1);
1656
1657 // Update each user counter
1658 foreach ($users as $userCounter) {
1659 $nbDaysToAdd = (isset($typeleaves[$userCounter['type']]['newbymonth']) ? $typeleaves[$userCounter['type']]['newbymonth'] : 0);
1660 if (empty($nbDaysToAdd)) {
1661 continue;
1662 }
1663
1664 dol_syslog("We update leave type id ".$userCounter['type']." for user id ".$userCounter['rowid'], LOG_DEBUG);
1665
1666 $nowHoliday = $userCounter['nb_holiday'];
1667 $newSolde = $nowHoliday + $nbDaysToAdd;
1668
1669 // We add a log for each user
1670 $this->addLogCP($user->id, $userCounter['rowid'], $langs->trans('HolidaysMonthlyUpdate'), $newSolde, $userCounter['type']);
1671
1672 $result = $this->updateSoldeCP($userCounter['rowid'], $newSolde, $userCounter['type']);
1673
1674 if ($result < 0) {
1675 $error++;
1676 break;
1677 }
1678 }
1679
1680 if (!$error) {
1681 $this->db->commit();
1682 return 1;
1683 } else {
1684 $this->db->rollback();
1685 return -1;
1686 }
1687 }
1688
1689 return 0;
1690 } else {
1691 // Mise à jour pour un utilisateur
1692 $nbHoliday = price2num($nbHoliday, 5);
1693
1694 $sql = "SELECT nb_holiday FROM ".MAIN_DB_PREFIX."holiday_users";
1695 $sql .= " WHERE fk_user = ".(int) $userID." AND fk_type = ".(int) $fk_type;
1696 $resql = $this->db->query($sql);
1697 if ($resql) {
1698 $num = $this->db->num_rows($resql);
1699
1700 if ($num > 0) {
1701 // Update for user
1702 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_users SET";
1703 $sql .= " nb_holiday = ".((float) $nbHoliday);
1704 $sql .= " WHERE fk_user = ".(int) $userID." AND fk_type = ".(int) $fk_type;
1705 $result = $this->db->query($sql);
1706 if (!$result) {
1707 $error++;
1708 $this->errors[] = $this->db->lasterror();
1709 }
1710 } else {
1711 // Insert for user
1712 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users(nb_holiday, fk_user, fk_type) VALUES (";
1713 $sql .= ((float) $nbHoliday);
1714 $sql .= ", ".(int) $userID.", ".(int) $fk_type.")";
1715 $result = $this->db->query($sql);
1716 if (!$result) {
1717 $error++;
1718 $this->errors[] = $this->db->lasterror();
1719 }
1720 }
1721 } else {
1722 $this->errors[] = $this->db->lasterror();
1723 $error++;
1724 }
1725
1726 if (!$error) {
1727 return 1;
1728 } else {
1729 return -1;
1730 }
1731 }
1732 }
1733
1741 public function createCPusers($single = false, $userid = '')
1742 {
1743 // do we have to add balance for all users ?
1744 if (!$single) {
1745 dol_syslog(get_class($this).'::createCPusers');
1746 $arrayofusers = $this->fetchUsers(false, true);
1747
1748 foreach ($arrayofusers as $users) {
1749 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users";
1750 $sql .= " (fk_user, nb_holiday)";
1751 $sql .= " VALUES (".((int) $users['rowid'])."', '0')";
1752
1753 $resql = $this->db->query($sql);
1754 if (!$resql) {
1755 dol_print_error($this->db);
1756 }
1757 }
1758 } else {
1759 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users";
1760 $sql .= " (fk_user, nb_holiday)";
1761 $sql .= " VALUES (".((int) $userid)."', '0')";
1762
1763 $resql = $this->db->query($sql);
1764 if (!$resql) {
1765 dol_print_error($this->db);
1766 }
1767 }
1768 }
1769
1777 public function getCPforUser($user_id, $fk_type = 0)
1778 {
1779 $sql = "SELECT nb_holiday";
1780 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users";
1781 $sql .= " WHERE fk_user = ".(int) $user_id;
1782 if ($fk_type > 0) {
1783 $sql .= " AND fk_type = ".(int) $fk_type;
1784 }
1785
1786 dol_syslog(get_class($this).'::getCPforUser user_id='.$user_id.' type_id='.$fk_type, LOG_DEBUG);
1787 $result = $this->db->query($sql);
1788 if ($result) {
1789 $obj = $this->db->fetch_object($result);
1790 //return number_format($obj->nb_holiday,2);
1791 if ($obj) {
1792 return $obj->nb_holiday;
1793 } else {
1794 return null;
1795 }
1796 } else {
1797 return null;
1798 }
1799 }
1800
1809 public function fetchUsers($stringlist = true, $type = true, $filters = '')
1810 {
1811 global $conf;
1812
1813 dol_syslog(get_class($this)."::fetchUsers", LOG_DEBUG);
1814
1815 if ($stringlist) {
1816 if ($type) {
1817 // If user of Dolibarr
1818 $sql = "SELECT";
1819 if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
1820 $sql .= " DISTINCT";
1821 }
1822 $sql .= " u.rowid";
1823 $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
1824
1825 if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
1826 $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
1827 $sql .= " WHERE ((ug.fk_user = u.rowid";
1828 $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
1829 $sql .= " OR u.entity = 0)"; // Show always superadmin
1830 } else {
1831 $sql .= " WHERE u.entity IN (".getEntity('user').")";
1832 }
1833 $sql .= " AND u.statut > 0";
1834 $sql .= " AND u.employee = 1"; // We only want employee users for holidays
1835 if ($filters) {
1836 $sql .= $filters;
1837 }
1838
1839 $resql = $this->db->query($sql);
1840
1841 // Si pas d'erreur SQL
1842 if ($resql) {
1843 $i = 0;
1844 $num = $this->db->num_rows($resql);
1845 $stringlist = '';
1846
1847 // Boucles du listage des utilisateurs
1848 while ($i < $num) {
1849 $obj = $this->db->fetch_object($resql);
1850
1851 if ($i == 0) {
1852 $stringlist .= $obj->rowid;
1853 } else {
1854 $stringlist .= ', '.$obj->rowid;
1855 }
1856
1857 $i++;
1858 }
1859 // Retoune le tableau des utilisateurs
1860 return $stringlist;
1861 } else {
1862 // Erreur SQL
1863 $this->error = "Error ".$this->db->lasterror();
1864 return -1;
1865 }
1866 } else {
1867 // We want only list of vacation balance for user ids
1868 $sql = "SELECT DISTINCT cpu.fk_user";
1869 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u";
1870 $sql .= " WHERE cpu.fk_user = u.rowid";
1871 if ($filters) {
1872 $sql .= $filters;
1873 }
1874
1875 $resql = $this->db->query($sql);
1876
1877 // Si pas d'erreur SQL
1878 if ($resql) {
1879 $i = 0;
1880 $num = $this->db->num_rows($resql);
1881 $stringlist = '';
1882
1883 // Boucles du listage des utilisateurs
1884 while ($i < $num) {
1885 $obj = $this->db->fetch_object($resql);
1886
1887 if ($i == 0) {
1888 $stringlist .= $obj->fk_user;
1889 } else {
1890 $stringlist .= ', '.$obj->fk_user;
1891 }
1892
1893 $i++;
1894 }
1895 // Retoune le tableau des utilisateurs
1896 return $stringlist;
1897 } else {
1898 // Erreur SQL
1899 $this->error = "Error ".$this->db->lasterror();
1900 return -1;
1901 }
1902 }
1903 } else {
1904 // Si faux donc return array
1905 // List for Dolibarr users
1906 if ($type) {
1907 // If we need users of Dolibarr
1908 $sql = "SELECT";
1909 if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
1910 $sql .= " DISTINCT";
1911 }
1912 $sql .= " u.rowid, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut, u.fk_user";
1913 $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
1914
1915 if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
1916 $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
1917 $sql .= " WHERE ((ug.fk_user = u.rowid";
1918 $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
1919 $sql .= " OR u.entity = 0)"; // Show always superadmin
1920 } else {
1921 $sql .= " WHERE u.entity IN (".getEntity('user').")";
1922 }
1923
1924 $sql .= " AND u.statut > 0";
1925 $sql .= " AND u.employee = 1"; // We only want employee users for holidays
1926 if ($filters) {
1927 $sql .= $filters;
1928 }
1929
1930 $resql = $this->db->query($sql);
1931
1932 // Si pas d'erreur SQL
1933 if ($resql) {
1934 $i = 0;
1935 $tab_result = $this->holiday;
1936 $num = $this->db->num_rows($resql);
1937
1938 // Boucles du listage des utilisateurs
1939 while ($i < $num) {
1940 $obj = $this->db->fetch_object($resql);
1941
1942 $tab_result[$i]['rowid'] = $obj->rowid; // rowid of user
1943 $tab_result[$i]['id'] = $obj->rowid; // id of user
1944 $tab_result[$i]['name'] = $obj->lastname; // deprecated
1945 $tab_result[$i]['lastname'] = $obj->lastname;
1946 $tab_result[$i]['firstname'] = $obj->firstname;
1947 $tab_result[$i]['gender'] = $obj->gender;
1948 $tab_result[$i]['status'] = $obj->statut;
1949 $tab_result[$i]['employee'] = $obj->employee;
1950 $tab_result[$i]['photo'] = $obj->photo;
1951 $tab_result[$i]['fk_user'] = $obj->fk_user; // rowid of manager
1952 //$tab_result[$i]['type'] = $obj->type;
1953 //$tab_result[$i]['nb_holiday'] = $obj->nb_holiday;
1954
1955 $i++;
1956 }
1957 // Retoune le tableau des utilisateurs
1958 return $tab_result;
1959 } else {
1960 // Erreur SQL
1961 $this->errors[] = "Error ".$this->db->lasterror();
1962 return -1;
1963 }
1964 } else {
1965 // List of vacation balance users
1966 $sql = "SELECT cpu.fk_type, cpu.nb_holiday, u.rowid, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut, u.fk_user";
1967 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u";
1968 $sql .= " WHERE cpu.fk_user = u.rowid";
1969 if ($filters) {
1970 $sql .= $filters;
1971 }
1972
1973 $resql = $this->db->query($sql);
1974
1975 // Si pas d'erreur SQL
1976 if ($resql) {
1977 $i = 0;
1978 $tab_result = $this->holiday;
1979 $num = $this->db->num_rows($resql);
1980
1981 // Boucles du listage des utilisateurs
1982 while ($i < $num) {
1983 $obj = $this->db->fetch_object($resql);
1984
1985 $tab_result[$i]['rowid'] = $obj->rowid; // rowid of user
1986 $tab_result[$i]['id'] = $obj->rowid; // id of user
1987 $tab_result[$i]['name'] = $obj->lastname; // deprecated
1988 $tab_result[$i]['lastname'] = $obj->lastname;
1989 $tab_result[$i]['firstname'] = $obj->firstname;
1990 $tab_result[$i]['gender'] = $obj->gender;
1991 $tab_result[$i]['status'] = $obj->statut;
1992 $tab_result[$i]['employee'] = $obj->employee;
1993 $tab_result[$i]['photo'] = $obj->photo;
1994 $tab_result[$i]['fk_user'] = $obj->fk_user; // rowid of manager
1995
1996 $tab_result[$i]['type'] = $obj->fk_type;
1997 $tab_result[$i]['nb_holiday'] = $obj->nb_holiday;
1998
1999 $i++;
2000 }
2001 // Retoune le tableau des utilisateurs
2002 return $tab_result;
2003 } else {
2004 // Erreur SQL
2005 $this->error = "Error ".$this->db->lasterror();
2006 return -1;
2007 }
2008 }
2009 }
2010 }
2011
2012
2013 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2021 {
2022 // phpcs:enable
2023 $users_validator = array();
2024
2025 $sql = "SELECT DISTINCT ur.fk_user";
2026 $sql .= " FROM ".MAIN_DB_PREFIX."user_rights as ur, ".MAIN_DB_PREFIX."rights_def as rd";
2027 $sql .= " WHERE ur.fk_id = rd.id and rd.module = 'holiday' AND rd.perms = 'approve'"; // Permission 'Approve';
2028 $sql .= "UNION";
2029 $sql .= " SELECT DISTINCT ugu.fk_user";
2030 $sql .= " FROM ".MAIN_DB_PREFIX."usergroup_user as ugu, ".MAIN_DB_PREFIX."usergroup_rights as ur, ".MAIN_DB_PREFIX."rights_def as rd";
2031 $sql .= " WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'holiday' AND rd.perms = 'approve'"; // Permission 'Approve';
2032 //print $sql;
2033
2034 dol_syslog(get_class($this)."::fetch_users_approver_holiday sql=".$sql);
2035 $result = $this->db->query($sql);
2036 if ($result) {
2037 $num_rows = $this->db->num_rows($result);
2038 $i = 0;
2039 while ($i < $num_rows) {
2040 $objp = $this->db->fetch_object($result);
2041 array_push($users_validator, $objp->fk_user);
2042 $i++;
2043 }
2044 return $users_validator;
2045 } else {
2046 $this->error = $this->db->lasterror();
2047 dol_syslog(get_class($this)."::fetch_users_approver_holiday Error ".$this->error, LOG_ERR);
2048 return -1;
2049 }
2050 }
2051
2052
2058 public function countActiveUsers()
2059 {
2060 $sql = "SELECT count(u.rowid) as compteur";
2061 $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
2062 $sql .= " WHERE u.statut > 0";
2063
2064 $result = $this->db->query($sql);
2065 $objet = $this->db->fetch_object($result);
2066
2067 return $objet->compteur;
2068 }
2075 {
2076 $sql = "SELECT count(u.rowid) as compteur";
2077 $sql .= " FROM ".MAIN_DB_PREFIX."user as u LEFT OUTER JOIN ".MAIN_DB_PREFIX."holiday_users hu ON (hu.fk_user=u.rowid)";
2078 $sql .= " WHERE u.statut > 0 AND hu.fk_user IS NULL";
2079
2080 $result = $this->db->query($sql);
2081 $objet = $this->db->fetch_object($result);
2082
2083 return $objet->compteur;
2084 }
2085
2093 public function verifNbUsers($userDolibarrWithoutCP, $userCP)
2094 {
2095 if (empty($userCP)) {
2096 $userCP = 0;
2097 }
2098 dol_syslog(get_class($this).'::verifNbUsers userDolibarr='.$userDolibarrWithoutCP.' userCP='.$userCP);
2099 return 1;
2100 }
2101
2102
2113 public function addLogCP($fk_user_action, $fk_user_update, $label, $new_solde, $fk_type)
2114 {
2115 global $conf, $langs;
2116
2117 $error = 0;
2118
2119 $prev_solde = price2num($this->getCPforUser($fk_user_update, $fk_type), 5);
2120 $new_solde = price2num($new_solde, 5);
2121 //print "$prev_solde == $new_solde";
2122
2123 if ($prev_solde == $new_solde) {
2124 return 0;
2125 }
2126
2127 $this->db->begin();
2128
2129 // Insert request
2130 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_logs (";
2131 $sql .= "date_action,";
2132 $sql .= "fk_user_action,";
2133 $sql .= "fk_user_update,";
2134 $sql .= "type_action,";
2135 $sql .= "prev_solde,";
2136 $sql .= "new_solde,";
2137 $sql .= "fk_type";
2138 $sql .= ") VALUES (";
2139 $sql .= " '".$this->db->idate(dol_now())."',";
2140 $sql .= " ".((int) $fk_user_action).",";
2141 $sql .= " ".((int) $fk_user_update).",";
2142 $sql .= " '".$this->db->escape($label)."',";
2143 $sql .= " ".((float) $prev_solde).",";
2144 $sql .= " ".((float) $new_solde).",";
2145 $sql .= " ".((int) $fk_type);
2146 $sql .= ")";
2147
2148 $resql = $this->db->query($sql);
2149 if (!$resql) {
2150 $error++;
2151 $this->errors[] = "Error ".$this->db->lasterror();
2152 }
2153
2154 if (!$error) {
2155 $this->optRowid = $this->db->last_insert_id(MAIN_DB_PREFIX."holiday_logs");
2156 }
2157
2158 // Commit or rollback
2159 if ($error) {
2160 foreach ($this->errors as $errmsg) {
2161 dol_syslog(get_class($this)."::addLogCP ".$errmsg, LOG_ERR);
2162 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
2163 }
2164 $this->db->rollback();
2165 return -1 * $error;
2166 } else {
2167 $this->db->commit();
2168 return $this->optRowid;
2169 }
2170 }
2171
2179 public function fetchLog($order, $filter)
2180 {
2181 $sql = "SELECT";
2182 $sql .= " cpl.rowid,";
2183 $sql .= " cpl.date_action,";
2184 $sql .= " cpl.fk_user_action,";
2185 $sql .= " cpl.fk_user_update,";
2186 $sql .= " cpl.type_action,";
2187 $sql .= " cpl.prev_solde,";
2188 $sql .= " cpl.new_solde,";
2189 $sql .= " cpl.fk_type";
2190 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_logs as cpl";
2191 $sql .= " WHERE cpl.rowid > 0"; // To avoid error with other search and criteria
2192
2193 // Filtrage de séléction
2194 if (!empty($filter)) {
2195 $sql .= " ".$filter;
2196 }
2197
2198 // Ordre d'affichage
2199 if (!empty($order)) {
2200 $sql .= " ".$order;
2201 }
2202
2203 dol_syslog(get_class($this)."::fetchLog", LOG_DEBUG);
2204 $resql = $this->db->query($sql);
2205
2206 // Si pas d'erreur SQL
2207 if ($resql) {
2208 $i = 0;
2209 $tab_result = $this->logs;
2210 $num = $this->db->num_rows($resql);
2211
2212 // Si pas d'enregistrement
2213 if (!$num) {
2214 return 2;
2215 }
2216
2217 // On liste les résultats et on les ajoutent dans le tableau
2218 while ($i < $num) {
2219 $obj = $this->db->fetch_object($resql);
2220
2221 $tab_result[$i]['rowid'] = $obj->rowid;
2222 $tab_result[$i]['id'] = $obj->rowid;
2223 $tab_result[$i]['date_action'] = $obj->date_action;
2224 $tab_result[$i]['fk_user_action'] = $obj->fk_user_action;
2225 $tab_result[$i]['fk_user_update'] = $obj->fk_user_update;
2226 $tab_result[$i]['type_action'] = $obj->type_action;
2227 $tab_result[$i]['prev_solde'] = $obj->prev_solde;
2228 $tab_result[$i]['new_solde'] = $obj->new_solde;
2229 $tab_result[$i]['fk_type'] = $obj->fk_type;
2230
2231 $i++;
2232 }
2233 // Retourne 1 et ajoute le tableau à la variable
2234 $this->logs = $tab_result;
2235 return 1;
2236 } else {
2237 // Erreur SQL
2238 $this->error = "Error ".$this->db->lasterror();
2239 return -1;
2240 }
2241 }
2242
2243
2251 public function getTypes($active = -1, $affect = -1)
2252 {
2253 global $mysoc;
2254
2255 $sql = "SELECT rowid, code, label, affect, delay, newbymonth";
2256 $sql .= " FROM ".MAIN_DB_PREFIX."c_holiday_types";
2257 $sql .= " WHERE (fk_country IS NULL OR fk_country = ".((int) $mysoc->country_id).')';
2258 if ($active >= 0) {
2259 $sql .= " AND active = ".((int) $active);
2260 }
2261 if ($affect >= 0) {
2262 $sql .= " AND affect = ".((int) $affect);
2263 }
2264 $sql .= " ORDER BY sortorder";
2265
2266 $result = $this->db->query($sql);
2267 if ($result) {
2268 $num = $this->db->num_rows($result);
2269 if ($num) {
2270 while ($obj = $this->db->fetch_object($result)) {
2271 $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);
2272 }
2273
2274 return $types;
2275 }
2276 } else {
2277 dol_print_error($this->db);
2278 }
2279
2280 return array();
2281 }
2282
2283
2290 public function info($id)
2291 {
2292 global $conf;
2293
2294 $sql = "SELECT f.rowid, f.statut as status,";
2295 $sql .= " f.date_create as datec,";
2296 $sql .= " f.tms as date_modification,";
2297 $sql .= " f.date_valid as datev,";
2298 $sql .= " f.date_approval as datea,";
2299 $sql .= " f.date_refuse as dater,";
2300 $sql .= " f.fk_user_create as fk_user_creation,";
2301 $sql .= " f.fk_user_modif as fk_user_modification,";
2302 $sql .= " f.fk_user_valid as fk_user_validation,";
2303 $sql .= " f.fk_user_approve as fk_user_approval_done,";
2304 $sql .= " f.fk_validator as fk_user_approval_expected,";
2305 $sql .= " f.fk_user_refuse as fk_user_refuse";
2306 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as f";
2307 $sql .= " WHERE f.rowid = ".((int) $id);
2308 $sql .= " AND f.entity = ".$conf->entity;
2309
2310 $resql = $this->db->query($sql);
2311 if ($resql) {
2312 if ($this->db->num_rows($resql)) {
2313 $obj = $this->db->fetch_object($resql);
2314
2315 $this->id = $obj->rowid;
2316
2317 $this->date_creation = $this->db->jdate($obj->datec);
2318 $this->date_modification = $this->db->jdate($obj->date_modification);
2319 $this->date_validation = $this->db->jdate($obj->datev);
2320 $this->date_approval = $this->db->jdate($obj->datea);
2321
2322 $this->user_creation_id = $obj->fk_user_creation;
2323 $this->user_validation_id = $obj->fk_user_valid;
2324 $this->user_modification_id = $obj->fk_user_modification;
2325
2326 if ($obj->status == Holiday::STATUS_APPROVED || $obj->status == Holiday::STATUS_CANCELED) {
2327 if ($obj->fk_user_approval_done) {
2328 $this->fk_user_approve = $obj->fk_user_approval_done;
2329 }
2330 }
2331 }
2332 $this->db->free($resql);
2333 } else {
2334 dol_print_error($this->db);
2335 }
2336 }
2337
2338
2346 public function initAsSpecimen()
2347 {
2348 global $user, $langs;
2349
2350 // Initialise parameters
2351 $this->id = 0;
2352 $this->specimen = 1;
2353
2354 $this->fk_user = $user->id;
2355 $this->description = 'SPECIMEN description';
2356 $this->date_debut = dol_now();
2357 $this->date_fin = dol_now() + (24 * 3600);
2358 $this->date_valid = dol_now();
2359 $this->fk_validator = $user->id;
2360 $this->halfday = 0;
2361 $this->fk_type = 1;
2363 }
2364
2365 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2371 public function load_state_board()
2372 {
2373 // phpcs:enable
2374 global $user;
2375
2376 $this->nb = array();
2377
2378 $sql = "SELECT count(h.rowid) as nb";
2379 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
2380 $sql .= " WHERE h.statut > 1";
2381 $sql .= " AND h.entity IN (".getEntity('holiday').")";
2382 if (!$user->hasRight('expensereport', 'readall')) {
2383 $userchildids = $user->getAllChildIds(1);
2384 $sql .= " AND (h.fk_user IN (".$this->db->sanitize(join(',', $userchildids)).")";
2385 $sql .= " OR h.fk_validator IN (".$this->db->sanitize(join(',', $userchildids))."))";
2386 }
2387
2388 $resql = $this->db->query($sql);
2389 if ($resql) {
2390 while ($obj = $this->db->fetch_object($resql)) {
2391 $this->nb["holidays"] = $obj->nb;
2392 }
2393 $this->db->free($resql);
2394 return 1;
2395 } else {
2396 dol_print_error($this->db);
2397 $this->error = $this->db->error();
2398 return -1;
2399 }
2400 }
2401
2402 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2409 public function load_board($user)
2410 {
2411 // phpcs:enable
2412 global $conf, $langs;
2413
2414 if ($user->socid) {
2415 return -1; // protection pour eviter appel par utilisateur externe
2416 }
2417
2418 $now = dol_now();
2419
2420 $sql = "SELECT h.rowid, h.date_debut";
2421 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
2422 $sql .= " WHERE h.statut = 2";
2423 $sql .= " AND h.entity IN (".getEntity('holiday').")";
2424 if (!$user->hasRight('expensereport', 'read_all')) {
2425 $userchildids = $user->getAllChildIds(1);
2426 $sql .= " AND (h.fk_user IN (".$this->db->sanitize(join(',', $userchildids)).")";
2427 $sql .= " OR h.fk_validator IN (".$this->db->sanitize(join(',', $userchildids))."))";
2428 }
2429
2430 $resql = $this->db->query($sql);
2431 if ($resql) {
2432 $langs->load("members");
2433
2434 $response = new WorkboardResponse();
2435 $response->warning_delay = $conf->holiday->approve->warning_delay / 60 / 60 / 24;
2436 $response->label = $langs->trans("HolidaysToApprove");
2437 $response->labelShort = $langs->trans("ToApprove");
2438 $response->url = DOL_URL_ROOT.'/holiday/list.php?search_status=2&amp;mainmenu=hrm&amp;leftmenu=holiday';
2439 $response->img = img_object('', "holiday");
2440
2441 while ($obj = $this->db->fetch_object($resql)) {
2442 $response->nbtodo++;
2443
2444 if ($this->db->jdate($obj->date_debut) < ($now - $conf->holiday->approve->warning_delay)) {
2445 $response->nbtodolate++;
2446 }
2447 }
2448
2449 return $response;
2450 } else {
2451 dol_print_error($this->db);
2452 $this->error = $this->db->error();
2453 return -1;
2454 }
2455 }
2463 public function getKanbanView($option = '', $arraydata = null)
2464 {
2465 global $langs;
2466
2467 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
2468
2469 $return = '<div class="box-flex-item box-flex-grow-zero">';
2470 $return .= '<div class="info-box info-box-sm">';
2471 $return .= '<span class="info-box-icon bg-infobox-action">';
2472 $return .= img_picto('', $this->picto);
2473 $return .= '</span>';
2474 $return .= '<div class="info-box-content">';
2475 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.$arraydata['user']->getNomUrl(-1).'</span>';
2476 if ($selected >= 0) {
2477 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
2478 }
2479 if (property_exists($this, 'fk_type')) {
2480 $return .= '<br>';
2481 //$return .= '<span class="opacitymedium">'.$langs->trans("Type").'</span> : ';
2482 $return .= '<div class="info_box-label tdoverflowmax100" title="'.dol_escape_htmltag($arraydata['labeltype']).'">'.dol_escape_htmltag($arraydata['labeltype']).'</div>';
2483 }
2484 if (property_exists($this, 'date_debut') && property_exists($this, 'date_fin')) {
2485 $return .= '<span class="info-box-label small">'.dol_print_date($this->date_debut, 'day').'</span>';
2486 $return .= ' <span class="opacitymedium small">'.$langs->trans("To").'</span> ';
2487 $return .= '<span class="info-box-label small">'.dol_print_date($this->date_fin, 'day').'</span>';
2488 if (!empty($arraydata['nbopenedday'])) {
2489 $return .= ' ('.$arraydata['nbopenedday'].')';
2490 }
2491 }
2492 if (method_exists($this, 'getLibStatut')) {
2493 $return .= '<div class="info-box-status">'.$this->getLibStatut(3).'</div>';
2494 }
2495 $return .= '</div>';
2496 $return .= '</div>';
2497 $return .= '</div>';
2498 return $return;
2499 }
2500}
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:447
$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.
load_state_board()
Load this->nb for dashboard.
const STATUS_DRAFT
Draft status.
createCPusers($single=false, $userid='')
Create entries for each user at setup step.
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.
updateSoldeCP($userID='', $nbHoliday='', $fk_type='')
Met à jour le timestamp de la dernière mise à jour du solde des CP.
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.
selectStatutCP($selected='', $htmlname='select_statut', $morecss='minwidth125')
Show select with list of leave status.
create($user, $notrigger=0)
Créer un congés payés dans la base de données.
countActiveUsersWithoutCP()
Compte le nombre d'utilisateur actifs dans Dolibarr sans 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 balance of holiday for one user.
fetch_users_approver_holiday()
Return list of people with permission to validate leave requests.
__construct($db)
Constructor.
getLibStatut($mode=0)
Returns the label status.
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.
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($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:62
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
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.
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 right right takeposterminal SELECT e e e e e statut
Definition invoice.php:1907