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