dolibarr 24.0.0-beta
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-2026 Frédéric France <frederic.france@free.fr>
8 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
9 * Copyright (C) 2026 Alexandre Spangaro <alexandre@inovea-conseil.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <https://www.gnu.org/licenses/>.
23 */
24
30require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
31
32
36class Holiday extends CommonObject
37{
41 public $element = 'holiday';
42
47 public $TRIGGER_PREFIX = 'HOLIDAY';
48
52 public $table_element = 'holiday';
53
57 public $fk_element = 'fk_holiday';
58
62 public $picto = 'holiday';
63
67 public $fk_user;
68
72 public $date_create = '';
73
77 public $description;
78
82 public $date_debut = '';
83
87 public $date_fin = '';
88
92 public $date_debut_gmt = '';
93
97 public $date_fin_gmt = '';
98
102 public $halfday = '';
103
108 public $statut = 0;
109
113 public $fk_validator;
114
118 public $date_valid = 0;
119
123 public $fk_user_valid;
124
128 public $date_approval;
129
133 public $fk_user_approve;
134
138 public $date_refuse = 0;
139
143 public $fk_user_refuse;
144
148 public $date_cancel = 0;
149
153 public $fk_user_cancel;
154
158 public $fk_user_create;
159
163 public $detail_refuse = '';
164
168 public $fk_type;
169
173 public $holiday = array();
174
175 public $events = array();
176
180 public $logs = array();
181
182
186 const STATUS_DRAFT = 1;
202 const STATUS_REFUSED = 5;
203
204
210 public function __construct($db)
211 {
212 $this->db = $db;
213
214 $this->ismultientitymanaged = 0;
215 }
216
217
225 public function getNextNumRef($objsoc)
226 {
227 global $langs, $conf;
228 $langs->load("order");
229
230 if (!getDolGlobalString('HOLIDAY_ADDON')) {
231 $conf->global->HOLIDAY_ADDON = 'mod_holiday_madonna';
232 }
233
234 if (getDolGlobalString('HOLIDAY_ADDON')) {
235 $mybool = false;
236
237 $file = getDolGlobalString('HOLIDAY_ADDON') . ".php";
238 $classname = getDolGlobalString('HOLIDAY_ADDON');
239
240 // Include file with class
241 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
242 foreach ($dirmodels as $reldir) {
243 $dir = dol_buildpath($reldir."core/modules/holiday/");
244
245 // Load file with numbering class (if found)
246 $mybool = ((bool) @include_once $dir.$file) || $mybool;
247 }
248
249 if (!$mybool) {
250 dol_print_error(null, "Failed to include file ".$file);
251 return '';
252 }
253
254 $obj = new $classname();
255 '@phan-var-force ModelNumRefHolidays $obj';
257 $numref = $obj->getNextValue($objsoc, $this);
258
259 if ($numref != "") {
260 return $numref;
261 } else {
262 $this->error = $obj->error;
263 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
264 return "";
265 }
266 } else {
267 print $langs->trans("Error")." ".$langs->trans("Error_HOLIDAY_ADDON_NotDefined");
268 return "";
269 }
270 }
271
277 public function updateBalance()
278 {
279 $this->db->begin();
280
281 // Update sold of vocations
282 $result = $this->updateSoldeCP();
283
284 // Check nb of users into table llx_holiday_users and update with empty lines
285 //if ($result > 0) $result = $this->verifNbUsers($this->countActiveUsersWithoutCP(), $this->getConfCP('nbUser'));
286
287 if ($result >= 0) {
288 $this->db->commit();
289 return 0; // for cronjob use (0 is OK, any other value is an error code)
290 } else {
291 $this->db->rollback();
292 return -1;
293 }
294 }
295
303 public function create($user, $notrigger = 0)
304 {
305 global $conf;
306 $error = 0;
307
308 $now = dol_now();
309
310 // Check parameters
311 if (empty($this->fk_user) || !is_numeric($this->fk_user) || $this->fk_user < 0) {
312 $this->error = "ErrorBadParameterFkUser";
313 return -1;
314 }
315 if (empty($this->fk_validator) || !is_numeric($this->fk_validator) || $this->fk_validator < 0) {
316 $this->error = "ErrorBadParameterFkValidator";
317 return -1;
318 }
319 if (empty($this->fk_type) || !is_numeric($this->fk_type) || $this->fk_type < 0) {
320 $this->error = "ErrorBadParameterFkType";
321 return -1;
322 }
323
324 // Insert request
325 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday(";
326 $sql .= "ref,";
327 $sql .= "fk_user,";
328 $sql .= "date_create,";
329 $sql .= "description,";
330 $sql .= "date_debut,";
331 $sql .= "date_fin,";
332 $sql .= "halfday,";
333 $sql .= "statut,";
334 $sql .= "fk_validator,";
335 $sql .= "fk_type,";
336 $sql .= "fk_user_create,";
337 $sql .= "entity";
338 $sql .= ") VALUES (";
339 $sql .= "'(PROV)',";
340 $sql .= " ".((int) $this->fk_user).",";
341 $sql .= " '".$this->db->idate($now)."',";
342 $sql .= " '".$this->db->escape($this->description)."',";
343 $sql .= " '".$this->db->idate($this->date_debut)."',";
344 $sql .= " '".$this->db->idate($this->date_fin)."',";
345 $sql .= " ".((int) $this->halfday).",";
346 $sql .= " '1',";
347 $sql .= " ".((int) $this->fk_validator).",";
348 $sql .= " ".((int) $this->fk_type).",";
349 $sql .= " ".((int) $user->id).",";
350 $sql .= " ".((int) $conf->entity);
351 $sql .= ")";
352
353 $this->db->begin();
354
355 dol_syslog(get_class($this)."::create", LOG_DEBUG);
356 $resql = $this->db->query($sql);
357 if (!$resql) {
358 $error++;
359 $this->errors[] = "Error ".$this->db->lasterror();
360 }
361
362 if (!$error) {
363 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."holiday");
364
365 if ($this->id) {
366 // update ref
367 $initialref = '(PROV'.$this->id.')';
368 if (!empty($this->ref)) {
369 $initialref = $this->ref;
370 }
371
372 $sql = 'UPDATE '.MAIN_DB_PREFIX."holiday SET ref='".$this->db->escape($initialref)."' WHERE rowid=".((int) $this->id);
373 if ($this->db->query($sql)) {
374 $this->ref = $initialref;
375 $result = $this->insertExtraFields();
376 if ($result < 0) {
377 $error++;
378 }
379
380 if (!$error && !$notrigger) {
381 // Call trigger
382 $result = $this->call_trigger('HOLIDAY_CREATE', $user);
383 if ($result < 0) {
384 $error++;
385 }
386 // End call triggers
387 }
388 }
389 }
390 }
391
392 // Commit or rollback
393 if ($error) {
394 foreach ($this->errors as $errmsg) {
395 dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR);
396 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
397 }
398 $this->db->rollback();
399 return -1 * $error;
400 } else {
401 $this->db->commit();
402 return $this->id;
403 }
404 }
405
406
414 public function fetch($id, $ref = '')
415 {
416 $sql = "SELECT";
417 $sql .= " cp.rowid,";
418 $sql .= " cp.ref,";
419 $sql .= " cp.fk_user,";
420 $sql .= " cp.date_create,";
421 $sql .= " cp.description,";
422 $sql .= " cp.date_debut,";
423 $sql .= " cp.date_fin,";
424 $sql .= " cp.halfday,";
425 $sql .= " cp.statut as status,";
426 $sql .= " cp.fk_validator,";
427 $sql .= " cp.date_valid,";
428 $sql .= " cp.fk_user_valid,";
429 $sql .= " cp.date_approval,";
430 $sql .= " cp.fk_user_approve,";
431 $sql .= " cp.date_refuse,";
432 $sql .= " cp.fk_user_refuse,";
433 $sql .= " cp.date_cancel,";
434 $sql .= " cp.fk_user_cancel,";
435 $sql .= " cp.detail_refuse,";
436 $sql .= " cp.note_private,";
437 $sql .= " cp.note_public,";
438 $sql .= " cp.fk_user_create,";
439 $sql .= " cp.fk_type,";
440 $sql .= " cp.entity";
441 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp";
442 if ($id > 0) {
443 $sql .= " WHERE cp.rowid = ".((int) $id);
444 } else {
445 $sql .= " WHERE cp.ref = '".$this->db->escape($ref)."'";
446 }
447
448 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
449 $resql = $this->db->query($sql);
450 if ($resql) {
451 if ($this->db->num_rows($resql)) {
452 $obj = $this->db->fetch_object($resql);
453
454 $this->id = (int) $obj->rowid;
455 $this->ref = (string) ($obj->ref ? $obj->ref : $obj->rowid);
456 $this->fk_user = (int) $obj->fk_user;
457 $this->date_create = $this->db->jdate($obj->date_create);
458 $this->description = $obj->description;
459 $this->date_debut = $this->db->jdate($obj->date_debut);
460 $this->date_fin = $this->db->jdate($obj->date_fin);
461 $this->date_debut_gmt = $this->db->jdate($obj->date_debut, 1);
462 $this->date_fin_gmt = $this->db->jdate($obj->date_fin, 1);
463 $this->halfday = (int) $obj->halfday;
464 $this->status = (int) $obj->status;
465 $this->statut = (int) $obj->status; // deprecated
466 $this->fk_validator = $obj->fk_validator;
467 $this->date_valid = $this->db->jdate($obj->date_valid);
468 $this->fk_user_valid = $obj->fk_user_valid;
469 $this->user_validation_id = $obj->fk_user_valid;
470 $this->date_approval = $this->db->jdate($obj->date_approval);
471 $this->fk_user_approve = $obj->fk_user_approve;
472 $this->date_refuse = $this->db->jdate($obj->date_refuse);
473 $this->fk_user_refuse = $obj->fk_user_refuse;
474 $this->date_cancel = $this->db->jdate($obj->date_cancel);
475 $this->fk_user_cancel = $obj->fk_user_cancel;
476 $this->detail_refuse = $obj->detail_refuse;
477 $this->note_private = $obj->note_private;
478 $this->note_public = $obj->note_public;
479 $this->fk_user_create = $obj->fk_user_create;
480 $this->fk_type = $obj->fk_type;
481 $this->entity = $obj->entity;
482
483 $this->fetch_optionals();
484
485 $result = 1;
486 } else {
487 $result = 0;
488 }
489 $this->db->free($resql);
490
491 return $result;
492 } else {
493 $this->error = "Error ".$this->db->lasterror();
494 return -1;
495 }
496 }
497
506 public function fetchByUser($user_id, $order = '', $filter = '')
507 {
508 $this->holiday = [];
509 $sql = "SELECT";
510 $sql .= " cp.rowid,";
511 $sql .= " cp.ref,";
512
513 $sql .= " cp.fk_user,";
514 $sql .= " cp.fk_type,";
515 $sql .= " cp.date_create,";
516 $sql .= " cp.tms as date_modification,";
517 $sql .= " cp.description,";
518 $sql .= " cp.date_debut,";
519 $sql .= " cp.date_fin,";
520 $sql .= " cp.halfday,";
521 $sql .= " cp.statut as status,";
522 $sql .= " cp.fk_validator,";
523 $sql .= " cp.date_valid,";
524 $sql .= " cp.fk_user_valid,";
525 $sql .= " cp.date_approval,";
526 $sql .= " cp.fk_user_approve,";
527 $sql .= " cp.date_refuse,";
528 $sql .= " cp.fk_user_refuse,";
529 $sql .= " cp.date_cancel,";
530 $sql .= " cp.fk_user_cancel,";
531 $sql .= " cp.detail_refuse,";
532
533 $sql .= " uu.lastname as user_lastname,";
534 $sql .= " uu.firstname as user_firstname,";
535 $sql .= " uu.login as user_login,";
536 $sql .= " uu.statut as user_status,";
537 $sql .= " uu.photo as user_photo,";
538
539 $sql .= " ua.lastname as validator_lastname,";
540 $sql .= " ua.firstname as validator_firstname,";
541 $sql .= " ua.login as validator_login,";
542 $sql .= " ua.statut as validator_status,";
543 $sql .= " ua.photo as validator_photo";
544
545 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp, ".MAIN_DB_PREFIX."user as uu, ".MAIN_DB_PREFIX."user as ua";
546 $sql .= " WHERE cp.entity IN (".getEntity('holiday').")";
547 $sql .= " AND cp.fk_user = uu.rowid AND cp.fk_validator = ua.rowid"; // Hack pour la recherche sur le tableau
548 $sql .= " AND cp.fk_user IN (".$this->db->sanitize($user_id).")";
549
550 // Selection filter
551 if (!empty($filter)) {
552 $sql .= $filter;
553 }
554
555 // Order of display of the result
556 if (!empty($order)) {
557 $sql .= $order;
558 }
559
560 dol_syslog(get_class($this)."::fetchByUser", LOG_DEBUG);
561 $resql = $this->db->query($sql);
562
563 // If no SQL error
564 if ($resql) {
565 $i = 0;
566 $tab_result = $this->holiday;
567 $num = $this->db->num_rows($resql);
568
569 // If no registration
570 if (!$num) {
571 return 2;
572 }
573
574 // List the records and add them to the table
575 while ($i < $num) {
576 $obj = $this->db->fetch_object($resql);
577
578 $tab_result[$i]['rowid'] = (int) $obj->rowid;
579 $tab_result[$i]['id'] = (int) $obj->rowid;
580 $tab_result[$i]['ref'] = (string) ($obj->ref ? $obj->ref : $obj->rowid);
581
582 $tab_result[$i]['fk_user'] = (int) $obj->fk_user;
583 $tab_result[$i]['fk_type'] = (int) $obj->fk_type;
584 $tab_result[$i]['date_create'] = $this->db->jdate($obj->date_create);
585 $tab_result[$i]['date_modification'] = $this->db->jdate($obj->date_modification);
586 $tab_result[$i]['description'] = (string) $obj->description;
587 $tab_result[$i]['date_debut'] = $this->db->jdate($obj->date_debut);
588 $tab_result[$i]['date_fin'] = $this->db->jdate($obj->date_fin);
589 $tab_result[$i]['date_debut_gmt'] = $this->db->jdate($obj->date_debut, 1);
590 $tab_result[$i]['date_fin_gmt'] = $this->db->jdate($obj->date_fin, 1);
591 $tab_result[$i]['halfday'] = (int) $obj->halfday;
592 $tab_result[$i]['statut'] = (int) $obj->status;
593 $tab_result[$i]['status'] = (int) $obj->status;
594 $tab_result[$i]['fk_validator'] = (int) $obj->fk_validator;
595 $tab_result[$i]['date_valid'] = $this->db->jdate($obj->date_valid);
596 $tab_result[$i]['fk_user_valid'] = (int) $obj->fk_user_valid;
597 $tab_result[$i]['date_approval'] = $this->db->jdate($obj->date_approval);
598 $tab_result[$i]['fk_user_approve'] = (int) $obj->fk_user_approve;
599 $tab_result[$i]['date_refuse'] = $this->db->jdate($obj->date_refuse);
600 $tab_result[$i]['fk_user_refuse'] = (int) $obj->fk_user_refuse;
601 $tab_result[$i]['date_cancel'] = $this->db->jdate($obj->date_cancel);
602 $tab_result[$i]['fk_user_cancel'] = (int) $obj->fk_user_cancel;
603 $tab_result[$i]['detail_refuse'] = (string) $obj->detail_refuse;
604
605 $tab_result[$i]['user_firstname'] = (string) $obj->user_firstname;
606 $tab_result[$i]['user_lastname'] = (string) $obj->user_lastname;
607 $tab_result[$i]['user_login'] = (string) $obj->user_login;
608 $tab_result[$i]['user_statut'] = (int) $obj->user_status;
609 $tab_result[$i]['user_status'] = (int) $obj->user_status;
610 $tab_result[$i]['user_photo'] = (string) $obj->user_photo;
611
612 $tab_result[$i]['validator_firstname'] = (string) $obj->validator_firstname;
613 $tab_result[$i]['validator_lastname'] = (string) $obj->validator_lastname;
614 $tab_result[$i]['validator_login'] = (string) $obj->validator_login;
615 $tab_result[$i]['validator_statut'] = (int) $obj->validator_status;
616 $tab_result[$i]['validator_status'] = (int) $obj->validator_status;
617 $tab_result[$i]['validator_photo'] = (string) $obj->validator_photo;
618
619 $i++;
620 }
621
622 // Returns 1 with the filled array
623 $this->holiday = $tab_result;
624 return 1;
625 } else {
626 // SQL Error
627 $this->error = "Error ".$this->db->lasterror();
628 return -1;
629 }
630 }
631
639 public function fetchAll($order, $filter)
640 {
641 $sql = "SELECT";
642 $sql .= " cp.rowid,";
643 $sql .= " cp.ref,";
644 $sql .= " cp.fk_user,";
645 $sql .= " cp.fk_type,";
646 $sql .= " cp.date_create,";
647 $sql .= " cp.tms as date_modification,";
648 $sql .= " cp.description,";
649 $sql .= " cp.date_debut,";
650 $sql .= " cp.date_fin,";
651 $sql .= " cp.halfday,";
652 $sql .= " cp.statut as status,";
653 $sql .= " cp.fk_validator,";
654 $sql .= " cp.date_valid,";
655 $sql .= " cp.fk_user_valid,";
656 $sql .= " cp.date_approval,";
657 $sql .= " cp.fk_user_approve,";
658 $sql .= " cp.date_refuse,";
659 $sql .= " cp.fk_user_refuse,";
660 $sql .= " cp.date_cancel,";
661 $sql .= " cp.fk_user_cancel,";
662 $sql .= " cp.detail_refuse,";
663
664 $sql .= " uu.lastname as user_lastname,";
665 $sql .= " uu.firstname as user_firstname,";
666 $sql .= " uu.login as user_login,";
667 $sql .= " uu.statut as user_status,";
668 $sql .= " uu.photo as user_photo,";
669
670 $sql .= " ua.lastname as validator_lastname,";
671 $sql .= " ua.firstname as validator_firstname,";
672 $sql .= " ua.login as validator_login,";
673 $sql .= " ua.statut as validator_status,";
674 $sql .= " ua.photo as validator_photo";
675
676 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp, ".MAIN_DB_PREFIX."user as uu, ".MAIN_DB_PREFIX."user as ua";
677 $sql .= " WHERE cp.entity IN (".getEntity('holiday').")";
678 $sql .= " AND cp.fk_user = uu.rowid AND cp.fk_validator = ua.rowid "; // Hack pour la recherche sur le tableau
679
680 // Selection filtering
681 if (!empty($filter)) {
682 $sql .= $filter;
683 }
684
685 // order of display
686 if (!empty($order)) {
687 $sql .= $order;
688 }
689
690 dol_syslog(get_class($this)."::fetchAll", LOG_DEBUG);
691 $resql = $this->db->query($sql);
692
693 // If no SQL error
694 if ($resql) {
695 $i = 0;
696 $tab_result = $this->holiday;
697 $num = $this->db->num_rows($resql);
698
699 // If no registration
700 if (!$num) {
701 return 2;
702 }
703
704 // List the records and add them to the table
705 while ($i < $num) {
706 $obj = $this->db->fetch_object($resql);
707
708 $tab_result[$i]['rowid'] = (int) $obj->rowid;
709 $tab_result[$i]['id'] = (int) $obj->rowid;
710 $tab_result[$i]['ref'] = (string) ($obj->ref ? $obj->ref : $obj->rowid);
711
712 $tab_result[$i]['fk_user'] = (int) $obj->fk_user;
713 $tab_result[$i]['fk_type'] = (int) $obj->fk_type;
714 $tab_result[$i]['date_create'] = $this->db->jdate($obj->date_create);
715 $tab_result[$i]['date_modification'] = $this->db->jdate($obj->date_modification);
716 $tab_result[$i]['description'] = (string) $obj->description;
717 $tab_result[$i]['date_debut'] = $this->db->jdate($obj->date_debut);
718 $tab_result[$i]['date_fin'] = $this->db->jdate($obj->date_fin);
719 $tab_result[$i]['date_debut_gmt'] = $this->db->jdate($obj->date_debut, 1);
720 $tab_result[$i]['date_fin_gmt'] = $this->db->jdate($obj->date_fin, 1);
721 $tab_result[$i]['halfday'] = (int) $obj->halfday;
722 $tab_result[$i]['statut'] = (int) $obj->status;
723 $tab_result[$i]['status'] = (int) $obj->status;
724 $tab_result[$i]['fk_validator'] = (int) $obj->fk_validator;
725 $tab_result[$i]['date_valid'] = $this->db->jdate($obj->date_valid);
726 $tab_result[$i]['fk_user_valid'] = (int) $obj->fk_user_valid;
727 $tab_result[$i]['date_approval'] = $this->db->jdate($obj->date_approval);
728 $tab_result[$i]['fk_user_approve'] = (int) $obj->fk_user_approve;
729 $tab_result[$i]['date_refuse'] = $this->db->jdate($obj->date_refuse);
730 $tab_result[$i]['fk_user_refuse'] = (int) $obj->fk_user_refuse;
731 $tab_result[$i]['date_cancel'] = $this->db->jdate($obj->date_cancel);
732 $tab_result[$i]['fk_user_cancel'] = (int) $obj->fk_user_cancel;
733 $tab_result[$i]['detail_refuse'] = (string) $obj->detail_refuse;
734
735 $tab_result[$i]['user_firstname'] = (string) $obj->user_firstname;
736 $tab_result[$i]['user_lastname'] = (string) $obj->user_lastname;
737 $tab_result[$i]['user_login'] = (string) $obj->user_login;
738 $tab_result[$i]['user_statut'] = (int) $obj->user_status;
739 $tab_result[$i]['user_status'] = (int) $obj->user_status;
740 $tab_result[$i]['user_photo'] = (string) $obj->user_photo;
741
742 $tab_result[$i]['validator_firstname'] = (string) $obj->validator_firstname;
743 $tab_result[$i]['validator_lastname'] = (string) $obj->validator_lastname;
744 $tab_result[$i]['validator_login'] = (string) $obj->validator_login;
745 $tab_result[$i]['validator_statut'] = (int) $obj->validator_status;
746 $tab_result[$i]['validator_status'] = (int) $obj->validator_status;
747 $tab_result[$i]['validator_photo'] = (string) $obj->validator_photo;
748
749 $i++;
750 }
751 // Returns 1 and adds the array to the variable
752 $this->holiday = $tab_result;
753 return 1;
754 } else {
755 // SQL Error
756 $this->error = "Error ".$this->db->lasterror();
757 return -1;
758 }
759 }
760
761
769 public function validate($user = null, $notrigger = 0)
770 {
771 global $conf, $langs;
772 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
773 $error = 0;
774
775
776 $checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type, true);
777
778 if ($checkBalance > 0) {
779 $balance = $this->getCPforUser($this->fk_user, $this->fk_type);
780 $daysAsked = num_open_day($this->date_debut, $this->date_fin, 0, 1, 0, '', $this->fk_user);
781
782 if (($balance - $daysAsked) < 0 && getDolGlobalString('HOLIDAY_DISALLOW_NEGATIVE_BALANCE')) {
783 $this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
784 return -1;
785 }
786 }
787
788 // Define new ref
789 if (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref) || $this->ref == $this->id) {
790 $num = $this->getNextNumRef(null);
791 } else {
792 $num = (string) $this->ref;
793 }
794 $this->newref = dol_sanitizeFileName($num);
795
796 // Update status
797 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
798 $sql .= " fk_user_valid = ".((int) $user->id).",";
799 $sql .= " date_valid = '".$this->db->idate(dol_now())."',";
800 if (!empty($this->status) && is_numeric($this->status)) {
801 $sql .= " statut = ".((int) $this->status).",";
802 } else {
803 $this->error = 'Property status must be a numeric value';
804 $error++;
805 }
806 $sql .= " ref = '".$this->db->escape($num)."'";
807 $sql .= " WHERE rowid = ".((int) $this->id);
808
809 $this->db->begin();
810
811 dol_syslog(get_class($this)."::validate", LOG_DEBUG);
812 $resql = $this->db->query($sql);
813 if (!$resql) {
814 $error++;
815 $this->errors[] = "Error ".$this->db->lasterror();
816 }
817
818 if (!$error) {
819 if (!$notrigger) {
820 // Call trigger
821 $result = $this->call_trigger('HOLIDAY_VALIDATE', $user);
822 if ($result < 0) {
823 $error++;
824 }
825 // End call triggers
826 }
827 }
828
829 if (!$error) {
830 $this->oldref = $this->ref;
831
832 // Rename directory if dir was a temporary ref
833 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
834 // Now we rename also files into index
835 $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) . "'";
836 $sql .= " WHERE filename LIKE '" . $this->db->escape($this->ref) . "%' AND filepath = 'holiday/" . $this->db->escape($this->ref) . "' and entity = " . ((int) $conf->entity);
837 $resql = $this->db->query($sql);
838 if (!$resql) {
839 $error++;
840 $this->error = $this->db->lasterror();
841 }
842 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'holiday/".$this->db->escape($this->newref)."'";
843 $sql .= " WHERE filepath = 'holiday/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
844 $resql = $this->db->query($sql);
845 if (!$resql) {
846 $error++;
847 $this->error = $this->db->lasterror();
848 }
849
850 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
851 $oldref = dol_sanitizeFileName($this->ref);
852 $newref = dol_sanitizeFileName($num);
853 $dirsource = $conf->holiday->multidir_output[$this->entity] . '/' . $oldref;
854 $dirdest = $conf->holiday->multidir_output[$this->entity] . '/' . $newref;
855 if (!$error && file_exists($dirsource)) {
856 dol_syslog(get_class($this) . "::validate rename dir " . $dirsource . " into " . $dirdest);
857 if (@rename($dirsource, $dirdest)) {
858 dol_syslog("Rename ok");
859 // Rename docs starting with $oldref with $newref
860 $listoffiles = dol_dir_list($dirdest, 'files', 1, '^' . preg_quote($oldref, '/'));
861 foreach ($listoffiles as $fileentry) {
862 $dirsource = $fileentry['name'];
863 $dirdest = preg_replace('/^' . preg_quote($oldref, '/') . '/', $newref, $dirsource);
864 $dirsource = $fileentry['path'] . '/' . $dirsource;
865 $dirdest = $fileentry['path'] . '/' . $dirdest;
866 @rename($dirsource, $dirdest);
867 }
868 }
869 }
870 }
871 }
872
873
874 // Commit or rollback
875 if ($error) {
876 foreach ($this->errors as $errmsg) {
877 dol_syslog(get_class($this)."::validate ".$errmsg, LOG_ERR);
878 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
879 }
880 $this->db->rollback();
881 return -1 * $error;
882 } else {
883 $this->db->commit();
884 return 1;
885 }
886 }
887
888
896 public function approve($user = null, $notrigger = 0)
897 {
898 $error = 0;
899
900 $checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type, true);
901
902 if ($checkBalance > 0) {
903 $balance = $this->getCPforUser($this->fk_user, $this->fk_type);
904 $daysAsked = num_open_day($this->date_debut, $this->date_fin, 0, 1, 0, '', $this->fk_user);
905
906 if (($balance - $daysAsked) < 0 && getDolGlobalString('HOLIDAY_DISALLOW_NEGATIVE_BALANCE')) {
907 $this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
908 return -1;
909 }
910 }
911
912 // Update request
913 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
914 $sql .= " description= '".$this->db->escape($this->description)."',";
915 if (!empty($this->date_debut)) {
916 $sql .= " date_debut = '".$this->db->idate($this->date_debut)."',";
917 } else {
918 $error++;
919 }
920 if (!empty($this->date_fin)) {
921 $sql .= " date_fin = '".$this->db->idate($this->date_fin)."',";
922 } else {
923 $error++;
924 }
925 $sql .= " halfday = ".((int) $this->halfday).",";
926 if (!empty($this->status) && is_numeric($this->status)) {
927 $sql .= " statut = ".((int) $this->status).",";
928 } else {
929 $error++;
930 }
931 if (!empty($this->fk_validator)) {
932 $sql .= " fk_validator = ".((int) $this->fk_validator).",";
933 } else {
934 $error++;
935 }
936 if (!empty($this->date_valid)) {
937 $sql .= " date_valid = '".$this->db->idate($this->date_valid)."',";
938 } else {
939 $sql .= " date_valid = NULL,";
940 }
941 if (!empty($this->fk_user_valid)) {
942 $sql .= " fk_user_valid = ".((int) $this->fk_user_valid).",";
943 } else {
944 $sql .= " fk_user_valid = NULL,";
945 }
946 if (!empty($this->date_approval)) {
947 $sql .= " date_approval = '".$this->db->idate($this->date_approval)."',";
948 } else {
949 $sql .= " date_approval = NULL,";
950 }
951 if (!empty($this->fk_user_approve)) {
952 $sql .= " fk_user_approve = ".((int) $this->fk_user_approve).",";
953 } else {
954 $sql .= " fk_user_approve = NULL,";
955 }
956 if (!empty($this->date_refuse)) {
957 $sql .= " date_refuse = '".$this->db->idate($this->date_refuse)."',";
958 } else {
959 $sql .= " date_refuse = NULL,";
960 }
961 if (!empty($this->fk_user_refuse)) {
962 $sql .= " fk_user_refuse = ".((int) $this->fk_user_refuse).",";
963 } else {
964 $sql .= " fk_user_refuse = NULL,";
965 }
966 if (!empty($this->date_cancel)) {
967 $sql .= " date_cancel = '".$this->db->idate($this->date_cancel)."',";
968 } else {
969 $sql .= " date_cancel = NULL,";
970 }
971 if (!empty($this->fk_user_cancel)) {
972 $sql .= " fk_user_cancel = ".((int) $this->fk_user_cancel).",";
973 } else {
974 $sql .= " fk_user_cancel = NULL,";
975 }
976 if (!empty($this->detail_refuse)) {
977 $sql .= " detail_refuse = '".$this->db->escape($this->detail_refuse)."'";
978 } else {
979 $sql .= " detail_refuse = NULL";
980 }
981 $sql .= " WHERE rowid = ".((int) $this->id);
982
983 $this->db->begin();
984
985 dol_syslog(get_class($this)."::approve", LOG_DEBUG);
986 $resql = $this->db->query($sql);
987 if (!$resql) {
988 $error++;
989 $this->errors[] = "Error ".$this->db->lasterror();
990 }
991
992 if (!$error) {
993 if (!$notrigger) {
994 // Call trigger
995 $result = $this->call_trigger('HOLIDAY_APPROVE', $user);
996 if ($result < 0) {
997 $error++;
998 }
999 // End call triggers
1000 }
1001 }
1002
1003 // Commit or rollback
1004 if ($error) {
1005 foreach ($this->errors as $errmsg) {
1006 dol_syslog(get_class($this)."::approve ".$errmsg, LOG_ERR);
1007 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1008 }
1009 $this->db->rollback();
1010 return -1 * $error;
1011 } else {
1012 $this->db->commit();
1013 return 1;
1014 }
1015 }
1016
1024 public function update($user = null, $notrigger = 0)
1025 {
1026 $error = 0;
1027
1028 $checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type, true);
1029
1030 if ($checkBalance > 0 && $this->status != self::STATUS_DRAFT && $this->status != self::STATUS_CANCELED) {
1031 $balance = $this->getCPforUser($this->fk_user, $this->fk_type);
1032 $daysAsked = num_open_day($this->date_debut, $this->date_fin, 0, 1, 0, '', $this->fk_user);
1033
1034 if (($balance - $daysAsked) < 0 && getDolGlobalString('HOLIDAY_DISALLOW_NEGATIVE_BALANCE')) {
1035 $this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
1036 return -1;
1037 }
1038 }
1039
1040 // Update request
1041 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
1042
1043 $sql .= " description= '".$this->db->escape($this->description)."',";
1044
1045 if (!empty($this->date_create)) {
1046 $sql .= " date_create = '".$this->db->idate($this->date_create)."',";
1047 } else {
1048 $error++;
1049 }
1050 if (!empty($this->date_debut)) {
1051 $sql .= " date_debut = '".$this->db->idate($this->date_debut)."',";
1052 } else {
1053 $error++;
1054 }
1055 if (!empty($this->date_fin)) {
1056 $sql .= " date_fin = '".$this->db->idate($this->date_fin)."',";
1057 } else {
1058 $error++;
1059 }
1060 $sql .= " halfday = ".((int) $this->halfday).",";
1061 if (!empty($this->status) && is_numeric($this->status)) {
1062 $sql .= " statut = ".((int) $this->status).",";
1063 } else {
1064 $error++;
1065 }
1066 if (!empty($this->fk_validator)) {
1067 $sql .= " fk_validator = ".((int) $this->fk_validator).",";
1068 } else {
1069 $error++;
1070 }
1071 if (!empty($this->date_valid)) {
1072 $sql .= " date_valid = '".$this->db->idate($this->date_valid)."',";
1073 } else {
1074 $sql .= " date_valid = NULL,";
1075 }
1076 if (!empty($this->fk_user_valid)) {
1077 $sql .= " fk_user_valid = ".((int) $this->fk_user_valid).",";
1078 } else {
1079 $sql .= " fk_user_valid = NULL,";
1080 }
1081 if (!empty($this->date_approval)) {
1082 $sql .= " date_approval = '".$this->db->idate($this->date_approval)."',";
1083 } else {
1084 $sql .= " date_approval = NULL,";
1085 }
1086 if (!empty($this->fk_user_approve)) {
1087 $sql .= " fk_user_approve = ".((int) $this->fk_user_approve).",";
1088 } else {
1089 $sql .= " fk_user_approve = NULL,";
1090 }
1091 if (!empty($this->date_refuse)) {
1092 $sql .= " date_refuse = '".$this->db->idate($this->date_refuse)."',";
1093 } else {
1094 $sql .= " date_refuse = NULL,";
1095 }
1096 if (!empty($this->fk_user_refuse)) {
1097 $sql .= " fk_user_refuse = ".((int) $this->fk_user_refuse).",";
1098 } else {
1099 $sql .= " fk_user_refuse = NULL,";
1100 }
1101 if (!empty($this->date_cancel)) {
1102 $sql .= " date_cancel = '".$this->db->idate($this->date_cancel)."',";
1103 } else {
1104 $sql .= " date_cancel = NULL,";
1105 }
1106 if (!empty($this->fk_user_cancel)) {
1107 $sql .= " fk_user_cancel = ".((int) $this->fk_user_cancel).",";
1108 } else {
1109 $sql .= " fk_user_cancel = NULL,";
1110 }
1111 if (!empty($this->detail_refuse)) {
1112 $sql .= " detail_refuse = '".$this->db->escape($this->detail_refuse)."'";
1113 } else {
1114 $sql .= " detail_refuse = NULL";
1115 }
1116
1117 $sql .= " WHERE rowid = ".((int) $this->id);
1118
1119 $this->db->begin();
1120
1121 dol_syslog(get_class($this)."::update", LOG_DEBUG);
1122 $resql = $this->db->query($sql);
1123 if (!$resql) {
1124 $error++;
1125 $this->errors[] = "Error ".$this->db->lasterror();
1126 }
1127
1128 if (!$error) {
1129 $result = $this->insertExtraFields();
1130 if ($result < 0) {
1131 $error++;
1132 }
1133 }
1134
1135 if (!$error) {
1136 if (!$notrigger && $user !== null) {
1137 // Call trigger
1138 $result = $this->call_trigger('HOLIDAY_MODIFY', $user);
1139 if ($result < 0) {
1140 $error++;
1141 }
1142 // End call triggers
1143 }
1144 }
1145
1146 // Commit or rollback
1147 if ($error) {
1148 foreach ($this->errors as $errmsg) {
1149 dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
1150 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1151 }
1152 $this->db->rollback();
1153 return -1 * $error;
1154 } else {
1155 $this->db->commit();
1156 return 1;
1157 }
1158 }
1159
1160
1168 public function delete($user, $notrigger = 0)
1169 {
1170 global $conf, $langs;
1171 $error = 0;
1172
1173 $sql = "DELETE FROM ".MAIN_DB_PREFIX."holiday";
1174 $sql .= " WHERE rowid=".((int) $this->id);
1175
1176 $this->db->begin();
1177
1178 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1179 $resql = $this->db->query($sql);
1180 if (!$resql) {
1181 $error++;
1182 $this->errors[] = "Error ".$this->db->lasterror();
1183 }
1184
1185 if (!$error) {
1186 if (!$notrigger) {
1187 // Call trigger
1188 $result = $this->call_trigger('HOLIDAY_DELETE', $user);
1189 if ($result < 0) {
1190 $error++;
1191 }
1192 // End call triggers
1193 }
1194 }
1195
1196 // Commit or rollback
1197 if ($error) {
1198 foreach ($this->errors as $errmsg) {
1199 dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
1200 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1201 }
1202 $this->db->rollback();
1203 return -1 * $error;
1204 } else {
1205 $this->db->commit();
1206 return 1;
1207 }
1208 }
1209
1223 public function verifDateHolidayCP($fk_user, $dateStart, $dateEnd, $halfday = 0)
1224 {
1225 $this->fetchByUser($fk_user, '', '');
1226
1227 foreach ($this->holiday as $infos_CP) {
1228 if ($infos_CP['statut'] == Holiday::STATUS_CANCELED) {
1229 continue; // ignore not validated holidays
1230 }
1231 if ($infos_CP['statut'] == Holiday::STATUS_REFUSED) {
1232 continue; // ignore refused holidays
1233 }
1234 //var_dump("--");
1235 //var_dump("old: ".dol_print_date($infos_CP['date_debut'],'dayhour').' '.dol_print_date($infos_CP['date_fin'],'dayhour').' '.$infos_CP['halfday']);
1236 //var_dump("new: ".dol_print_date($dateStart,'dayhour').' '.dol_print_date($dateEnd,'dayhour').' '.$halfday);
1237
1238 if ($halfday == 0) {
1239 if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1240 return false;
1241 }
1242 if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1243 return false;
1244 }
1245 } elseif ($halfday == -1) {
1246 // new start afternoon, new end afternoon
1247 if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1248 if ($dateStart < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
1249 return false;
1250 }
1251 }
1252 if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1253 if ($dateStart < $dateEnd) {
1254 return false;
1255 }
1256 if ($dateEnd < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
1257 return false;
1258 }
1259 }
1260 } elseif ($halfday == 1) {
1261 // new start morning, new end morning
1262 if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1263 if ($dateStart < $dateEnd) {
1264 return false;
1265 }
1266 if ($dateStart > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
1267 return false;
1268 }
1269 }
1270 if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1271 if ($dateEnd > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
1272 return false;
1273 }
1274 }
1275 } elseif ($halfday == 2) {
1276 // new start afternoon, new end morning
1277 if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1278 if ($dateStart < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
1279 return false;
1280 }
1281 }
1282 if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1283 if ($dateEnd > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
1284 return false;
1285 }
1286 }
1287 } else {
1288 dol_print_error(null, 'Bad value of parameter halfday when calling function verifDateHolidayCP');
1289 }
1290 }
1291
1292 return true;
1293 }
1294
1295
1305 public function verifDateHolidayForTimestamp($fk_user, $timestamp, $status = '-1')
1306 {
1307 $isavailablemorning = true;
1308 $isavailableafternoon = true;
1309
1310 // Check into leave requests
1311 $sql = "SELECT cp.rowid, cp.date_debut as date_start, cp.date_fin as date_end, cp.halfday, cp.statut as status";
1312 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp";
1313 $sql .= " WHERE cp.entity IN (".getEntity('holiday').")";
1314 $sql .= " AND cp.fk_user = ".(int) $fk_user;
1315 $sql .= " AND cp.date_debut <= '".$this->db->idate($timestamp)."' AND cp.date_fin >= '".$this->db->idate($timestamp)."'";
1316 if ($status != '-1') {
1317 $sql .= " AND cp.statut IN (".$this->db->sanitize($status).")";
1318 }
1319
1320 $resql = $this->db->query($sql);
1321 if ($resql) {
1322 $num_rows = $this->db->num_rows($resql); // Note, we can have 2 records if on is morning and the other one is afternoon
1323 if ($num_rows > 0) {
1324 $arrayofrecord = array();
1325 $i = 0;
1326 while ($i < $num_rows) {
1327 $obj = $this->db->fetch_object($resql);
1328
1329 // Note: $obj->halfday is 0:Full days, 2:Start afternoon end morning, -1:Start afternoon, 1:End morning
1330 $arrayofrecord[$obj->rowid] = array('date_start' => $this->db->jdate($obj->date_start), 'date_end' => $this->db->jdate($obj->date_end), 'halfday' => $obj->halfday, 'status' => $obj->status);
1331 $i++;
1332 }
1333
1334 // We found a record, user is on holiday by default, so is not available is true.
1335 $isavailablemorning = true;
1336 foreach ($arrayofrecord as $record) {
1337 if ($timestamp == $record['date_start'] && $record['halfday'] == 2) {
1338 continue;
1339 }
1340 if ($timestamp == $record['date_start'] && $record['halfday'] == -1) {
1341 continue;
1342 }
1343 $isavailablemorning = false;
1344 break;
1345 }
1346 $isavailableafternoon = true;
1347 foreach ($arrayofrecord as $record) {
1348 if ($timestamp == $record['date_end'] && $record['halfday'] == 2) {
1349 continue;
1350 }
1351 if ($timestamp == $record['date_end'] && $record['halfday'] == 1) {
1352 continue;
1353 }
1354 $isavailableafternoon = false;
1355 break;
1356 }
1357 }
1358 } else {
1359 dol_print_error($this->db);
1360 }
1361
1362 $result = array('morning' => (int) $isavailablemorning, 'afternoon' => (int) $isavailableafternoon);
1363 if (!$isavailablemorning) {
1364 $result['morning_reason'] = 'leave_request';
1365 }
1366 if (!$isavailableafternoon) {
1367 $result['afternoon_reason'] = 'leave_request';
1368 }
1369 return $result;
1370 }
1371
1378 public function getTooltipContentArray($params)
1379 {
1380 global $langs;
1381
1382 $langs->load('holiday');
1383 $nofetch = !empty($params['nofetch']);
1384
1385 $datas = array();
1386 $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Holiday").'</u>';
1387 if (isset($this->status)) {
1388 $datas['picto'] .= ' '.$this->getLibStatut(5);
1389 }
1390 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
1391 // show type for this record only in ajax to not overload lists
1392 if (!$nofetch && !empty($this->fk_type)) {
1393 $typeleaves = $this->getTypes(1, -1);
1394 if (empty($typeleaves[$this->fk_type])) {
1395 $labeltoshow = $langs->trans("TypeWasDisabledOrRemoved", $this->fk_type);
1396 } else {
1397 $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']);
1398 }
1399 $datas['type'] = '<br><b>'.$langs->trans("Type") . ':</b> ' . $labeltoshow;
1400 }
1401 if (isset($this->halfday) && !empty($this->date_debut) && !empty($this->date_fin)) {
1402 $listhalfday = array(
1403 'morning' => $langs->trans("Morning"),
1404 "afternoon" => $langs->trans("Afternoon")
1405 );
1406 $starthalfday = ($this->halfday == -1 || $this->halfday == 2) ? 'afternoon' : 'morning';
1407 $endhalfday = ($this->halfday == 1 || $this->halfday == 2) ? 'morning' : 'afternoon';
1408 $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>';
1409 $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>';
1410 }
1411
1412
1413 return $datas;
1414 }
1415
1425 public function getNomUrl($withpicto = 0, $save_lastsearch_value = -1, $notooltip = 0, $morecss = '')
1426 {
1427 global $conf, $langs, $hookmanager;
1428
1429 if (!empty($conf->dol_no_mouse_hover)) {
1430 $notooltip = 1; // Force disable tooltips
1431 }
1432
1433 $result = '';
1434 $params = [
1435 'id' => $this->id,
1436 'objecttype' => $this->element,
1437 'nofetch' => 1,
1438 ];
1439 $classfortooltip = 'classfortooltip';
1440 $dataparams = '';
1441 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1442 $classfortooltip = 'classforajaxtooltip';
1443 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1444 $label = '';
1445 } else {
1446 $label = implode($this->getTooltipContentArray($params));
1447 }
1448
1449 $url = DOL_URL_ROOT.'/holiday/card.php?id='.$this->id;
1450
1451 //if ($option != 'nolink')
1452 //{
1453 // Add param to save lastsearch_values or not
1454 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1455 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1456 $add_save_lastsearch_values = 1;
1457 }
1458 if ($add_save_lastsearch_values) {
1459 $url .= '&save_lastsearch_values=1';
1460 }
1461 //}
1462
1463 $linkclose = '';
1464 if (empty($notooltip)) {
1465 if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1466 $label = $langs->trans("ShowMyObject");
1467 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
1468 }
1469 $linkclose .= ($label ? ' title="'.dolPrintHTMLForAttribute($label).'"' : ' title="tocomplete"');
1470 $linkclose .= $dataparams.' class="'.$classfortooltip.($morecss ? ' '.$morecss : '').'"';
1471 } else {
1472 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
1473 }
1474
1475 $linkstart = '<a href="'.$url.'"';
1476 $linkstart .= $linkclose.'>';
1477 $linkend = '</a>';
1478
1479 $result .= $linkstart;
1480
1481 if ($withpicto) {
1482 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
1483 }
1484 if ($withpicto != 2) {
1485 $result .= $this->ref;
1486 }
1487 $result .= $linkend;
1488
1489 global $action;
1490 $hookmanager->initHooks(array($this->element . 'dao'));
1491 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1492 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1493 if ($reshook > 0) {
1494 $result = $hookmanager->resPrint;
1495 } else {
1496 $result .= $hookmanager->resPrint;
1497 }
1498 return $result;
1499 }
1500
1501
1508 public function getLibStatut($mode = 0)
1509 {
1510 return $this->LibStatut($this->status, $mode, $this->date_debut);
1511 }
1512
1513 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1522 public function LibStatut($status, $mode = 0, $startdate = '')
1523 {
1524 // phpcs:enable
1525 global $langs;
1526
1527 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
1528 global $langs;
1529 //$langs->load("mymodule");
1530 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP');
1531 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP');
1532 $this->labelStatus[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP');
1533 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP');
1534 $this->labelStatus[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP');
1535 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP');
1536 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP');
1537 $this->labelStatusShort[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP');
1538 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP');
1539 $this->labelStatusShort[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP');
1540 }
1541
1542 $params = array();
1543 $statusType = 'status6';
1544 if (!empty($startdate) && $startdate >= dol_now()) { // If not yet passed, we use a green "in live" color
1545 $statusType = 'status4';
1546 $params = array('tooltip' => $this->labelStatus[$status].' - '.$langs->trans("Forthcoming"));
1547 }
1548 if ($status == self::STATUS_DRAFT) {
1549 $statusType = 'status0';
1550 }
1551 if ($status == self::STATUS_VALIDATED) {
1552 $statusType = 'status1';
1553 }
1554 if ($status == self::STATUS_CANCELED) {
1555 $statusType = 'status9';
1556 }
1557 if ($status == self::STATUS_REFUSED) {
1558 $statusType = 'status9';
1559 }
1560
1561 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode, '', $params);
1562 }
1563
1564
1573 public function selectStatutCP($selected = 0, $htmlname = 'select_statut', $morecss = 'minwidth125')
1574 {
1575 global $langs;
1576
1577 // List of status label
1578 $name = array('DraftCP', 'ToReviewCP', 'ApprovedCP', 'CancelCP', 'RefuseCP');
1579 $nb = count($name) + 1;
1580
1581 // Select HTML
1582 $out = '<select name="'.$htmlname.'" id="'.$htmlname.'" class="flat'.($morecss ? ' '.$morecss : '').'">'."\n";
1583 $out .= '<option value="-1">&nbsp;</option>'."\n";
1584
1585 // Loop on status
1586 for ($i = 1; $i < $nb; $i++) {
1587 if ($i == $selected) {
1588 $out .= '<option value="'.$i.'" selected>'.$langs->trans($name[$i - 1]).'</option>'."\n";
1589 } else {
1590 $out .= '<option value="'.$i.'">'.$langs->trans($name[$i - 1]).'</option>'."\n";
1591 }
1592 }
1593
1594 $out .= "</select>\n";
1595
1596 $showempty = 0;
1597 $out .= ajax_combobox($htmlname, array(), 0, 0, 'resolve', ($showempty < 0 ? (string) $showempty : '-1'), $morecss);
1598
1599 return $out;
1600 }
1601
1609 public function updateConfCP($name, $value)
1610 {
1611 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
1612 $sql .= " value = '".$this->db->escape($value)."'";
1613 $sql .= " WHERE name = '".$this->db->escape($name)."'";
1614
1615 dol_syslog(get_class($this).'::updateConfCP name='.$name, LOG_DEBUG);
1616 $result = $this->db->query($sql);
1617 if ($result) {
1618 return true;
1619 }
1620
1621 return false;
1622 }
1623
1632 public function getConfCP($name, $createifnotfound = '')
1633 {
1634 $sql = "SELECT value";
1635 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_config";
1636 $sql .= " WHERE name = '".$this->db->escape($name)."'";
1637
1638 dol_syslog(get_class($this).'::getConfCP name='.$name.' createifnotfound='.$createifnotfound, LOG_DEBUG);
1639 $result = $this->db->query($sql);
1640
1641 if ($result) {
1642 $obj = $this->db->fetch_object($result);
1643 // Return value
1644 if (empty($obj)) {
1645 if ($createifnotfound) {
1646 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_config(name, value)";
1647 $sql .= " VALUES('".$this->db->escape($name)."', '".$this->db->escape($createifnotfound)."')";
1648 $result = $this->db->query($sql);
1649 if ($result) {
1650 return $createifnotfound;
1651 } else {
1652 $this->error = $this->db->lasterror();
1653 return -2;
1654 }
1655 } else {
1656 return '';
1657 }
1658 } else {
1659 return $obj->value;
1660 }
1661 } else {
1662 // Erreur SQL
1663 $this->error = $this->db->lasterror();
1664 return -1;
1665 }
1666 }
1667
1676 public function updateSoldeCP($userID = 0, $nbHoliday = 0, $fk_type = 0)
1677 {
1678 global $user, $langs;
1679
1680 $error = 0;
1681
1682 if (empty($userID) && empty($nbHoliday) && empty($fk_type)) {
1683 include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
1684 $langs->load("holiday");
1685
1686 $decrease = getDolGlobalInt('HOLIDAY_DECREASE_AT_END_OF_MONTH');
1687
1688 // If updated for everyone at the beginning of the month
1689 $now = dol_now();
1690
1691 // Get month of last update
1692 $stringInDBForLastUpdate = $this->getConfCP('lastUpdate', dol_print_date($now, '%Y%m%d%H%M%S')); // Example '20200101120000'
1693 // Protection when $lastUpdate has a not valid value
1694 if ($stringInDBForLastUpdate < '20000101000000') {
1695 $stringInDBForLastUpdate = '20000101000000';
1696 }
1697 $lastUpdate = dol_stringtotime($stringInDBForLastUpdate);
1698 //print 'lastUpdate:'.$lastUpdate;exit;
1699
1700 $yearMonthLastUpdate = dol_print_date($lastUpdate, '%Y%m');
1701 $yearMonthNow = dol_print_date($now, '%Y%m');
1702 //print 'yearMonthLastUpdate='.$yearMonthLastUpdate.' yearMonthNow='.$yearMonthNow;
1703
1704 // 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,
1705 // catching up to the current month if a gap is detected
1706 while ($yearMonthLastUpdate < $yearMonthNow) {
1707 $this->db->begin();
1708
1709 $year = dol_print_date($lastUpdate, '%Y');
1710 $month = dol_print_date($lastUpdate, '%m');
1711
1712 $users = $this->fetchUsers(false, false, ' AND u.statut > 0');
1713 $nbUser = count($users);
1714
1715 $typeleaves = $this->getTypes(1, 1);
1716
1717 // Update each user counter
1718 foreach ($users as $userCounter) {
1719 $nbDaysToAdd = (isset($typeleaves[$userCounter['type']]['newbymonth']) ? $typeleaves[$userCounter['type']]['newbymonth'] : 0);
1720 if (empty($nbDaysToAdd)) {
1721 continue;
1722 }
1723
1724 dol_syslog("We update leave type id ".$userCounter['type']." for user id ".$userCounter['rowid'], LOG_DEBUG);
1725
1726 $nowHoliday = (float) $userCounter['nb_holiday'];
1727 $newSolde = $nowHoliday + $nbDaysToAdd;
1728
1729 // We add a log for each user when its balance gets increased
1730 $this->addLogCP($user->id, $userCounter['rowid'], $langs->trans('HolidayMonthlyCredit'), $newSolde, $userCounter['type']);
1731
1732 $result = $this->updateSoldeCP($userCounter['rowid'], $newSolde, $userCounter['type']);
1733
1734 if ($result < 0) {
1735 $this->db->rollback();
1736 return -1;
1737 }
1738
1739 if (empty($decrease)) {
1740 continue;
1741 }
1742
1743 // We fetch a user's holiday in the current month and then calculate the number of days to deduct if he has at least one registered
1744 $filter = " AND cp.statut = ".((int) self::STATUS_APPROVED);
1745 $filter .= " AND cp.date_fin >= '".$this->db->idate(dol_stringtotime(dol_print_date($lastUpdate, '%Y-%m-01')))."'";
1746 $filter .= " AND cp.date_debut <= '".$this->db->idate(dol_stringtotime(dol_print_date($lastUpdate, '%Y-%m-t')))."'";
1747 $filter .= " AND cp.fk_type = ".((int) $userCounter['type']);
1748 $this->fetchByUser($userCounter['id'], '', $filter);
1749
1750 if (empty($this->holiday)) {
1751 continue;
1752 }
1753
1754 $startOfMonth = dol_mktime(0, 0, 0, (int) $month, 1, (int) $year, 1);
1755 $endOfMonth = dol_mktime(0, 0, 0, (int) $month, (int) dol_print_date($lastUpdate, 't'), (int) $year, 1);
1756
1757 foreach ($this->holiday as $obj) {
1758 $startDate = $obj['date_debut_gmt'];
1759 $endDate = $obj['date_fin_gmt'];
1760
1761 if ($startDate <= $endOfMonth && $startDate < $startOfMonth) {
1762 $startDate = $startOfMonth;
1763 }
1764
1765 if ($startOfMonth <= $endDate && $endDate > $endOfMonth) {
1766 $endDate = $endOfMonth;
1767 }
1768
1769 $nbDaysToDeduct = (int) num_open_day($startDate, $endDate, 0, 1, $obj['halfday'], $obj['country_id'], $obj['fk_user']);
1770
1771 if ($nbDaysToDeduct <= 0) {
1772 continue;
1773 }
1774
1775 $newSolde -= $nbDaysToDeduct;
1776
1777 // We add a log for each user when its balance gets decreased
1778 $this->addLogCP($user->id, $userCounter['rowid'], $obj['ref'].' - '.$langs->trans('HolidayConsumption'), $newSolde, $userCounter['type']);
1779
1780 $result = $this->updateSoldeCP($userCounter['rowid'], $newSolde, $userCounter['type']);
1781
1782 if ($result < 0) {
1783 $this->db->rollback();
1784 return -1;
1785 }
1786 }
1787 }
1788
1789 // Updating the date of the last monthly balance update
1790 $newMonth = dol_get_next_month((int) dol_print_date($lastUpdate, '%m'), (int) dol_print_date($lastUpdate, '%Y'));
1791 $lastUpdate = dol_mktime(0, 0, 0, (int) $newMonth['month'], 1, (int) $newMonth['year']);
1792
1793 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
1794 $sql .= " value = '".$this->db->escape(dol_print_date($lastUpdate, '%Y%m%d%H%M%S'))."'";
1795 $sql .= " WHERE name = 'lastUpdate'";
1796 $result = $this->db->query($sql);
1797
1798 if (!$result) {
1799 $this->db->rollback();
1800 return -1;
1801 }
1802
1803 $this->db->commit();
1804
1805 $yearMonthLastUpdate = dol_print_date($lastUpdate, '%Y%m');
1806 }
1807
1808 return 1;
1809 } else {
1810 // Update for one user
1811 $nbHoliday = price2num($nbHoliday, 5);
1812
1813 $sql = "SELECT nb_holiday FROM ".MAIN_DB_PREFIX."holiday_users";
1814 $sql .= " WHERE fk_user = ".(int) $userID." AND fk_type = ".(int) $fk_type;
1815 $resql = $this->db->query($sql);
1816 if ($resql) {
1817 $num = $this->db->num_rows($resql);
1818
1819 if ($num > 0) {
1820 // Update for user
1821 $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_users SET";
1822 $sql .= " nb_holiday = ".((float) $nbHoliday);
1823 $sql .= " WHERE fk_user = ".(int) $userID." AND fk_type = ".(int) $fk_type;
1824 $result = $this->db->query($sql);
1825 if (!$result) {
1826 $error++;
1827 $this->errors[] = $this->db->lasterror();
1828 }
1829 } else {
1830 // Insert for user
1831 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users(nb_holiday, fk_user, fk_type) VALUES (";
1832 $sql .= ((float) $nbHoliday);
1833 $sql .= ", ".(int) $userID.", ".(int) $fk_type.")";
1834 $result = $this->db->query($sql);
1835 if (!$result) {
1836 $error++;
1837 $this->errors[] = $this->db->lasterror();
1838 }
1839 }
1840 } else {
1841 $this->errors[] = $this->db->lasterror();
1842 $error++;
1843 }
1844
1845 if (!$error) {
1846 return 1;
1847 } else {
1848 return -1;
1849 }
1850 }
1851 }
1852
1860 public function createCPusers($single = false, $userid = 0)
1861 {
1862 // do we have to add balance for all users ?
1863 if (!$single) {
1864 dol_syslog(get_class($this).'::createCPusers');
1865 $arrayofusers = $this->fetchUsers(false, true);
1866
1867 foreach ($arrayofusers as $users) {
1868 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users";
1869 $sql .= " (fk_user, nb_holiday)";
1870 $sql .= " VALUES (".((int) $users['rowid'])."', '0')";
1871
1872 $resql = $this->db->query($sql);
1873 if (!$resql) {
1874 dol_print_error($this->db);
1875 }
1876 }
1877 } else {
1878 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users";
1879 $sql .= " (fk_user, nb_holiday)";
1880 $sql .= " VALUES (".((int) $userid)."', '0')";
1881
1882 $resql = $this->db->query($sql);
1883 if (!$resql) {
1884 dol_print_error($this->db);
1885 }
1886 }
1887 }
1888
1896 public function getCPforUser($user_id, $fk_type = 0)
1897 {
1898 $sql = "SELECT nb_holiday";
1899 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users";
1900 $sql .= " WHERE fk_user = ".(int) $user_id;
1901 if ($fk_type > 0) {
1902 $sql .= " AND fk_type = ".(int) $fk_type;
1903 }
1904
1905 dol_syslog(get_class($this).'::getCPforUser user_id='.$user_id.' type_id='.$fk_type, LOG_DEBUG);
1906 $result = $this->db->query($sql);
1907 if ($result) {
1908 $obj = $this->db->fetch_object($result);
1909 //return number_format($obj->nb_holiday,2);
1910 if ($obj) {
1911 return $obj->nb_holiday;
1912 } else {
1913 return null;
1914 }
1915 } else {
1916 return null;
1917 }
1918 }
1919
1928 public function fetchUsers($stringlist = true, $type = true, $filters = '')
1929 {
1930 dol_syslog(get_class($this)."::fetchUsers", LOG_DEBUG);
1931
1932 if ($stringlist) {
1933 if ($type) {
1934 // If user of Dolibarr
1935 $sql = "SELECT";
1936 if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
1937 $sql .= " DISTINCT";
1938 }
1939 $sql .= " u.rowid";
1940 $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
1941
1942 if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
1943 $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
1944 $sql .= " WHERE ((ug.fk_user = u.rowid";
1945 $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
1946 $sql .= " OR u.entity = 0)"; // Show always superadmin
1947 } else {
1948 $sql .= " WHERE u.entity IN (".getEntity('user').")";
1949 }
1950 $sql .= " AND u.statut > 0";
1951 $sql .= " AND u.employee = 1"; // We only want employee users for holidays
1952 if ($filters) {
1953 $sql .= $filters;
1954 }
1955
1956 $resql = $this->db->query($sql);
1957
1958 // If no SQL error
1959 if ($resql) {
1960 $i = 0;
1961 $num = $this->db->num_rows($resql);
1962 $stringlist = '';
1963
1964 // User listing loops
1965 while ($i < $num) {
1966 $obj = $this->db->fetch_object($resql);
1967
1968 if ($i == 0) {
1969 $stringlist .= $obj->rowid;
1970 } else {
1971 $stringlist .= ', '.$obj->rowid;
1972 }
1973
1974 $i++;
1975 }
1976 // Returns the user table
1977 return $stringlist;
1978 } else {
1979 // SQL error
1980 $this->error = "Error ".$this->db->lasterror();
1981 return -1;
1982 }
1983 } else {
1984 // We want only list of vacation balance for user ids
1985 $sql = "SELECT DISTINCT cpu.fk_user";
1986 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u";
1987 $sql .= " WHERE cpu.fk_user = u.rowid";
1988 if ($filters) {
1989 $sql .= $filters;
1990 }
1991
1992 $resql = $this->db->query($sql);
1993
1994 // If no SQL error
1995 if ($resql) {
1996 $i = 0;
1997 $num = $this->db->num_rows($resql);
1998 $stringlist = '';
1999
2000 // User listing loops
2001 while ($i < $num) {
2002 $obj = $this->db->fetch_object($resql);
2003
2004 if ($i == 0) {
2005 $stringlist .= $obj->fk_user;
2006 } else {
2007 $stringlist .= ', '.$obj->fk_user;
2008 }
2009
2010 $i++;
2011 }
2012 // Returns the user table
2013 return $stringlist;
2014 } else {
2015 // SQL error
2016 $this->error = "Error ".$this->db->lasterror();
2017 return -1;
2018 }
2019 }
2020 } else {
2021 // If false, return array
2022 // List for Dolibarr users
2023 if ($type) {
2024 // If we need users of Dolibarr
2025 $sql = "SELECT";
2026 if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
2027 $sql .= " DISTINCT";
2028 }
2029 $sql .= " u.rowid, u.lastname, u.firstname, u.gender, u.fk_country as country_id, u.photo, u.employee, u.statut as status, u.fk_user";
2030 $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
2031
2032 if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
2033 $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
2034 $sql .= " WHERE ((ug.fk_user = u.rowid";
2035 $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
2036 $sql .= " OR u.entity = 0)"; // Show always superadmin
2037 } else {
2038 $sql .= " WHERE u.entity IN (".getEntity('user').")";
2039 }
2040
2041 $sql .= " AND u.statut > 0";
2042 $sql .= " AND u.employee = 1"; // We only want employee users for holidays
2043 if ($filters) {
2044 $sql .= $filters;
2045 }
2046
2047 $resql = $this->db->query($sql);
2048
2049 // If no SQL error
2050 if ($resql) {
2051 $i = 0;
2052 $tab_result = $this->holiday;
2053 $num = $this->db->num_rows($resql);
2054
2055 // User listing loops
2056 while ($i < $num) {
2057 $obj = $this->db->fetch_object($resql);
2058
2059 $tab_result[$i]['rowid'] = (int) $obj->rowid; // rowid of user
2060 $tab_result[$i]['id'] = (int) $obj->rowid; // id of user
2061 $tab_result[$i]['name'] = $obj->lastname; // deprecated
2062 $tab_result[$i]['lastname'] = $obj->lastname;
2063 $tab_result[$i]['firstname'] = $obj->firstname;
2064 $tab_result[$i]['gender'] = $obj->gender;
2065 $tab_result[$i]['status'] = (int) $obj->status;
2066 $tab_result[$i]['employee'] = (int) $obj->employee;
2067 $tab_result[$i]['photo'] = $obj->photo;
2068 $tab_result[$i]['fk_user'] = (int) $obj->fk_user; // rowid of manager
2069 $tab_result[$i]['country_id'] = (int) $obj->country_id; // id of country of user
2070 //$tab_result[$i]['type'] = $obj->type;
2071 //$tab_result[$i]['nb_holiday'] = $obj->nb_holiday;
2072
2073 $i++;
2074 }
2075 // Returns the user table
2076 return $tab_result;
2077 } else {
2078 // SQL error
2079 $this->errors[] = "Error ".$this->db->lasterror();
2080 return -1;
2081 }
2082 } else {
2083 // List of vacation balance users
2084 $sql = "SELECT cpu.fk_type, cpu.nb_holiday, u.rowid, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut as status, u.fk_user";
2085 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u";
2086 $sql .= " WHERE cpu.fk_user = u.rowid";
2087 if ($filters) {
2088 $sql .= $filters;
2089 }
2090
2091 $resql = $this->db->query($sql);
2092
2093 // If no SQL error
2094 if ($resql) {
2095 $i = 0;
2096 $tab_result = $this->holiday;
2097 $num = $this->db->num_rows($resql);
2098
2099 // User listing loops
2100 while ($i < $num) {
2101 $obj = $this->db->fetch_object($resql);
2102
2103 $tab_result[$i]['rowid'] = $obj->rowid; // rowid of user
2104 $tab_result[$i]['id'] = $obj->rowid; // id of user
2105 $tab_result[$i]['name'] = $obj->lastname; // deprecated
2106 $tab_result[$i]['lastname'] = $obj->lastname;
2107 $tab_result[$i]['firstname'] = $obj->firstname;
2108 $tab_result[$i]['gender'] = $obj->gender;
2109 $tab_result[$i]['status'] = $obj->status;
2110 $tab_result[$i]['employee'] = $obj->employee;
2111 $tab_result[$i]['photo'] = $obj->photo;
2112 $tab_result[$i]['fk_user'] = $obj->fk_user; // rowid of manager
2113
2114 $tab_result[$i]['type'] = $obj->fk_type;
2115 $tab_result[$i]['nb_holiday'] = $obj->nb_holiday;
2116
2117 $i++;
2118 }
2119 // Returns the user table
2120 return $tab_result;
2121 } else {
2122 // SQL error
2123 $this->error = "Error ".$this->db->lasterror();
2124 return -1;
2125 }
2126 }
2127 }
2128 }
2129
2130
2131 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2139 {
2140 // phpcs:enable
2141 $users_validator = array();
2142
2143 $sql = "SELECT DISTINCT ur.fk_user";
2144 $sql .= " FROM ".MAIN_DB_PREFIX."user_rights as ur, ".MAIN_DB_PREFIX."rights_def as rd";
2145 $sql .= " WHERE ur.fk_id = rd.id and rd.module = 'holiday' AND rd.perms = 'approve'"; // Permission 'Approve';
2146 $sql .= "UNION";
2147 $sql .= " SELECT DISTINCT ugu.fk_user";
2148 $sql .= " FROM ".MAIN_DB_PREFIX."usergroup_user as ugu, ".MAIN_DB_PREFIX."usergroup_rights as ur, ".MAIN_DB_PREFIX."rights_def as rd";
2149 $sql .= " WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'holiday' AND rd.perms = 'approve'"; // Permission 'Approve';
2150 //print $sql;
2151
2152 dol_syslog(get_class($this)."::fetch_users_approver_holiday sql=".$sql);
2153 $result = $this->db->query($sql);
2154 if ($result) {
2155 $num_rows = $this->db->num_rows($result);
2156 $i = 0;
2157 while ($i < $num_rows) {
2158 $objp = $this->db->fetch_object($result);
2159 array_push($users_validator, $objp->fk_user);
2160 $i++;
2161 }
2162 return $users_validator;
2163 } else {
2164 $this->error = $this->db->lasterror();
2165 dol_syslog(get_class($this)."::fetch_users_approver_holiday Error ".$this->error, LOG_ERR);
2166 return -1;
2167 }
2168 }
2169
2170
2176 public function countActiveUsers()
2177 {
2178 $sql = "SELECT count(u.rowid) as compteur";
2179 $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
2180 $sql .= " WHERE u.statut > 0";
2181
2182 $result = $this->db->query($sql);
2183 $object = $this->db->fetch_object($result);
2184
2185 return $object->compteur;
2186 }
2193 {
2194 $sql = "SELECT count(u.rowid) as compteur";
2195 $sql .= " FROM ".MAIN_DB_PREFIX."user as u LEFT JOIN ".MAIN_DB_PREFIX."holiday_users hu ON (hu.fk_user=u.rowid)";
2196 $sql .= " WHERE u.statut > 0 AND hu.fk_user IS NULL";
2197
2198 $result = $this->db->query($sql);
2199 $object = $this->db->fetch_object($result);
2200
2201 return $object->compteur;
2202 }
2203
2211 public function verifNbUsers($userDolibarrWithoutCP, $userCP)
2212 {
2213 if (empty($userCP)) {
2214 $userCP = 0;
2215 }
2216 dol_syslog(get_class($this).'::verifNbUsers userDolibarr='.$userDolibarrWithoutCP.' userCP='.$userCP);
2217 return 1;
2218 }
2219
2220
2231 public function addLogCP($fk_user_action, $fk_user_update, $label, $new_solde, $fk_type)
2232 {
2233 $error = 0;
2234
2235 $prev_solde = price2num((float) $this->getCPforUser($fk_user_update, $fk_type), 5);
2236 $new_solde = price2num($new_solde, 5);
2237 //print "$prev_solde == $new_solde";
2238
2239 if ($prev_solde == $new_solde) {
2240 return 0;
2241 }
2242
2243 $this->db->begin();
2244
2245 // Insert request
2246 $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_logs (";
2247 $sql .= "date_action,";
2248 $sql .= "fk_user_action,";
2249 $sql .= "fk_user_update,";
2250 $sql .= "type_action,";
2251 $sql .= "prev_solde,";
2252 $sql .= "new_solde,";
2253 $sql .= "fk_type";
2254 $sql .= ") VALUES (";
2255 $sql .= " '".$this->db->idate(dol_now())."',";
2256 $sql .= " ".((int) $fk_user_action).",";
2257 $sql .= " ".((int) $fk_user_update).",";
2258 $sql .= " '".$this->db->escape($label)."',";
2259 $sql .= " ".((float) $prev_solde).",";
2260 $sql .= " ".((float) $new_solde).",";
2261 $sql .= " ".((int) $fk_type);
2262 $sql .= ")";
2263
2264 $resql = $this->db->query($sql);
2265 if (!$resql) {
2266 $error++;
2267 $this->errors[] = "Error ".$this->db->lasterror();
2268 }
2269
2270 $optRowid = 0;
2271 if (!$error) {
2272 $optRowid = $this->db->last_insert_id(MAIN_DB_PREFIX."holiday_logs");
2273 }
2274
2275 // Commit or rollback
2276 if ($error) {
2277 foreach ($this->errors as $errmsg) {
2278 dol_syslog(get_class($this)."::addLogCP ".$errmsg, LOG_ERR);
2279 $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
2280 }
2281 $this->db->rollback();
2282 return -1 * $error;
2283 } else {
2284 $this->db->commit();
2285 return $optRowid;
2286 }
2287 }
2288
2296 public function fetchLog($sqlorder, $sqlwhere)
2297 {
2298 $sql = "SELECT";
2299 $sql .= " cpl.rowid,";
2300 $sql .= " cpl.date_action,";
2301 $sql .= " cpl.fk_user_action,";
2302 $sql .= " cpl.fk_user_update,";
2303 $sql .= " cpl.type_action,";
2304 $sql .= " cpl.prev_solde,";
2305 $sql .= " cpl.new_solde,";
2306 $sql .= " cpl.fk_type";
2307 $sql .= " FROM ".MAIN_DB_PREFIX."holiday_logs as cpl";
2308 $sql .= " WHERE cpl.rowid > 0"; // To avoid error with other search and criteria
2309
2310 // Filter
2311 if (!empty($sqlwhere)) {
2312 $sql .= " ".$sqlwhere;
2313 }
2314
2315 // Order
2316 if (!empty($sqlorder)) {
2317 $sql .= " ".$sqlorder;
2318 }
2319
2320 dol_syslog(get_class($this)."::fetchLog", LOG_DEBUG);
2321 $resql = $this->db->query($sql);
2322
2323 // If no error SQL
2324 if ($resql) {
2325 $i = 0;
2326 $tab_result = $this->logs;
2327 $num = $this->db->num_rows($resql);
2328
2329 // If no record
2330 if (!$num) {
2331 return 2;
2332 }
2333
2334 // Loop on result to fill the array
2335 while ($i < $num) {
2336 $obj = $this->db->fetch_object($resql);
2337
2338 $tab_result[$i]['rowid'] = (int) $obj->rowid;
2339 $tab_result[$i]['id'] = (int) $obj->rowid;
2340 $tab_result[$i]['date_action'] = (string) $obj->date_action;
2341 $tab_result[$i]['fk_user_action'] = (int) $obj->fk_user_action;
2342 $tab_result[$i]['fk_user_update'] = (int) $obj->fk_user_update;
2343 $tab_result[$i]['type_action'] = (string) $obj->type_action;
2344 $tab_result[$i]['prev_solde'] = (float) $obj->prev_solde;
2345 $tab_result[$i]['new_solde'] = (float) $obj->new_solde;
2346 $tab_result[$i]['fk_type'] = (int) $obj->fk_type;
2347
2348 $i++;
2349 }
2350 // Returns 1 and adds the array to the variable
2351 $this->logs = $tab_result;
2352 return 1;
2353 } else {
2354 // SQL error
2355 $this->error = "Error ".$this->db->lasterror();
2356 return -1;
2357 }
2358 }
2359
2360
2368 public function getTypes($active = -1, $affect = -1)
2369 {
2370 global $mysoc;
2371
2372 $sql = "SELECT rowid, code, label, affect, delay, newbymonth";
2373 $sql .= " FROM ".MAIN_DB_PREFIX."c_holiday_types";
2374 $sql .= " WHERE (fk_country IS NULL OR fk_country = ".((int) $mysoc->country_id).')';
2375 $sql .= " AND entity IN (0, ".getEntity('c_holiday_types').")"; // Need entity 0 (holiday types common to all countries= + current entity).
2376 if ($active >= 0) {
2377 $sql .= " AND active = ".((int) $active);
2378 }
2379 if ($affect >= 0) {
2380 $sql .= " AND affect = ".((int) $affect);
2381 }
2382 $sql .= " ORDER BY sortorder";
2383
2384 $result = $this->db->query($sql);
2385 if ($result) {
2386 $num = $this->db->num_rows($result);
2387 if ($num) {
2388 $types = array();
2389 while ($obj = $this->db->fetch_object($result)) {
2390 $types[$obj->rowid] = array(
2391 'id' => $obj->rowid,
2392 'rowid' => $obj->rowid,
2393 'code' => $obj->code,
2394 'label' => $obj->label,
2395 'affect' => $obj->affect,
2396 'delay' => $obj->delay,
2397 'newbymonth' => $obj->newbymonth
2398 );
2399 }
2400
2401 return $types;
2402 }
2403 } else {
2404 dol_print_error($this->db);
2405 }
2406
2407 return array();
2408 }
2409
2410
2417 public function info($id)
2418 {
2419 global $conf;
2420
2421 $sql = "SELECT f.rowid, f.statut as status,";
2422 $sql .= " f.date_create as datec,";
2423 $sql .= " f.tms as date_modification,";
2424 $sql .= " f.date_valid as datev,";
2425 $sql .= " f.date_approval as datea,";
2426 $sql .= " f.date_refuse as dater,";
2427 $sql .= " f.fk_user_create as fk_user_creation,";
2428 $sql .= " f.fk_user_modif as fk_user_modification,";
2429 $sql .= " f.fk_user_valid as fk_user_validation,";
2430 $sql .= " f.fk_user_approve as fk_user_approval_done,";
2431 $sql .= " f.fk_validator as fk_user_approval_expected,";
2432 $sql .= " f.fk_user_refuse as fk_user_refuse";
2433 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as f";
2434 $sql .= " WHERE f.rowid = ".((int) $id);
2435 $sql .= " AND f.entity = ".$conf->entity;
2436
2437 $resql = $this->db->query($sql);
2438 if ($resql) {
2439 if ($this->db->num_rows($resql)) {
2440 $obj = $this->db->fetch_object($resql);
2441
2442 $this->id = $obj->rowid;
2443
2444 $this->date_creation = $this->db->jdate($obj->datec);
2445 $this->date_modification = $this->db->jdate($obj->date_modification);
2446 $this->date_validation = $this->db->jdate($obj->datev);
2447 $this->date_approval = $this->db->jdate($obj->datea);
2448
2449 $this->user_creation_id = $obj->fk_user_creation;
2450 $this->user_validation_id = $obj->fk_user_validation;
2451 $this->user_modification_id = $obj->fk_user_modification;
2452
2453 if ($obj->status == Holiday::STATUS_APPROVED || $obj->status == Holiday::STATUS_CANCELED) {
2454 if ($obj->fk_user_approval_done) {
2455 $this->fk_user_approve = $obj->fk_user_approval_done;
2456 }
2457 }
2458 }
2459 $this->db->free($resql);
2460 } else {
2461 dol_print_error($this->db);
2462 }
2463 }
2464
2465
2473 public function initAsSpecimen()
2474 {
2475 global $user, $langs;
2476
2477 // Initialise parameters
2478 $this->id = 0;
2479 $this->specimen = 1;
2480
2481 $this->fk_user = $user->id;
2482 $this->description = 'SPECIMEN description';
2483 $this->date_debut = dol_now();
2484 $this->date_fin = dol_now() + (24 * 3600);
2485 $this->date_valid = dol_now();
2486 $this->fk_validator = $user->id;
2487 $this->halfday = 0;
2488 $this->fk_type = 1;
2490
2491 return 1;
2492 }
2493
2499 public function loadStateBoard()
2500 {
2501 global $user;
2502
2503 $this->nb = array();
2504
2505 $sql = "SELECT count(h.rowid) as nb";
2506 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
2507 $sql .= " WHERE h.statut > 1";
2508 $sql .= " AND h.entity IN (".getEntity('holiday').")";
2509 if (!$user->hasRight('holiday', 'readall')) {
2510 $userchildids = $user->getAllChildIds(1);
2511 $sql .= " AND (h.fk_user IN (".$this->db->sanitize(implode(',', $userchildids)).")";
2512 $sql .= " OR h.fk_validator IN (".$this->db->sanitize(implode(',', $userchildids))."))";
2513 }
2514
2515 $resql = $this->db->query($sql);
2516 if ($resql) {
2517 while ($obj = $this->db->fetch_object($resql)) {
2518 $this->nb["holidays"] = $obj->nb;
2519 }
2520 $this->db->free($resql);
2521 return 1;
2522 } else {
2523 dol_print_error($this->db);
2524 $this->error = $this->db->error();
2525 return -1;
2526 }
2527 }
2528
2529 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2536 public function load_board($user)
2537 {
2538 // phpcs:enable
2539 global $conf, $langs;
2540
2541 if ($user->socid) {
2542 return -1; // Protection to prevent calls by external users
2543 }
2544
2545 $now = dol_now();
2546
2547 $sql = "SELECT h.rowid, h.date_debut";
2548 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
2549 $sql .= " WHERE h.statut = 2";
2550 $sql .= " AND h.entity IN (".getEntity('holiday').")";
2551 if (!$user->hasRight('holiday', 'read_all')) {
2552 $userchildids = $user->getAllChildIds(1);
2553 $sql .= " AND (h.fk_user IN (".$this->db->sanitize(implode(',', $userchildids)).")";
2554 $sql .= " OR h.fk_validator IN (".$this->db->sanitize(implode(',', $userchildids))."))";
2555 }
2556
2557 $resql = $this->db->query($sql);
2558 if ($resql) {
2559 $langs->load("members");
2560
2561 $response = new WorkboardResponse();
2562 $response->warning_delay = $conf->holiday->approve->warning_delay / 60 / 60 / 24;
2563 $response->label = $langs->trans("HolidaysToApprove");
2564 $response->labelShort = $langs->trans("ToApprove");
2565 $response->url = DOL_URL_ROOT.'/holiday/list.php?search_status=2&amp;mainmenu=hrm&amp;leftmenu=holiday';
2566 $response->img = img_object('', "holiday");
2567
2568 while ($obj = $this->db->fetch_object($resql)) {
2569 $response->nbtodo++;
2570
2571 if ($this->db->jdate($obj->date_debut) < ($now - $conf->holiday->approve->warning_delay)) {
2572 $response->nbtodolate++;
2573 }
2574 }
2575
2576 return $response;
2577 } else {
2578 dol_print_error($this->db);
2579 $this->error = $this->db->error();
2580 return -1;
2581 }
2582 }
2590 public function getKanbanView($option = '', $arraydata = null)
2591 {
2592 global $langs;
2593
2594 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
2595
2596 $return = '<div class="box-flex-item box-flex-grow-zero">';
2597 $return .= '<div class="info-box info-box-sm">';
2598 $return .= '<span class="info-box-icon bg-infobox-action">';
2599 $return .= img_picto('', $this->picto);
2600 $return .= '</span>';
2601 $return .= '<div class="info-box-content">';
2602 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.$this->getNomUrl().'</span>';
2603 if ($selected >= 0) {
2604 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
2605 }
2606 if (property_exists($this, 'fk_type')) {
2607 $return .= '<br>';
2608 //$return .= '<span class="opacitymedium">'.$langs->trans("Type").'</span> : ';
2609 $return .= '<div class="info_box-label tdoverflowmax100" title="'.dol_escape_htmltag($arraydata['labeltype']).'">'.dol_escape_htmltag($arraydata['labeltype']).'</div>';
2610 }
2611 if (property_exists($this, 'date_debut') && property_exists($this, 'date_fin')) {
2612 $return .= '<span class="info-box-label small">'.dol_print_date($this->date_debut, 'day').'</span>';
2613 $return .= ' <span class="opacitymedium small">'.$langs->trans("To").'</span> ';
2614 $return .= '<span class="info-box-label small">'.dol_print_date($this->date_fin, 'day').'</span>';
2615 if (!empty($arraydata['nbopenedday'])) {
2616 $return .= ' ('.$arraydata['nbopenedday'].')';
2617 }
2618 }
2619 if (method_exists($this, 'getLibStatut')) {
2620 $return .= '<div class="info-box-status">'.$this->getLibStatut(3).'</div>';
2621 }
2622 $return .= '</div>';
2623 $return .= '</div>';
2624 $return .= '</div>';
2625 return $return;
2626 }
2627
2638 public function sendPreviousMonthHRInformations($mailto = "", $template = "", $newlang = "")
2639 {
2640 global $conf, $langs, $user;
2641
2642 $outputlangs = $langs;
2643
2644 $error = 0;
2645 $this->output = '';
2646 $this->error = '';
2647 $arrayfields = array(
2648 'user' => 'Employee',
2649 'type' => 'Type',
2650 'date_start' => 'DateDebCP',
2651 'date_end' => 'DateFinCP',
2652 'used_days' => 'NbUseDaysCPShort',
2653 );
2654
2655 if (!empty($newlang)) {
2656 $outputlangs = new Translate("", $conf);
2657 $outputlangs->setDefaultLang($newlang);
2658 }
2659 $outputlangs->loadLangs(array('main', 'holiday', 'hrm'));
2660
2661 if (empty($mailto) || !isValidEmail($mailto)) {
2662 $this->errors[] = 'Bad value for parameter mailto. Must be a valid email address.';
2663 return 1;
2664 }
2665
2666 $typeleaves = $this->getTypes(1, -1);
2667 $arraytypeleaves = array();
2668 foreach ($typeleaves as $val) {
2669 $labeltoshow = ($outputlangs->trans($val['code']) != $val['code'] ? $outputlangs->trans($val['code']) : $val['label']);
2670 $arraytypeleaves[$val['rowid']] = $labeltoshow;
2671 }
2672 $listhalfday = array('morning' => $outputlangs->trans("Morning"), "afternoon" => $outputlangs->trans("Afternoon"));
2673
2674 $datenow = dol_getdate(dol_now());
2675 $prev_month = dol_get_prev_month($datenow["mon"], $datenow["year"]);
2676 $year_month = sprintf("%04d", $prev_month["year"]).'-'.sprintf("%02d", $prev_month["month"]);
2677 $arrayleaves = array();
2678
2679 $sql = "SELECT cp.rowid, cp.ref, cp.fk_user, cp.date_debut, cp.date_fin, cp.fk_type, cp.description, cp.halfday, cp.statut as status";
2680 $sql .= " FROM ".MAIN_DB_PREFIX."holiday cp";
2681 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user u ON cp.fk_user = u.rowid";
2682 $sql .= " WHERE cp.entity IN (".getEntity('holiday').") AND cp.rowid > 0";
2683 $sql .= " AND cp.statut = ".Holiday::STATUS_APPROVED;
2684 $sql .= " AND (";
2685 $sql .= " (date_format(cp.date_debut, '%Y-%m') = '".$this->db->escape($year_month)."' OR date_format(cp.date_fin, '%Y-%m') = '".$this->db->escape($year_month)."')";
2686 $sql .= " OR"; // For leave over several months
2687 $sql .= " (date_format(cp.date_debut, '%Y-%m') < '".$this->db->escape($year_month)."' AND date_format(cp.date_fin, '%Y-%m') > '".$this->db->escape($year_month)."') ";
2688 $sql .= " )";
2689 $sql .= $this->db->order("cp.fk_user, cp.date_debut", "ASC");
2690 $resql = $this->db->query($sql);
2691 if (empty($resql)) {
2692 $this->errors[] = $this->db->lasterror();
2693 return 1;
2694 }
2695 $num = $this->db->num_rows($resql);
2696 if ($num > 0) {
2697 $tmpuser = new User($this->db);
2698 while ($obj = $this->db->fetch_object($resql)) {
2699 $tmpuser->fetch($obj->fk_user);
2700
2701 $date_start = $this->db->jdate($obj->date_debut, true);
2702 $date_end = $this->db->jdate($obj->date_fin, true);
2703
2704 $tmpstart = dol_getdate($date_start);
2705 $tmpend = dol_getdate($date_end);
2706
2707 $starthalfday = ($obj->halfday == -1 || $obj->halfday == 2) ? 'afternoon' : 'morning';
2708 $endhalfday = ($obj->halfday == 1 || $obj->halfday == 2) ? 'morning' : 'afternoon';
2709
2710 $halfdayinmonth = $obj->halfday;
2711 $starthalfdayinmonth = $starthalfday;
2712 $endhalfdayinmonth = $endhalfday;
2713
2714 //0:Full days, 2:Start afternoon end morning, -1:Start afternoon end afternoon, 1:Start morning end morning
2715
2716 // Set date_start_gmt and date_end_gmt that are date to show for the selected month
2717 $date_start_inmonth = $this->db->jdate($obj->date_debut, true);
2718 $date_end_inmonth = $this->db->jdate($obj->date_fin, true);
2719 if ($tmpstart['year'] < $prev_month["year"] || $tmpstart['mon'] < $prev_month["month"]) {
2720 $date_start_inmonth = dol_get_first_day($prev_month["year"], $prev_month["month"], true);
2721 $starthalfdayinmonth = 'morning';
2722 if ($halfdayinmonth == 2) {
2723 $halfdayinmonth = 1;
2724 }
2725 if ($halfdayinmonth == -1) {
2726 $halfdayinmonth = 0;
2727 }
2728 }
2729 if ($tmpend['year'] > $prev_month["year"] || $tmpend['mon'] > $prev_month["month"]) {
2730 $date_end_inmonth = dol_get_last_day($prev_month["year"], $prev_month["month"], true) - ((24 * 3600) - 1);
2731 $endhalfdayinmonth = 'afternoon';
2732 if ($halfdayinmonth == 2) {
2733 $halfdayinmonth = -1;
2734 }
2735 if ($halfdayinmonth == 1) {
2736 $halfdayinmonth = 0;
2737 }
2738 }
2739 $arrayleaves[] = array(
2740 "user" => $tmpuser->getNomUrl(0, 'nolink', 0, 0, 24, 1),
2741 "type" => $arraytypeleaves[$obj->fk_type],
2742 "date_start" => dol_print_date($date_start_inmonth, 'day') . ' <span class="opacitymedium">('.$outputlangs->trans($listhalfday[$starthalfdayinmonth]).')</span>',
2743 "date_end" => dol_print_date($date_end_inmonth, 'day') . ' <span class="opacitymedium">('.$outputlangs->trans($listhalfday[$endhalfdayinmonth]).')</span>',
2744 "used_days" => num_open_day($date_start_inmonth, $date_end_inmonth, 0, 1, $halfdayinmonth, $tmpuser->country_id, $obj->fk_user)
2745 );
2746 }
2747 }
2748
2749 $outputarrayleaves = '<br><table style="width: 100%;border-collapse: separate !important;border-spacing: 0px;border-top: 1px solid #b6b6b6;border-left: 1px solid #b6b6b6;border-right: 1px solid #b6b6b6;margin: 0px 0px 20px 0px;">';
2750 $outputarrayleaves .= '<tr>';
2751 foreach ($arrayfields as $key => $label) {
2752 $outputarrayleaves .= '<td style="border-bottom:1px solid #b6b6b6;padding: 6px 10px 6px 12px;">';
2753 $outputarrayleaves .= $outputlangs->trans($label);
2754 $outputarrayleaves .= '</td>';
2755 }
2756 $outputarrayleaves .= '</tr>';
2757
2758 if (!empty($arrayleaves)) {
2759 foreach ($arrayleaves as $key => $fields) {
2760 $outputarrayleaves .= '<tr>';
2761 foreach ($fields as $field => $value) {
2762 $outputarrayleaves .= '<td style="border-bottom:1px solid #b6b6b6;padding: 6px 10px 6px 12px;" id="'.$field.'">';
2763 $outputarrayleaves .= $value;
2764 $outputarrayleaves .= '</td>';
2765 }
2766 $outputarrayleaves .= '</tr>';
2767 }
2768 } else {
2769 $outputarrayleaves .= '<tr>';
2770 $outputarrayleaves .= '<td style="border-bottom:1px solid #b6b6b6;padding: 6px 10px 6px 12px;" colspan="5">';
2771 $outputarrayleaves .= $outputlangs->trans("None");
2772 $outputarrayleaves .= '</td>';
2773 $outputarrayleaves .= '</tr>';
2774 }
2775 $outputarrayleaves .= '</table>';
2776
2777 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
2778 include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
2779
2780 $formmail = new FormMail($this->db);
2781 $templateId = 0;
2782 $templateLabel = '';
2783 if (empty($template) || $template == 'EmailTemplateCode') {
2784 $templateLabel = '(HolidayHrInformationsPreviousMonth)';
2785 } else {
2786 if (is_numeric($template)) {
2787 $templateId = $template;
2788 } else {
2789 $templateLabel = $template;
2790 }
2791 }
2792 $mailtemplate = $formmail->getEMailTemplate($this->db, "holiday", $user, $outputlangs, $templateId, 1, $templateLabel);
2793
2794 if (is_numeric($mailtemplate) || empty($mailtemplate->topic)) {
2795 $this->errors[] = 'No mail template found for code "'.$templateLabel.'" or id "'.$templateId.'".';
2796 $error++;
2797 }
2798
2799 if (!$error) {
2800 $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $this);
2801 complete_substitutions_array($substitutionarray, $outputlangs, $this);
2802
2803 $subject = make_substitutions($mailtemplate->topic, $substitutionarray, $outputlangs);
2804 $msg = make_substitutions($mailtemplate->content, $substitutionarray, $outputlangs);
2805 $from = dol_string_nospecial(getDolGlobalString('MAIN_INFO_SOCIETE_NOM'), ' ', array(",")).' <' . getDolGlobalString('MAIN_INFO_SOCIETE_MAIL').'>';
2806
2807 $msg = preg_replace('/__HOLIDAY_ARRAY_PER_EMPLOYEE_FOR_PERIOD__/', $outputarrayleaves, $msg);
2808 $cmail = new CMailFile($subject, $mailto, $from, $msg, array(), array(), array(), '', '', 0, 1);
2809 $result = $cmail->sendfile();
2810 if (!$result || !empty($cmail->error) || !empty($cmail->errors)) {
2811 $this->errors[] = $cmail->error;
2812 if (is_array($cmail->errors) && count($cmail->errors) > 0) {
2813 $this->errors = array_merge($this->errors, $cmail->errors);
2814 $error++;
2815 }
2816 }
2817 }
2818
2819 if (!empty($this->errors)) {
2820 $this->output .= "\n";
2821 // The $this->errors will be concatenated to the output by the function that call this method.
2822 }
2823 return ($error ? 1 : 0);
2824 }
2825}
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:476
$object ref
Definition info.php:90
Class to send emails (with attachments or not) Usage: $mailfile = new CMailFile($subject,...
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.
Class to manage a HTML form to send a unitary email Usage: $formail = new FormMail($db) $formmail->pr...
Class of the module paid holiday.
getTypes($active=-1, $affect=-1)
Return array with list of types.
getNomUrl($withpicto=0, $save_lastsearch_value=-1, $notooltip=0, $morecss='')
Return clickable name (with picto eventually)
verifDateHolidayCP($fk_user, $dateStart, $dateEnd, $halfday=0)
Check if a user is on holiday (partially or completely) into a period.
validate($user=null, $notrigger=0)
Validate leave request.
info($id)
Load information on object.
updateBalance()
Update balance of vacations and check table of users for holidays is complete.
updateConfCP($name, $value)
Met à jour une option du module Holiday Payés.
const STATUS_VALIDATED
Validated status.
const STATUS_DRAFT
Draft status.
fetch($id, $ref='')
Load object in memory from database.
addLogCP($fk_user_action, $fk_user_update, $label, $new_solde, $fk_type)
addLogCP
verifNbUsers($userDolibarrWithoutCP, $userCP)
Compare the number of active Dolibarr users to the number of paid leave users.
verifDateHolidayForTimestamp($fk_user, $timestamp, $status='-1')
Check that a user is not on holiday for a particular timestamp.
approve($user=null, $notrigger=0)
Approve leave request.
const STATUS_REFUSED
Refused.
getConfCP($name, $createifnotfound='')
Return value of a conf parameter for leave module TODO Move this into llx_const table.
load_board($user)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
initAsSpecimen()
Initialise an instance with random values.
create($user, $notrigger=0)
Créer un congés payés dans la base de données.
selectStatutCP($selected=0, $htmlname='select_statut', $morecss='minwidth125')
Show select with list of leave status.
countActiveUsersWithoutCP()
Count number of active users in Dolibarr without Paid leave.
updateSoldeCP($userID=0, $nbHoliday=0, $fk_type=0)
Updates the timestamp of the last CP balance update.
update($user=null, $notrigger=0)
Update database.
getCPforUser($user_id, $fk_type=0)
Return the balance of annual leave of a user.
sendPreviousMonthHRInformations($mailto="", $template="", $newlang="")
Send a mail with previous month Hr information CAN BE A CRON TASK.
fetch_users_approver_holiday()
Return list of people with permission to validate leave requests.
__construct($db)
Constructor.
loadStateBoard()
Load this->nb for dashboard.
getLibStatut($mode=0)
Returns the label status.
createCPusers($single=false, $userid=0)
Create entries for each user at setup step.
fetchAll($order, $filter)
List all holidays of all users.
const STATUS_CANCELED
Canceled.
fetchLog($sqlorder, $sqlwhere)
List log of leaves.
countActiveUsers()
Count number of active users in Dolibarr.
fetchByUser($user_id, $order='', $filter='')
List holidays for a particular user or list of users.
const STATUS_APPROVED
Approved.
getTooltipContentArray($params)
getTooltipContentArray
fetchUsers($stringlist=true, $type=true, $filters='')
Get list of Users or list of vacation balance.
getKanbanView($option='', $arraydata=null)
Return clickable link of object (with eventually picto)
LibStatut($status, $mode=0, $startdate='')
Returns the label of a status.
Class to manage translations.
Class to manage Dolibarr users.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:168
global $mysoc
dol_get_prev_month($month, $year)
Return previous month.
Definition date.lib.php:523
num_open_day($timestampStart, $timestampEnd, $inhour=0, $lastday=0, $halfday=0, $countryCodeOrId='', $user_id=0)
Function to return number of working days (and text of units) between two dates (working days)
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition date.lib.php:604
dol_get_next_month($month, $year)
Return next month.
Definition date.lib.php:542
dol_stringtotime($string, $gm=1)
Convert a string date into a GM Timestamps date Warning: YYYY-MM-DDTHH:MM:SS+02:00 (RFC3339) is not s...
Definition date.lib.php:435
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition date.lib.php:623
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.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:64
$date_start
Variables from include:
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_string_nospecial($str, $newstr='_', $badcharstoreplace='', $badcharstoremove='', $keepspaces=0)
Clean a string from all punctuation characters to use it as a ref or login.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
complete_substitutions_array(&$substitutionarray, $outputlangs, $object=null, $parameters=null, $callfunc="completesubstitutionarray")
Complete the $substitutionarray with more entries coming from external module that had set the "subst...
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
isValidEmail($address, $acceptsupervisorkey=0, $acceptuserkey=0)
Return true if email syntax is ok.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
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...
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php