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