dolibarr  18.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-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 
791  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
792  $oldref = dol_sanitizeFileName($this->ref);
793  $newref = dol_sanitizeFileName($num);
794  $dirsource = $conf->holiday->multidir_output[$this->entity] . '/' . $oldref;
795  $dirdest = $conf->holiday->multidir_output[$this->entity] . '/' . $newref;
796  if (!$error && file_exists($dirsource)) {
797  dol_syslog(get_class($this) . "::validate rename dir " . $dirsource . " into " . $dirdest);
798  if (@rename($dirsource, $dirdest)) {
799  dol_syslog("Rename ok");
800  // Rename docs starting with $oldref with $newref
801  $listoffiles = dol_dir_list($dirdest, 'files', 1, '^' . preg_quote($oldref, '/'));
802  foreach ($listoffiles as $fileentry) {
803  $dirsource = $fileentry['name'];
804  $dirdest = preg_replace('/^' . preg_quote($oldref, '/') . '/', $newref, $dirsource);
805  $dirsource = $fileentry['path'] . '/' . $dirsource;
806  $dirdest = $fileentry['path'] . '/' . $dirdest;
807  @rename($dirsource, $dirdest);
808  }
809  }
810  }
811  }
812  }
813 
814 
815  // Commit or rollback
816  if ($error) {
817  foreach ($this->errors as $errmsg) {
818  dol_syslog(get_class($this)."::validate ".$errmsg, LOG_ERR);
819  $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
820  }
821  $this->db->rollback();
822  return -1 * $error;
823  } else {
824  $this->db->commit();
825  return 1;
826  }
827  }
828 
829 
837  public function approve($user = null, $notrigger = 0)
838  {
839  global $conf, $langs;
840  $error = 0;
841 
842  $checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type);
843 
844  if ($checkBalance > 0) {
845  $balance = $this->getCPforUser($this->fk_user, $this->fk_type);
846 
847  if ($balance < 0) {
848  $this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
849  return -1;
850  }
851  }
852 
853  // Update request
854  $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
855 
856  $sql .= " description= '".$this->db->escape($this->description)."',";
857 
858  if (!empty($this->date_debut)) {
859  $sql .= " date_debut = '".$this->db->idate($this->date_debut)."',";
860  } else {
861  $error++;
862  }
863  if (!empty($this->date_fin)) {
864  $sql .= " date_fin = '".$this->db->idate($this->date_fin)."',";
865  } else {
866  $error++;
867  }
868  $sql .= " halfday = ".((int) $this->halfday).",";
869  if (!empty($this->statut) && is_numeric($this->statut)) {
870  $sql .= " statut = ".((int) $this->statut).",";
871  } else {
872  $error++;
873  }
874  if (!empty($this->fk_validator)) {
875  $sql .= " fk_validator = ".((int) $this->fk_validator).",";
876  } else {
877  $error++;
878  }
879  if (!empty($this->date_valid)) {
880  $sql .= " date_valid = '".$this->db->idate($this->date_valid)."',";
881  } else {
882  $sql .= " date_valid = NULL,";
883  }
884  if (!empty($this->fk_user_valid)) {
885  $sql .= " fk_user_valid = ".((int) $this->fk_user_valid).",";
886  } else {
887  $sql .= " fk_user_valid = NULL,";
888  }
889  if (!empty($this->date_approval)) {
890  $sql .= " date_approval = '".$this->db->idate($this->date_approval)."',";
891  } else {
892  $sql .= " date_approval = NULL,";
893  }
894  if (!empty($this->fk_user_approve)) {
895  $sql .= " fk_user_approve = ".((int) $this->fk_user_approve).",";
896  } else {
897  $sql .= " fk_user_approve = NULL,";
898  }
899  if (!empty($this->date_refuse)) {
900  $sql .= " date_refuse = '".$this->db->idate($this->date_refuse)."',";
901  } else {
902  $sql .= " date_refuse = NULL,";
903  }
904  if (!empty($this->fk_user_refuse)) {
905  $sql .= " fk_user_refuse = ".((int) $this->fk_user_refuse).",";
906  } else {
907  $sql .= " fk_user_refuse = NULL,";
908  }
909  if (!empty($this->date_cancel)) {
910  $sql .= " date_cancel = '".$this->db->idate($this->date_cancel)."',";
911  } else {
912  $sql .= " date_cancel = NULL,";
913  }
914  if (!empty($this->fk_user_cancel)) {
915  $sql .= " fk_user_cancel = ".((int) $this->fk_user_cancel).",";
916  } else {
917  $sql .= " fk_user_cancel = NULL,";
918  }
919  if (!empty($this->detail_refuse)) {
920  $sql .= " detail_refuse = '".$this->db->escape($this->detail_refuse)."'";
921  } else {
922  $sql .= " detail_refuse = NULL";
923  }
924  $sql .= " WHERE rowid = ".((int) $this->id);
925 
926  $this->db->begin();
927 
928  dol_syslog(get_class($this)."::approve", LOG_DEBUG);
929  $resql = $this->db->query($sql);
930  if (!$resql) {
931  $error++; $this->errors[] = "Error ".$this->db->lasterror();
932  }
933 
934  if (!$error) {
935  if (!$notrigger) {
936  // Call trigger
937  $result = $this->call_trigger('HOLIDAY_APPROVE', $user);
938  if ($result < 0) {
939  $error++;
940  }
941  // End call triggers
942  }
943  }
944 
945  // Commit or rollback
946  if ($error) {
947  foreach ($this->errors as $errmsg) {
948  dol_syslog(get_class($this)."::approve ".$errmsg, LOG_ERR);
949  $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
950  }
951  $this->db->rollback();
952  return -1 * $error;
953  } else {
954  $this->db->commit();
955  return 1;
956  }
957  }
958 
966  public function update($user = null, $notrigger = 0)
967  {
968  global $conf, $langs;
969  $error = 0;
970 
971  $checkBalance = getDictionaryValue('c_holiday_types', 'block_if_negative', $this->fk_type);
972 
973  if ($checkBalance > 0 && $this->statut != self::STATUS_DRAFT) {
974  $balance = $this->getCPforUser($this->fk_user, $this->fk_type);
975 
976  if ($balance < 0) {
977  $this->error = 'LeaveRequestCreationBlockedBecauseBalanceIsNegative';
978  return -1;
979  }
980  }
981 
982  // Update request
983  $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET";
984 
985  $sql .= " description= '".$this->db->escape($this->description)."',";
986 
987  if (!empty($this->date_debut)) {
988  $sql .= " date_debut = '".$this->db->idate($this->date_debut)."',";
989  } else {
990  $error++;
991  }
992  if (!empty($this->date_fin)) {
993  $sql .= " date_fin = '".$this->db->idate($this->date_fin)."',";
994  } else {
995  $error++;
996  }
997  $sql .= " halfday = ".$this->halfday.",";
998  if (!empty($this->statut) && is_numeric($this->statut)) {
999  $sql .= " statut = ".$this->statut.",";
1000  } else {
1001  $error++;
1002  }
1003  if (!empty($this->fk_validator)) {
1004  $sql .= " fk_validator = '".$this->db->escape($this->fk_validator)."',";
1005  } else {
1006  $error++;
1007  }
1008  if (!empty($this->date_valid)) {
1009  $sql .= " date_valid = '".$this->db->idate($this->date_valid)."',";
1010  } else {
1011  $sql .= " date_valid = NULL,";
1012  }
1013  if (!empty($this->fk_user_valid)) {
1014  $sql .= " fk_user_valid = ".((int) $this->fk_user_valid).",";
1015  } else {
1016  $sql .= " fk_user_valid = NULL,";
1017  }
1018  if (!empty($this->date_approval)) {
1019  $sql .= " date_approval = '".$this->db->idate($this->date_approval)."',";
1020  } else {
1021  $sql .= " date_approval = NULL,";
1022  }
1023  if (!empty($this->fk_user_approve)) {
1024  $sql .= " fk_user_approve = ".((int) $this->fk_user_approve).",";
1025  } else {
1026  $sql .= " fk_user_approve = NULL,";
1027  }
1028  if (!empty($this->date_refuse)) {
1029  $sql .= " date_refuse = '".$this->db->idate($this->date_refuse)."',";
1030  } else {
1031  $sql .= " date_refuse = NULL,";
1032  }
1033  if (!empty($this->fk_user_refuse)) {
1034  $sql .= " fk_user_refuse = ".((int) $this->fk_user_refuse).",";
1035  } else {
1036  $sql .= " fk_user_refuse = NULL,";
1037  }
1038  if (!empty($this->date_cancel)) {
1039  $sql .= " date_cancel = '".$this->db->idate($this->date_cancel)."',";
1040  } else {
1041  $sql .= " date_cancel = NULL,";
1042  }
1043  if (!empty($this->fk_user_cancel)) {
1044  $sql .= " fk_user_cancel = ".((int) $this->fk_user_cancel).",";
1045  } else {
1046  $sql .= " fk_user_cancel = NULL,";
1047  }
1048  if (!empty($this->detail_refuse)) {
1049  $sql .= " detail_refuse = '".$this->db->escape($this->detail_refuse)."'";
1050  } else {
1051  $sql .= " detail_refuse = NULL";
1052  }
1053 
1054  $sql .= " WHERE rowid = ".((int) $this->id);
1055 
1056  $this->db->begin();
1057 
1058  dol_syslog(get_class($this)."::update", LOG_DEBUG);
1059  $resql = $this->db->query($sql);
1060  if (!$resql) {
1061  $error++; $this->errors[] = "Error ".$this->db->lasterror();
1062  }
1063 
1064  if (!$error) {
1065  if (!$notrigger) {
1066  // Call trigger
1067  $result = $this->call_trigger('HOLIDAY_MODIFY', $user);
1068  if ($result < 0) {
1069  $error++;
1070  }
1071  // End call triggers
1072  }
1073  }
1074 
1075  // Commit or rollback
1076  if ($error) {
1077  foreach ($this->errors as $errmsg) {
1078  dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
1079  $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1080  }
1081  $this->db->rollback();
1082  return -1 * $error;
1083  } else {
1084  $this->db->commit();
1085  return 1;
1086  }
1087  }
1088 
1089 
1097  public function delete($user, $notrigger = 0)
1098  {
1099  global $conf, $langs;
1100  $error = 0;
1101 
1102  $sql = "DELETE FROM ".MAIN_DB_PREFIX."holiday";
1103  $sql .= " WHERE rowid=".((int) $this->id);
1104 
1105  $this->db->begin();
1106 
1107  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1108  $resql = $this->db->query($sql);
1109  if (!$resql) {
1110  $error++; $this->errors[] = "Error ".$this->db->lasterror();
1111  }
1112 
1113  if (!$error) {
1114  if (!$notrigger) {
1115  // Call trigger
1116  $result = $this->call_trigger('HOLIDAY_DELETE', $user);
1117  if ($result < 0) {
1118  $error++;
1119  }
1120  // End call triggers
1121  }
1122  }
1123 
1124  // Commit or rollback
1125  if ($error) {
1126  foreach ($this->errors as $errmsg) {
1127  dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
1128  $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
1129  }
1130  $this->db->rollback();
1131  return -1 * $error;
1132  } else {
1133  $this->db->commit();
1134  return 1;
1135  }
1136  }
1137 
1151  public function verifDateHolidayCP($fk_user, $dateStart, $dateEnd, $halfday = 0)
1152  {
1153  $this->fetchByUser($fk_user, '', '');
1154 
1155  foreach ($this->holiday as $infos_CP) {
1156  if ($infos_CP['statut'] == Holiday::STATUS_CANCELED) {
1157  continue; // ignore not validated holidays
1158  }
1159  if ($infos_CP['statut'] == Holiday::STATUS_REFUSED) {
1160  continue; // ignore refused holidays
1161  }
1162  //var_dump("--");
1163  //var_dump("old: ".dol_print_date($infos_CP['date_debut'],'dayhour').' '.dol_print_date($infos_CP['date_fin'],'dayhour').' '.$infos_CP['halfday']);
1164  //var_dump("new: ".dol_print_date($dateStart,'dayhour').' '.dol_print_date($dateEnd,'dayhour').' '.$halfday);
1165 
1166  if ($halfday == 0) {
1167  if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1168  return false;
1169  }
1170  if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1171  return false;
1172  }
1173  } elseif ($halfday == -1) {
1174  // new start afternoon, new end afternoon
1175  if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1176  if ($dateStart < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
1177  return false;
1178  }
1179  }
1180  if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1181  if ($dateStart < $dateEnd) {
1182  return false;
1183  }
1184  if ($dateEnd < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
1185  return false;
1186  }
1187  }
1188  } elseif ($halfday == 1) {
1189  // new start morning, new end morning
1190  if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1191  if ($dateStart < $dateEnd) {
1192  return false;
1193  }
1194  if ($dateStart > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
1195  return false;
1196  }
1197  }
1198  if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1199  if ($dateEnd > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
1200  return false;
1201  }
1202  }
1203  } elseif ($halfday == 2) {
1204  // new start afternoon, new end morning
1205  if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) {
1206  if ($dateStart < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) {
1207  return false;
1208  }
1209  }
1210  if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) {
1211  if ($dateEnd > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) {
1212  return false;
1213  }
1214  }
1215  } else {
1216  dol_print_error('', 'Bad value of parameter halfday when calling function verifDateHolidayCP');
1217  }
1218  }
1219 
1220  return true;
1221  }
1222 
1223 
1233  public function verifDateHolidayForTimestamp($fk_user, $timestamp, $status = '-1')
1234  {
1235  global $langs, $conf;
1236 
1237  $isavailablemorning = true;
1238  $isavailableafternoon = true;
1239 
1240  // Check into leave requests
1241  $sql = "SELECT cp.rowid, cp.date_debut as date_start, cp.date_fin as date_end, cp.halfday, cp.statut";
1242  $sql .= " FROM ".MAIN_DB_PREFIX."holiday as cp";
1243  $sql .= " WHERE cp.entity IN (".getEntity('holiday').")";
1244  $sql .= " AND cp.fk_user = ".(int) $fk_user;
1245  $sql .= " AND cp.date_debut <= '".$this->db->idate($timestamp)."' AND cp.date_fin >= '".$this->db->idate($timestamp)."'";
1246  if ($status != '-1') {
1247  $sql .= " AND cp.statut IN (".$this->db->sanitize($status).")";
1248  }
1249 
1250  $resql = $this->db->query($sql);
1251  if ($resql) {
1252  $num_rows = $this->db->num_rows($resql); // Note, we can have 2 records if on is morning and the other one is afternoon
1253  if ($num_rows > 0) {
1254  $arrayofrecord = array();
1255  $i = 0;
1256  while ($i < $num_rows) {
1257  $obj = $this->db->fetch_object($resql);
1258 
1259  // Note: $obj->halfday is 0:Full days, 2:Sart afternoon end morning, -1:Start afternoon, 1:End morning
1260  $arrayofrecord[$obj->rowid] = array('date_start'=>$this->db->jdate($obj->date_start), 'date_end'=>$this->db->jdate($obj->date_end), 'halfday'=>$obj->halfday);
1261  $i++;
1262  }
1263 
1264  // We found a record, user is on holiday by default, so is not available is true.
1265  $isavailablemorning = true;
1266  foreach ($arrayofrecord as $record) {
1267  if ($timestamp == $record['date_start'] && $record['halfday'] == 2) {
1268  continue;
1269  }
1270  if ($timestamp == $record['date_start'] && $record['halfday'] == -1) {
1271  continue;
1272  }
1273  $isavailablemorning = false;
1274  break;
1275  }
1276  $isavailableafternoon = true;
1277  foreach ($arrayofrecord as $record) {
1278  if ($timestamp == $record['date_end'] && $record['halfday'] == 2) {
1279  continue;
1280  }
1281  if ($timestamp == $record['date_end'] && $record['halfday'] == 1) {
1282  continue;
1283  }
1284  $isavailableafternoon = false;
1285  break;
1286  }
1287  }
1288  } else {
1289  dol_print_error($this->db);
1290  }
1291 
1292  $result = array('morning'=>$isavailablemorning, 'afternoon'=>$isavailableafternoon);
1293  if (!$isavailablemorning) {
1294  $result['morning_reason'] = 'leave_request';
1295  }
1296  if (!$isavailableafternoon) {
1297  $result['afternoon_reason'] = 'leave_request';
1298  }
1299  return $result;
1300  }
1301 
1309  public function getTooltipContentArray($params)
1310  {
1311  global $conf, $langs;
1312 
1313  $langs->load('holiday');
1314  $nofetch = !empty($params['nofetch']);
1315 
1316  $datas = array();
1317  $datas['picto'] = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Holiday").'</u>';
1318  if (isset($this->statut)) {
1319  $datas['picto'] .= ' '.$this->getLibStatut(5);
1320  }
1321  $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
1322  // show type for this record only in ajax to not overload lists
1323  if (!$nofetch && !empty($this->fk_type)) {
1324  $typeleaves = $this->getTypes(1, -1);
1325  $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']);
1326  $datas['type'] = '<br><b>'.$langs->trans("Type") . ':</b> ' . (empty($labeltoshow) ? $langs->trans("TypeWasDisabledOrRemoved", $this->fk_type) : $labeltoshow);
1327  }
1328  if (isset($this->halfday) && !empty($this->date_debut) && !empty($this->date_fin)) {
1329  $listhalfday = array(
1330  'morning' => $langs->trans("Morning"),
1331  "afternoon" => $langs->trans("Afternoon")
1332  );
1333  $starthalfday = ($this->halfday == -1 || $this->halfday == 2) ? 'afternoon' : 'morning';
1334  $endhalfday = ($this->halfday == 1 || $this->halfday == 2) ? 'morning' : 'afternoon';
1335  $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>';
1336  $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>';
1337  }
1338 
1339 
1340  return $datas;
1341  }
1342 
1351  public function getNomUrl($withpicto = 0, $save_lastsearch_value = -1, $notooltip = 0)
1352  {
1353  global $langs, $hookmanager;
1354 
1355  $result = '';
1356 
1357  $params = [
1358  'id' => $this->id,
1359  'objecttype' => $this->element,
1360  'nofetch' => 1,
1361  ];
1362  $classfortooltip = 'classfortooltip';
1363  $dataparams = '';
1364  if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1365  $classfortooltip = 'classforajaxtooltip';
1366  $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1367  $label = '';
1368  } else {
1369  $label = implode($this->getTooltipContentArray($params));
1370  }
1371 
1372  $url = DOL_URL_ROOT.'/holiday/card.php?id='.$this->id;
1373 
1374  //if ($option != 'nolink')
1375  //{
1376  // Add param to save lastsearch_values or not
1377  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1378  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1379  $add_save_lastsearch_values = 1;
1380  }
1381  if ($add_save_lastsearch_values) {
1382  $url .= '&save_lastsearch_values=1';
1383  }
1384  //}
1385  $linkstart = '<a href="'.$url.'"';
1386  $linkstart .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
1387  $linkstart .= $dataparams.' class="'.$classfortooltip.'">';
1388  $linkend = '</a>';
1389 
1390  $result .= $linkstart;
1391  if ($withpicto) {
1392  $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1);
1393  }
1394  if ($withpicto != 2) {
1395  $result .= $this->ref;
1396  }
1397  $result .= $linkend;
1398  global $action;
1399  $hookmanager->initHooks(array($this->element . 'dao'));
1400  $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
1401  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1402  if ($reshook > 0) {
1403  $result = $hookmanager->resPrint;
1404  } else {
1405  $result .= $hookmanager->resPrint;
1406  }
1407  return $result;
1408  }
1409 
1410 
1417  public function getLibStatut($mode = 0)
1418  {
1419  return $this->LibStatut($this->statut, $mode, $this->date_debut);
1420  }
1421 
1422  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1431  public function LibStatut($status, $mode = 0, $startdate = '')
1432  {
1433  // phpcs:enable
1434  global $langs;
1435 
1436  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
1437  global $langs;
1438  //$langs->load("mymodule");
1439  $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP');
1440  $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP');
1441  $this->labelStatus[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP');
1442  $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP');
1443  $this->labelStatus[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP');
1444  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP');
1445  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP');
1446  $this->labelStatusShort[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP');
1447  $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP');
1448  $this->labelStatusShort[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP');
1449  }
1450 
1451  $params = array();
1452  $statusType = 'status6';
1453  if (!empty($startdate) && $startdate >= dol_now()) { // If not yet passed, we use a green "in live" color
1454  $statusType = 'status4';
1455  $params = array('tooltip'=>$this->labelStatus[$status].' - '.$langs->trans("Forthcoming"));
1456  }
1457  if ($status == self::STATUS_DRAFT) {
1458  $statusType = 'status0';
1459  }
1460  if ($status == self::STATUS_VALIDATED) {
1461  $statusType = 'status1';
1462  }
1463  if ($status == self::STATUS_CANCELED) {
1464  $statusType = 'status5';
1465  }
1466  if ($status == self::STATUS_REFUSED) {
1467  $statusType = 'status5';
1468  }
1469 
1470  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode, '', $params);
1471  }
1472 
1473 
1482  public function selectStatutCP($selected = '', $htmlname = 'select_statut', $morecss = 'minwidth125')
1483  {
1484  global $langs;
1485 
1486  // Liste des statuts
1487  $name = array('DraftCP', 'ToReviewCP', 'ApprovedCP', 'CancelCP', 'RefuseCP');
1488  $nb = count($name) + 1;
1489 
1490  // Select HTML
1491  $out = '<select name="'.$htmlname.'" id="'.$htmlname.'" class="flat'.($morecss ? ' '.$morecss : '').'">'."\n";
1492  $out .= '<option value="-1">&nbsp;</option>'."\n";
1493 
1494  // Boucle des statuts
1495  for ($i = 1; $i < $nb; $i++) {
1496  if ($i == $selected) {
1497  $out .= '<option value="'.$i.'" selected>'.$langs->trans($name[$i - 1]).'</option>'."\n";
1498  } else {
1499  $out .= '<option value="'.$i.'">'.$langs->trans($name[$i - 1]).'</option>'."\n";
1500  }
1501  }
1502 
1503  $out .= '</select>'."\n";
1504 
1505  $showempty= 0;
1506  $out .= ajax_combobox($htmlname, array(), 0, 0, 'resolve', ($showempty < 0 ? (string) $showempty : '-1'), $morecss);
1507 
1508  return $out;
1509  }
1510 
1518  public function updateConfCP($name, $value)
1519  {
1520 
1521  $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
1522  $sql .= " value = '".$this->db->escape($value)."'";
1523  $sql .= " WHERE name = '".$this->db->escape($name)."'";
1524 
1525  dol_syslog(get_class($this).'::updateConfCP name='.$name, LOG_DEBUG);
1526  $result = $this->db->query($sql);
1527  if ($result) {
1528  return true;
1529  }
1530 
1531  return false;
1532  }
1533 
1542  public function getConfCP($name, $createifnotfound = '')
1543  {
1544  $sql = "SELECT value";
1545  $sql .= " FROM ".MAIN_DB_PREFIX."holiday_config";
1546  $sql .= " WHERE name = '".$this->db->escape($name)."'";
1547 
1548  dol_syslog(get_class($this).'::getConfCP name='.$name.' createifnotfound='.$createifnotfound, LOG_DEBUG);
1549  $result = $this->db->query($sql);
1550 
1551  if ($result) {
1552  $obj = $this->db->fetch_object($result);
1553  // Return value
1554  if (empty($obj)) {
1555  if ($createifnotfound) {
1556  $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_config(name, value)";
1557  $sql .= " VALUES('".$this->db->escape($name)."', '".$this->db->escape($createifnotfound)."')";
1558  $result = $this->db->query($sql);
1559  if ($result) {
1560  return $createifnotfound;
1561  } else {
1562  $this->error = $this->db->lasterror();
1563  return -2;
1564  }
1565  } else {
1566  return '';
1567  }
1568  } else {
1569  return $obj->value;
1570  }
1571  } else {
1572  // Erreur SQL
1573  $this->error = $this->db->lasterror();
1574  return -1;
1575  }
1576  }
1577 
1586  public function updateSoldeCP($userID = '', $nbHoliday = '', $fk_type = '')
1587  {
1588  global $user, $langs;
1589 
1590  $error = 0;
1591 
1592  if (empty($userID) && empty($nbHoliday) && empty($fk_type)) {
1593  $langs->load("holiday");
1594 
1595  // Si mise à jour pour tout le monde en début de mois
1596  $now = dol_now();
1597 
1598  $month = date('m', $now);
1599  $newdateforlastupdate = dol_print_date($now, '%Y%m%d%H%M%S');
1600 
1601  // Get month of last update
1602  $lastUpdate = $this->getConfCP('lastUpdate', $newdateforlastupdate);
1603  $monthLastUpdate = $lastUpdate[4].$lastUpdate[5];
1604  //print 'month: '.$month.' lastUpdate:'.$lastUpdate.' monthLastUpdate:'.$monthLastUpdate;exit;
1605 
1606  // 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.
1607  if ($month != $monthLastUpdate) {
1608  $this->db->begin();
1609 
1610  $users = $this->fetchUsers(false, false, ' AND u.statut > 0');
1611  $nbUser = count($users);
1612 
1613  $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
1614  $sql .= " value = '".$this->db->escape($newdateforlastupdate)."'";
1615  $sql .= " WHERE name = 'lastUpdate'";
1616  $result = $this->db->query($sql);
1617 
1618  $typeleaves = $this->getTypes(1, 1);
1619 
1620  // Update each user counter
1621  foreach ($users as $userCounter) {
1622  $nbDaysToAdd = (isset($typeleaves[$userCounter['type']]['newbymonth']) ? $typeleaves[$userCounter['type']]['newbymonth'] : 0);
1623  if (empty($nbDaysToAdd)) {
1624  continue;
1625  }
1626 
1627  dol_syslog("We update leave type id ".$userCounter['type']." for user id ".$userCounter['rowid'], LOG_DEBUG);
1628 
1629  $nowHoliday = $userCounter['nb_holiday'];
1630  $newSolde = $nowHoliday + $nbDaysToAdd;
1631 
1632  // We add a log for each user
1633  $this->addLogCP($user->id, $userCounter['rowid'], $langs->trans('HolidaysMonthlyUpdate'), $newSolde, $userCounter['type']);
1634 
1635  $result = $this->updateSoldeCP($userCounter['rowid'], $newSolde, $userCounter['type']);
1636 
1637  if ($result < 0) {
1638  $error++;
1639  break;
1640  }
1641  }
1642 
1643  if (!$error) {
1644  $this->db->commit();
1645  return 1;
1646  } else {
1647  $this->db->rollback();
1648  return -1;
1649  }
1650  }
1651 
1652  return 0;
1653  } else {
1654  // Mise à jour pour un utilisateur
1655  $nbHoliday = price2num($nbHoliday, 5);
1656 
1657  $sql = "SELECT nb_holiday FROM ".MAIN_DB_PREFIX."holiday_users";
1658  $sql .= " WHERE fk_user = ".(int) $userID." AND fk_type = ".(int) $fk_type;
1659  $resql = $this->db->query($sql);
1660  if ($resql) {
1661  $num = $this->db->num_rows($resql);
1662 
1663  if ($num > 0) {
1664  // Update for user
1665  $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_users SET";
1666  $sql .= " nb_holiday = ".((float) $nbHoliday);
1667  $sql .= " WHERE fk_user = ".(int) $userID." AND fk_type = ".(int) $fk_type;
1668  $result = $this->db->query($sql);
1669  if (!$result) {
1670  $error++;
1671  $this->errors[] = $this->db->lasterror();
1672  }
1673  } else {
1674  // Insert for user
1675  $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users(nb_holiday, fk_user, fk_type) VALUES (";
1676  $sql .= ((float) $nbHoliday);
1677  $sql .= ", ".(int) $userID.", ".(int) $fk_type.")";
1678  $result = $this->db->query($sql);
1679  if (!$result) {
1680  $error++;
1681  $this->errors[] = $this->db->lasterror();
1682  }
1683  }
1684  } else {
1685  $this->errors[] = $this->db->lasterror();
1686  $error++;
1687  }
1688 
1689  if (!$error) {
1690  return 1;
1691  } else {
1692  return -1;
1693  }
1694  }
1695  }
1696 
1704  public function createCPusers($single = false, $userid = '')
1705  {
1706  // do we have to add balance for all users ?
1707  if (!$single) {
1708  dol_syslog(get_class($this).'::createCPusers');
1709  $arrayofusers = $this->fetchUsers(false, true);
1710 
1711  foreach ($arrayofusers as $users) {
1712  $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users";
1713  $sql .= " (fk_user, nb_holiday)";
1714  $sql .= " VALUES (".((int) $users['rowid'])."', '0')";
1715 
1716  $resql = $this->db->query($sql);
1717  if (!$resql) {
1718  dol_print_error($this->db);
1719  }
1720  }
1721  } else {
1722  $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users";
1723  $sql .= " (fk_user, nb_holiday)";
1724  $sql .= " VALUES (".((int) $userid)."', '0')";
1725 
1726  $resql = $this->db->query($sql);
1727  if (!$resql) {
1728  dol_print_error($this->db);
1729  }
1730  }
1731  }
1732 
1740  public function getCPforUser($user_id, $fk_type = 0)
1741  {
1742  $sql = "SELECT nb_holiday";
1743  $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users";
1744  $sql .= " WHERE fk_user = ".(int) $user_id;
1745  if ($fk_type > 0) {
1746  $sql .= " AND fk_type = ".(int) $fk_type;
1747  }
1748 
1749  dol_syslog(get_class($this).'::getCPforUser user_id='.$user_id.' type_id='.$fk_type, LOG_DEBUG);
1750  $result = $this->db->query($sql);
1751  if ($result) {
1752  $obj = $this->db->fetch_object($result);
1753  //return number_format($obj->nb_holiday,2);
1754  if ($obj) {
1755  return $obj->nb_holiday;
1756  } else {
1757  return null;
1758  }
1759  } else {
1760  return null;
1761  }
1762  }
1763 
1772  public function fetchUsers($stringlist = true, $type = true, $filters = '')
1773  {
1774  global $conf;
1775 
1776  dol_syslog(get_class($this)."::fetchUsers", LOG_DEBUG);
1777 
1778  if ($stringlist) {
1779  if ($type) {
1780  // If user of Dolibarr
1781  $sql = "SELECT";
1782  if (isModEnabled('multicompany') && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
1783  $sql .= " DISTINCT";
1784  }
1785  $sql .= " u.rowid";
1786  $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
1787 
1788  if (isModEnabled('multicompany') && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
1789  $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
1790  $sql .= " WHERE ((ug.fk_user = u.rowid";
1791  $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
1792  $sql .= " OR u.entity = 0)"; // Show always superadmin
1793  } else {
1794  $sql .= " WHERE u.entity IN (".getEntity('user').")";
1795  }
1796  $sql .= " AND u.statut > 0";
1797  $sql .= " AND u.employee = 1"; // We only want employee users for holidays
1798  if ($filters) {
1799  $sql .= $filters;
1800  }
1801 
1802  $resql = $this->db->query($sql);
1803 
1804  // Si pas d'erreur SQL
1805  if ($resql) {
1806  $i = 0;
1807  $num = $this->db->num_rows($resql);
1808  $stringlist = '';
1809 
1810  // Boucles du listage des utilisateurs
1811  while ($i < $num) {
1812  $obj = $this->db->fetch_object($resql);
1813 
1814  if ($i == 0) {
1815  $stringlist .= $obj->rowid;
1816  } else {
1817  $stringlist .= ', '.$obj->rowid;
1818  }
1819 
1820  $i++;
1821  }
1822  // Retoune le tableau des utilisateurs
1823  return $stringlist;
1824  } else {
1825  // Erreur SQL
1826  $this->error = "Error ".$this->db->lasterror();
1827  return -1;
1828  }
1829  } else {
1830  // We want only list of vacation balance for user ids
1831  $sql = "SELECT DISTINCT cpu.fk_user";
1832  $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u";
1833  $sql .= " WHERE cpu.fk_user = u.rowid";
1834  if ($filters) {
1835  $sql .= $filters;
1836  }
1837 
1838  $resql = $this->db->query($sql);
1839 
1840  // Si pas d'erreur SQL
1841  if ($resql) {
1842  $i = 0;
1843  $num = $this->db->num_rows($resql);
1844  $stringlist = '';
1845 
1846  // Boucles du listage des utilisateurs
1847  while ($i < $num) {
1848  $obj = $this->db->fetch_object($resql);
1849 
1850  if ($i == 0) {
1851  $stringlist .= $obj->fk_user;
1852  } else {
1853  $stringlist .= ', '.$obj->fk_user;
1854  }
1855 
1856  $i++;
1857  }
1858  // Retoune le tableau des utilisateurs
1859  return $stringlist;
1860  } else {
1861  // Erreur SQL
1862  $this->error = "Error ".$this->db->lasterror();
1863  return -1;
1864  }
1865  }
1866  } else {
1867  // Si faux donc return array
1868  // List for Dolibarr users
1869  if ($type) {
1870  // If we need users of Dolibarr
1871  $sql = "SELECT";
1872  if (isModEnabled('multicompany') && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
1873  $sql .= " DISTINCT";
1874  }
1875  $sql .= " u.rowid, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut, u.fk_user";
1876  $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
1877 
1878  if (isModEnabled('multicompany') && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
1879  $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
1880  $sql .= " WHERE ((ug.fk_user = u.rowid";
1881  $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
1882  $sql .= " OR u.entity = 0)"; // Show always superadmin
1883  } else {
1884  $sql .= " WHERE u.entity IN (".getEntity('user').")";
1885  }
1886 
1887  $sql .= " AND u.statut > 0";
1888  $sql .= " AND u.employee = 1"; // We only want employee users for holidays
1889  if ($filters) {
1890  $sql .= $filters;
1891  }
1892 
1893  $resql = $this->db->query($sql);
1894 
1895  // Si pas d'erreur SQL
1896  if ($resql) {
1897  $i = 0;
1898  $tab_result = $this->holiday;
1899  $num = $this->db->num_rows($resql);
1900 
1901  // Boucles du listage des utilisateurs
1902  while ($i < $num) {
1903  $obj = $this->db->fetch_object($resql);
1904 
1905  $tab_result[$i]['rowid'] = $obj->rowid; // rowid of user
1906  $tab_result[$i]['id'] = $obj->rowid; // id of user
1907  $tab_result[$i]['name'] = $obj->lastname; // deprecated
1908  $tab_result[$i]['lastname'] = $obj->lastname;
1909  $tab_result[$i]['firstname'] = $obj->firstname;
1910  $tab_result[$i]['gender'] = $obj->gender;
1911  $tab_result[$i]['status'] = $obj->statut;
1912  $tab_result[$i]['employee'] = $obj->employee;
1913  $tab_result[$i]['photo'] = $obj->photo;
1914  $tab_result[$i]['fk_user'] = $obj->fk_user; // rowid of manager
1915  //$tab_result[$i]['type'] = $obj->type;
1916  //$tab_result[$i]['nb_holiday'] = $obj->nb_holiday;
1917 
1918  $i++;
1919  }
1920  // Retoune le tableau des utilisateurs
1921  return $tab_result;
1922  } else {
1923  // Erreur SQL
1924  $this->errors[] = "Error ".$this->db->lasterror();
1925  return -1;
1926  }
1927  } else {
1928  // List of vacation balance users
1929  $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";
1930  $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u";
1931  $sql .= " WHERE cpu.fk_user = u.rowid";
1932  if ($filters) {
1933  $sql .= $filters;
1934  }
1935 
1936  $resql = $this->db->query($sql);
1937 
1938  // Si pas d'erreur SQL
1939  if ($resql) {
1940  $i = 0;
1941  $tab_result = $this->holiday;
1942  $num = $this->db->num_rows($resql);
1943 
1944  // Boucles du listage des utilisateurs
1945  while ($i < $num) {
1946  $obj = $this->db->fetch_object($resql);
1947 
1948  $tab_result[$i]['rowid'] = $obj->rowid; // rowid of user
1949  $tab_result[$i]['id'] = $obj->rowid; // id of user
1950  $tab_result[$i]['name'] = $obj->lastname; // deprecated
1951  $tab_result[$i]['lastname'] = $obj->lastname;
1952  $tab_result[$i]['firstname'] = $obj->firstname;
1953  $tab_result[$i]['gender'] = $obj->gender;
1954  $tab_result[$i]['status'] = $obj->statut;
1955  $tab_result[$i]['employee'] = $obj->employee;
1956  $tab_result[$i]['photo'] = $obj->photo;
1957  $tab_result[$i]['fk_user'] = $obj->fk_user; // rowid of manager
1958 
1959  $tab_result[$i]['type'] = $obj->fk_type;
1960  $tab_result[$i]['nb_holiday'] = $obj->nb_holiday;
1961 
1962  $i++;
1963  }
1964  // Retoune le tableau des utilisateurs
1965  return $tab_result;
1966  } else {
1967  // Erreur SQL
1968  $this->error = "Error ".$this->db->lasterror();
1969  return -1;
1970  }
1971  }
1972  }
1973  }
1974 
1975 
1976  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1984  {
1985  // phpcs:enable
1986  $users_validator = array();
1987 
1988  $sql = "SELECT DISTINCT ur.fk_user";
1989  $sql .= " FROM ".MAIN_DB_PREFIX."user_rights as ur, ".MAIN_DB_PREFIX."rights_def as rd";
1990  $sql .= " WHERE ur.fk_id = rd.id and rd.module = 'holiday' AND rd.perms = 'approve'"; // Permission 'Approve';
1991  $sql .= "UNION";
1992  $sql .= " SELECT DISTINCT ugu.fk_user";
1993  $sql .= " FROM ".MAIN_DB_PREFIX."usergroup_user as ugu, ".MAIN_DB_PREFIX."usergroup_rights as ur, ".MAIN_DB_PREFIX."rights_def as rd";
1994  $sql .= " WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'holiday' AND rd.perms = 'approve'"; // Permission 'Approve';
1995  //print $sql;
1996 
1997  dol_syslog(get_class($this)."::fetch_users_approver_holiday sql=".$sql);
1998  $result = $this->db->query($sql);
1999  if ($result) {
2000  $num_rows = $this->db->num_rows($result); $i = 0;
2001  while ($i < $num_rows) {
2002  $objp = $this->db->fetch_object($result);
2003  array_push($users_validator, $objp->fk_user);
2004  $i++;
2005  }
2006  return $users_validator;
2007  } else {
2008  $this->error = $this->db->lasterror();
2009  dol_syslog(get_class($this)."::fetch_users_approver_holiday Error ".$this->error, LOG_ERR);
2010  return -1;
2011  }
2012  }
2013 
2014 
2020  public function countActiveUsers()
2021  {
2022  $sql = "SELECT count(u.rowid) as compteur";
2023  $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
2024  $sql .= " WHERE u.statut > 0";
2025 
2026  $result = $this->db->query($sql);
2027  $objet = $this->db->fetch_object($result);
2028 
2029  return $objet->compteur;
2030  }
2036  public function countActiveUsersWithoutCP()
2037  {
2038 
2039  $sql = "SELECT count(u.rowid) as compteur";
2040  $sql .= " FROM ".MAIN_DB_PREFIX."user as u LEFT OUTER JOIN ".MAIN_DB_PREFIX."holiday_users hu ON (hu.fk_user=u.rowid)";
2041  $sql .= " WHERE u.statut > 0 AND hu.fk_user IS NULL";
2042 
2043  $result = $this->db->query($sql);
2044  $objet = $this->db->fetch_object($result);
2045 
2046  return $objet->compteur;
2047  }
2048 
2056  public function verifNbUsers($userDolibarrWithoutCP, $userCP)
2057  {
2058  if (empty($userCP)) {
2059  $userCP = 0;
2060  }
2061  dol_syslog(get_class($this).'::verifNbUsers userDolibarr='.$userDolibarrWithoutCP.' userCP='.$userCP);
2062  return 1;
2063  }
2064 
2065 
2076  public function addLogCP($fk_user_action, $fk_user_update, $label, $new_solde, $fk_type)
2077  {
2078  global $conf, $langs;
2079 
2080  $error = 0;
2081 
2082  $prev_solde = price2num($this->getCPforUser($fk_user_update, $fk_type), 5);
2083  $new_solde = price2num($new_solde, 5);
2084  //print "$prev_solde == $new_solde";
2085 
2086  if ($prev_solde == $new_solde) {
2087  return 0;
2088  }
2089 
2090  $this->db->begin();
2091 
2092  // Insert request
2093  $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_logs (";
2094  $sql .= "date_action,";
2095  $sql .= "fk_user_action,";
2096  $sql .= "fk_user_update,";
2097  $sql .= "type_action,";
2098  $sql .= "prev_solde,";
2099  $sql .= "new_solde,";
2100  $sql .= "fk_type";
2101  $sql .= ") VALUES (";
2102  $sql .= " '".$this->db->idate(dol_now())."',";
2103  $sql .= " ".((int) $fk_user_action).",";
2104  $sql .= " ".((int) $fk_user_update).",";
2105  $sql .= " '".$this->db->escape($label)."',";
2106  $sql .= " ".((float) $prev_solde).",";
2107  $sql .= " ".((float) $new_solde).",";
2108  $sql .= " ".((int) $fk_type);
2109  $sql .= ")";
2110 
2111  $resql = $this->db->query($sql);
2112  if (!$resql) {
2113  $error++; $this->errors[] = "Error ".$this->db->lasterror();
2114  }
2115 
2116  if (!$error) {
2117  $this->optRowid = $this->db->last_insert_id(MAIN_DB_PREFIX."holiday_logs");
2118  }
2119 
2120  // Commit or rollback
2121  if ($error) {
2122  foreach ($this->errors as $errmsg) {
2123  dol_syslog(get_class($this)."::addLogCP ".$errmsg, LOG_ERR);
2124  $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
2125  }
2126  $this->db->rollback();
2127  return -1 * $error;
2128  } else {
2129  $this->db->commit();
2130  return $this->optRowid;
2131  }
2132  }
2133 
2141  public function fetchLog($order, $filter)
2142  {
2143  $sql = "SELECT";
2144  $sql .= " cpl.rowid,";
2145  $sql .= " cpl.date_action,";
2146  $sql .= " cpl.fk_user_action,";
2147  $sql .= " cpl.fk_user_update,";
2148  $sql .= " cpl.type_action,";
2149  $sql .= " cpl.prev_solde,";
2150  $sql .= " cpl.new_solde,";
2151  $sql .= " cpl.fk_type";
2152  $sql .= " FROM ".MAIN_DB_PREFIX."holiday_logs as cpl";
2153  $sql .= " WHERE cpl.rowid > 0"; // To avoid error with other search and criteria
2154 
2155  // Filtrage de séléction
2156  if (!empty($filter)) {
2157  $sql .= " ".$filter;
2158  }
2159 
2160  // Ordre d'affichage
2161  if (!empty($order)) {
2162  $sql .= " ".$order;
2163  }
2164 
2165  dol_syslog(get_class($this)."::fetchLog", LOG_DEBUG);
2166  $resql = $this->db->query($sql);
2167 
2168  // Si pas d'erreur SQL
2169  if ($resql) {
2170  $i = 0;
2171  $tab_result = $this->logs;
2172  $num = $this->db->num_rows($resql);
2173 
2174  // Si pas d'enregistrement
2175  if (!$num) {
2176  return 2;
2177  }
2178 
2179  // On liste les résultats et on les ajoutent dans le tableau
2180  while ($i < $num) {
2181  $obj = $this->db->fetch_object($resql);
2182 
2183  $tab_result[$i]['rowid'] = $obj->rowid;
2184  $tab_result[$i]['id'] = $obj->rowid;
2185  $tab_result[$i]['date_action'] = $obj->date_action;
2186  $tab_result[$i]['fk_user_action'] = $obj->fk_user_action;
2187  $tab_result[$i]['fk_user_update'] = $obj->fk_user_update;
2188  $tab_result[$i]['type_action'] = $obj->type_action;
2189  $tab_result[$i]['prev_solde'] = $obj->prev_solde;
2190  $tab_result[$i]['new_solde'] = $obj->new_solde;
2191  $tab_result[$i]['fk_type'] = $obj->fk_type;
2192 
2193  $i++;
2194  }
2195  // Retourne 1 et ajoute le tableau à la variable
2196  $this->logs = $tab_result;
2197  return 1;
2198  } else {
2199  // Erreur SQL
2200  $this->error = "Error ".$this->db->lasterror();
2201  return -1;
2202  }
2203  }
2204 
2205 
2213  public function getTypes($active = -1, $affect = -1)
2214  {
2215  global $mysoc;
2216 
2217  $sql = "SELECT rowid, code, label, affect, delay, newbymonth";
2218  $sql .= " FROM ".MAIN_DB_PREFIX."c_holiday_types";
2219  $sql .= " WHERE (fk_country IS NULL OR fk_country = ".((int) $mysoc->country_id).')';
2220  if ($active >= 0) {
2221  $sql .= " AND active = ".((int) $active);
2222  }
2223  if ($affect >= 0) {
2224  $sql .= " AND affect = ".((int) $affect);
2225  }
2226  $sql .= " ORDER BY sortorder";
2227 
2228  $result = $this->db->query($sql);
2229  if ($result) {
2230  $num = $this->db->num_rows($result);
2231  if ($num) {
2232  while ($obj = $this->db->fetch_object($result)) {
2233  $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);
2234  }
2235 
2236  return $types;
2237  }
2238  } else {
2239  dol_print_error($this->db);
2240  }
2241 
2242  return array();
2243  }
2244 
2245 
2252  public function info($id)
2253  {
2254  global $conf;
2255 
2256  $sql = "SELECT f.rowid, f.statut as status,";
2257  $sql .= " f.date_create as datec,";
2258  $sql .= " f.tms as date_modification,";
2259  $sql .= " f.date_valid as datev,";
2260  $sql .= " f.date_approval as datea,";
2261  $sql .= " f.date_refuse as dater,";
2262  $sql .= " f.fk_user_create as fk_user_creation,";
2263  $sql .= " f.fk_user_modif as fk_user_modification,";
2264  $sql .= " f.fk_user_valid as fk_user_validation,";
2265  $sql .= " f.fk_user_approve as fk_user_approval_done,";
2266  $sql .= " f.fk_validator as fk_user_approval_expected,";
2267  $sql .= " f.fk_user_refuse as fk_user_refuse";
2268  $sql .= " FROM ".MAIN_DB_PREFIX."holiday as f";
2269  $sql .= " WHERE f.rowid = ".((int) $id);
2270  $sql .= " AND f.entity = ".$conf->entity;
2271 
2272  $resql = $this->db->query($sql);
2273  if ($resql) {
2274  if ($this->db->num_rows($resql)) {
2275  $obj = $this->db->fetch_object($resql);
2276 
2277  $this->id = $obj->rowid;
2278 
2279  $this->date_creation = $this->db->jdate($obj->datec);
2280  $this->date_modification = $this->db->jdate($obj->date_modification);
2281  $this->date_validation = $this->db->jdate($obj->datev);
2282  $this->date_approval = $this->db->jdate($obj->datea);
2283 
2284  if (!empty($obj->fk_user_creation)) {
2285  $cuser = new User($this->db);
2286  $cuser->fetch($obj->fk_user_creation);
2287  $this->user_creation = $cuser;
2288  }
2289  if (!empty($obj->fk_user_valid)) {
2290  $vuser = new User($this->db);
2291  $vuser->fetch($obj->fk_user_valid);
2292  $this->user_validation = $vuser;
2293  }
2294  if (!empty($obj->fk_user_modification)) {
2295  $muser = new User($this->db);
2296  $muser->fetch($obj->fk_user_modification);
2297  $this->user_modification = $muser;
2298  }
2299 
2300  if ($obj->status == Holiday::STATUS_APPROVED || $obj->status == Holiday::STATUS_CANCELED) {
2301  if ($obj->fk_user_approval_done) {
2302  $auser = new User($this->db);
2303  $auser->fetch($obj->fk_user_approval_done);
2304  $this->user_approve = $auser;
2305  }
2306  }
2307  }
2308  $this->db->free($resql);
2309  } else {
2310  dol_print_error($this->db);
2311  }
2312  }
2313 
2314 
2322  public function initAsSpecimen()
2323  {
2324  global $user, $langs;
2325 
2326  // Initialise parameters
2327  $this->id = 0;
2328  $this->specimen = 1;
2329 
2330  $this->fk_user = $user->id;
2331  $this->description = 'SPECIMEN description';
2332  $this->date_debut = dol_now();
2333  $this->date_fin = dol_now() + (24 * 3600);
2334  $this->date_valid = dol_now();
2335  $this->fk_validator = $user->id;
2336  $this->halfday = 0;
2337  $this->fk_type = 1;
2338  $this->statut = Holiday::STATUS_VALIDATED;
2339  }
2340 
2341  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2347  public function load_state_board()
2348  {
2349  // phpcs:enable
2350  global $user;
2351 
2352  $this->nb = array();
2353 
2354  $sql = "SELECT count(h.rowid) as nb";
2355  $sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
2356  $sql .= " WHERE h.statut > 1";
2357  $sql .= " AND h.entity IN (".getEntity('holiday').")";
2358  if (empty($user->rights->expensereport->readall)) {
2359  $userchildids = $user->getAllChildIds(1);
2360  $sql .= " AND (h.fk_user IN (".$this->db->sanitize(join(',', $userchildids)).")";
2361  $sql .= " OR h.fk_validator IN (".$this->db->sanitize(join(',', $userchildids))."))";
2362  }
2363 
2364  $resql = $this->db->query($sql);
2365  if ($resql) {
2366  while ($obj = $this->db->fetch_object($resql)) {
2367  $this->nb["holidays"] = $obj->nb;
2368  }
2369  $this->db->free($resql);
2370  return 1;
2371  } else {
2372  dol_print_error($this->db);
2373  $this->error = $this->db->error();
2374  return -1;
2375  }
2376  }
2377 
2378  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2385  public function load_board($user)
2386  {
2387  // phpcs:enable
2388  global $conf, $langs;
2389 
2390  if ($user->socid) {
2391  return -1; // protection pour eviter appel par utilisateur externe
2392  }
2393 
2394  $now = dol_now();
2395 
2396  $sql = "SELECT h.rowid, h.date_debut";
2397  $sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
2398  $sql .= " WHERE h.statut = 2";
2399  $sql .= " AND h.entity IN (".getEntity('holiday').")";
2400  if (empty($user->rights->expensereport->read_all)) {
2401  $userchildids = $user->getAllChildIds(1);
2402  $sql .= " AND (h.fk_user IN (".$this->db->sanitize(join(',', $userchildids)).")";
2403  $sql .= " OR h.fk_validator IN (".$this->db->sanitize(join(',', $userchildids))."))";
2404  }
2405 
2406  $resql = $this->db->query($sql);
2407  if ($resql) {
2408  $langs->load("members");
2409 
2410  $response = new WorkboardResponse();
2411  $response->warning_delay = $conf->holiday->approve->warning_delay / 60 / 60 / 24;
2412  $response->label = $langs->trans("HolidaysToApprove");
2413  $response->labelShort = $langs->trans("ToApprove");
2414  $response->url = DOL_URL_ROOT.'/holiday/list.php?search_status=2&amp;mainmenu=hrm&amp;leftmenu=holiday';
2415  $response->img = img_object('', "holiday");
2416 
2417  while ($obj = $this->db->fetch_object($resql)) {
2418  $response->nbtodo++;
2419 
2420  if ($this->db->jdate($obj->date_debut) < ($now - $conf->holiday->approve->warning_delay)) {
2421  $response->nbtodolate++;
2422  }
2423  }
2424 
2425  return $response;
2426  } else {
2427  dol_print_error($this->db);
2428  $this->error = $this->db->error();
2429  return -1;
2430  }
2431  }
2439  public function getKanbanView($option = '', $arraydata = null)
2440  {
2441  global $langs;
2442 
2443  $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
2444 
2445  $return = '<div class="box-flex-item box-flex-grow-zero">';
2446  $return .= '<div class="info-box info-box-sm">';
2447  $return .= '<span class="info-box-icon bg-infobox-action">';
2448  $return .= img_picto('', $this->picto);
2449  $return .= '</span>';
2450  $return .= '<div class="info-box-content">';
2451  $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.$arraydata['user']->getNomUrl(-1).'</span>';
2452  $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
2453  if (property_exists($this, 'fk_type')) {
2454  $return .= '<br><span class="opacitymedium">'.$langs->trans("Type").'</span> : ';
2455  $return .= '<span class="info_box-label maxwidth100">'.$arraydata['labeltype'].'</span>';
2456  }
2457  if (property_exists($this, 'date_debut') && property_exists($this, 'date_fin')) {
2458  $return .= '<br><span class="info-box-label">'.dol_print_date($this->date_debut, 'day').'</span>';
2459  $return .= ' <span class="opacitymedium">'.$langs->trans("To").'</span> ';
2460  $return .= '<span class="info-box-label">'.dol_print_date($this->date_fin, 'day').'</span>';
2461  }
2462  if (method_exists($this, 'getLibStatut')) {
2463  $return .= '<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).'</div>';
2464  }
2465  $return .= '</div>';
2466  $return .= '</div>';
2467  $return .= '</div>';
2468  return $return;
2469  }
2470 }
Holiday\initAsSpecimen
initAsSpecimen()
Initialise an instance with random values.
Definition: holiday.class.php:2322
Holiday\getTooltipContentArray
getTooltipContentArray($params)
getTooltipContentArray
Definition: holiday.class.php:1309
Holiday\getLibStatut
getLibStatut($mode=0)
Returns the label status.
Definition: holiday.class.php:1417
Holiday\fetchLog
fetchLog($order, $filter)
Liste le log des congés payés.
Definition: holiday.class.php:2141
dol_sanitizeFileName
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
Definition: functions.lib.php:1322
description
print *****$script_file(".$version.") pid cd cd cd description as description
Definition: email_expire_services_to_customers.php:83
Holiday\__construct
__construct($db)
Constructor.
Definition: holiday.class.php:169
Holiday\createCPusers
createCPusers($single=false, $userid='')
Create entries for each user at setup step.
Definition: holiday.class.php:1704
Holiday\selectStatutCP
selectStatutCP($selected='', $htmlname='select_statut', $morecss='minwidth125')
Affiche un select HTML des statuts de congés payés.
Definition: holiday.class.php:1482
Holiday\validate
validate($user=null, $notrigger=0)
Validate leave request.
Definition: holiday.class.php:720
dol_print_error
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
Definition: functions.lib.php:5096
Holiday\getTypes
getTypes($active=-1, $affect=-1)
Return array with list of types.
Definition: holiday.class.php:2213
dol_buildpath
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
Definition: functions.lib.php:1157
dol_dir_list
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
Holiday\getCPforUser
getCPforUser($user_id, $fk_type=0)
Return balance of holiday for one user.
Definition: holiday.class.php:1740
Holiday\STATUS_APPROVED
const STATUS_APPROVED
Approved.
Definition: holiday.class.php:153
Holiday\update
update($user=null, $notrigger=0)
Update database.
Definition: holiday.class.php:966
Holiday\approve
approve($user=null, $notrigger=0)
Approve leave request.
Definition: holiday.class.php:837
CommonObject
Parent class of all other business classes (invoices, contracts, proposals, orders,...
Definition: commonobject.class.php:45
Holiday\countActiveUsers
countActiveUsers()
Compte le nombre d'utilisateur actifs dans Dolibarr.
Definition: holiday.class.php:2020
price2num
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
Definition: functions.lib.php:5943
Holiday\countActiveUsersWithoutCP
countActiveUsersWithoutCP()
Compte le nombre d'utilisateur actifs dans Dolibarr sans CP.
Definition: holiday.class.php:2036
dol_print_date
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
Definition: functions.lib.php:2665
WorkboardResponse
Definition: workboardresponse.class.php:24
img_picto
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
Definition: functions.lib.php:4125
Holiday\STATUS_REFUSED
const STATUS_REFUSED
Refused.
Definition: holiday.class.php:161
Holiday
Class of the module paid holiday.
Definition: holiday.class.php:34
Holiday\verifDateHolidayForTimestamp
verifDateHolidayForTimestamp($fk_user, $timestamp, $status='-1')
Check that a user is not on holiday for a particular timestamp.
Definition: holiday.class.php:1233
Holiday\verifNbUsers
verifNbUsers($userDolibarrWithoutCP, $userCP)
Compare le nombre d'utilisateur actif de Dolibarr à celui des utilisateurs des congés payés.
Definition: holiday.class.php:2056
Holiday\getKanbanView
getKanbanView($option='', $arraydata=null)
Return clicable link of object (with eventually picto)
Definition: holiday.class.php:2439
CommonObject\insertExtraFields
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
Definition: commonobject.class.php:6110
Holiday\addLogCP
addLogCP($fk_user_action, $fk_user_update, $label, $new_solde, $fk_type)
addLogCP
Definition: holiday.class.php:2076
Holiday\STATUS_DRAFT
const STATUS_DRAFT
Draft status.
Definition: holiday.class.php:145
Holiday\fetchAll
fetchAll($order, $filter)
List all holidays of all users.
Definition: holiday.class.php:590
$sql
if(isModEnabled('facture') &&!empty($user->rights->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
getDictionaryValue
getDictionaryValue($tablename, $field, $id, $checkentity=false, $rowidfield='rowid')
Return the value of a filed into a dictionary for the record $id.
Definition: functions.lib.php:10732
Holiday\verifDateHolidayCP
verifDateHolidayCP($fk_user, $dateStart, $dateEnd, $halfday=0)
Check if a user is on holiday (partially or completely) into a period.
Definition: holiday.class.php:1151
Holiday\fetchByUser
fetchByUser($user_id, $order='', $filter='')
List holidays for a particular user or list of users.
Definition: holiday.class.php:461
dol_syslog
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
Definition: functions.lib.php:1732
Holiday\updateBalance
updateBalance()
Update balance of vacations and check table of users for holidays is complete.
Definition: holiday.class.php:232
Holiday\getNomUrl
getNomUrl($withpicto=0, $save_lastsearch_value=-1, $notooltip=0)
Return clicable name (with picto eventually)
Definition: holiday.class.php:1351
CommonObject\fetch_optionals
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...
Definition: commonobject.class.php:5959
isModEnabled
isModEnabled($module)
Is Dolibarr module enabled.
Definition: functions.lib.php:207
ref
$object ref
Definition: info.php:78
Holiday\fetch_users_approver_holiday
fetch_users_approver_holiday()
Return list of people with permission to validate leave requests.
Definition: holiday.class.php:1983
User
Class to manage Dolibarr users.
Definition: user.class.php:47
Holiday\STATUS_CANCELED
const STATUS_CANCELED
Canceled.
Definition: holiday.class.php:157
Holiday\info
info($id)
Load information on object.
Definition: holiday.class.php:2252
dolGetStatus
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
Definition: functions.lib.php:10932
Holiday\getNextNumRef
getNextNumRef($objsoc)
Returns the reference to the following non used Order depending on the active numbering module define...
Definition: holiday.class.php:182
Holiday\LibStatut
LibStatut($status, $mode=0, $startdate='')
Returns the label of a status.
Definition: holiday.class.php:1431
Holiday\fetchUsers
fetchUsers($stringlist=true, $type=true, $filters='')
Get list of Users or list of vacation balance.
Definition: holiday.class.php:1772
img_object
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
Definition: functions.lib.php:4462
Holiday\STATUS_VALIDATED
const STATUS_VALIDATED
Validated status.
Definition: holiday.class.php:149
dol_now
dol_now($mode='auto')
Return date for now.
Definition: functions.lib.php:3046
CommonObject\call_trigger
call_trigger($triggerName, $user)
Call trigger based on this instance.
Definition: commonobject.class.php:5743
ajax_combobox
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
getDolGlobalInt
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
Definition: functions.lib.php:156
Holiday\fetch
fetch($id, $ref='')
Load object in memory from database.
Definition: holiday.class.php:368
Holiday\updateConfCP
updateConfCP($name, $value)
Met à jour une option du module Holiday Payés.
Definition: holiday.class.php:1518
Holiday\load_board
load_board($user)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
Definition: holiday.class.php:2385
Holiday\load_state_board
load_state_board()
Load this->nb for dashboard.
Definition: holiday.class.php:2347
Holiday\updateSoldeCP
updateSoldeCP($userID='', $nbHoliday='', $fk_type='')
Met à jour le timestamp de la dernière mise à jour du solde des CP.
Definition: holiday.class.php:1586
Holiday\create
create($user, $notrigger=0)
Créer un congés payés dans la base de données.
Definition: holiday.class.php:258
Holiday\getConfCP
getConfCP($name, $createifnotfound='')
Return value of a conf parameter for leave module TODO Move this into llx_const table.
Definition: holiday.class.php:1542
float
div float
Buy price without taxes.
Definition: style.css.php:921