dolibarr  17.0.4
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-2021 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 
1302 
1311  public function getNomUrl($withpicto = 0, $save_lastsearch_value = -1, $notooltip = 0)
1312  {
1313  global $langs, $hookmanager;
1314 
1315  $result = '';
1316 
1317  $label = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Holiday").'</u>';
1318  if (isset($this->statut)) {
1319  $label .= ' '.$this->getLibStatut(5);
1320  }
1321  $label .= '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
1322 
1323  $url = DOL_URL_ROOT.'/holiday/card.php?id='.$this->id;
1324 
1325  //if ($option != 'nolink')
1326  //{
1327  // Add param to save lastsearch_values or not
1328  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1329  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1330  $add_save_lastsearch_values = 1;
1331  }
1332  if ($add_save_lastsearch_values) {
1333  $url .= '&save_lastsearch_values=1';
1334  }
1335  //}
1336 
1337  $linkstart = '<a href="'.$url.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
1338  $linkend = '</a>';
1339 
1340  $result .= $linkstart;
1341  if ($withpicto) {
1342  $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
1343  }
1344  if ($withpicto != 2) {
1345  $result .= $this->ref;
1346  }
1347  $result .= $linkend;
1348  global $action;
1349  $hookmanager->initHooks(array($this->element . 'dao'));
1350  $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
1351  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1352  if ($reshook > 0) {
1353  $result = $hookmanager->resPrint;
1354  } else {
1355  $result .= $hookmanager->resPrint;
1356  }
1357  return $result;
1358  }
1359 
1360 
1367  public function getLibStatut($mode = 0)
1368  {
1369  return $this->LibStatut($this->statut, $mode, $this->date_debut);
1370  }
1371 
1372  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1381  public function LibStatut($status, $mode = 0, $startdate = '')
1382  {
1383  // phpcs:enable
1384  global $langs;
1385 
1386  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
1387  global $langs;
1388  //$langs->load("mymodule");
1389  $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP');
1390  $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP');
1391  $this->labelStatus[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP');
1392  $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP');
1393  $this->labelStatus[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP');
1394  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP');
1395  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP');
1396  $this->labelStatusShort[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP');
1397  $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP');
1398  $this->labelStatusShort[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP');
1399  }
1400 
1401  $params = array();
1402  $statusType = 'status6';
1403  if (!empty($startdate) && $startdate >= dol_now()) { // If not yet passed, we use a green "in live" color
1404  $statusType = 'status4';
1405  $params = array('tooltip'=>$this->labelStatus[$status].' - '.$langs->trans("Forthcoming"));
1406  }
1407  if ($status == self::STATUS_DRAFT) {
1408  $statusType = 'status0';
1409  }
1410  if ($status == self::STATUS_VALIDATED) {
1411  $statusType = 'status1';
1412  }
1413  if ($status == self::STATUS_CANCELED) {
1414  $statusType = 'status5';
1415  }
1416  if ($status == self::STATUS_REFUSED) {
1417  $statusType = 'status5';
1418  }
1419 
1420  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode, '', $params);
1421  }
1422 
1423 
1432  public function selectStatutCP($selected = '', $htmlname = 'select_statut', $morecss = 'minwidth125')
1433  {
1434  global $langs;
1435 
1436  // Liste des statuts
1437  $name = array('DraftCP', 'ToReviewCP', 'ApprovedCP', 'CancelCP', 'RefuseCP');
1438  $nb = count($name) + 1;
1439 
1440  // Select HTML
1441  $out = '<select name="'.$htmlname.'" id="'.$htmlname.'" class="flat'.($morecss ? ' '.$morecss : '').'">'."\n";
1442  $out .= '<option value="-1">&nbsp;</option>'."\n";
1443 
1444  // Boucle des statuts
1445  for ($i = 1; $i < $nb; $i++) {
1446  if ($i == $selected) {
1447  $out .= '<option value="'.$i.'" selected>'.$langs->trans($name[$i - 1]).'</option>'."\n";
1448  } else {
1449  $out .= '<option value="'.$i.'">'.$langs->trans($name[$i - 1]).'</option>'."\n";
1450  }
1451  }
1452 
1453  $out .= '</select>'."\n";
1454  $out .= ajax_combobox($htmlname);
1455 
1456  print $out;
1457  }
1458 
1466  public function updateConfCP($name, $value)
1467  {
1468 
1469  $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
1470  $sql .= " value = '".$this->db->escape($value)."'";
1471  $sql .= " WHERE name = '".$this->db->escape($name)."'";
1472 
1473  dol_syslog(get_class($this).'::updateConfCP name='.$name.'', LOG_DEBUG);
1474  $result = $this->db->query($sql);
1475  if ($result) {
1476  return true;
1477  }
1478 
1479  return false;
1480  }
1481 
1490  public function getConfCP($name, $createifnotfound = '')
1491  {
1492  $sql = "SELECT value";
1493  $sql .= " FROM ".MAIN_DB_PREFIX."holiday_config";
1494  $sql .= " WHERE name = '".$this->db->escape($name)."'";
1495 
1496  dol_syslog(get_class($this).'::getConfCP name='.$name.' createifnotfound='.$createifnotfound, LOG_DEBUG);
1497  $result = $this->db->query($sql);
1498 
1499  if ($result) {
1500  $obj = $this->db->fetch_object($result);
1501  // Return value
1502  if (empty($obj)) {
1503  if ($createifnotfound) {
1504  $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_config(name, value)";
1505  $sql .= " VALUES('".$this->db->escape($name)."', '".$this->db->escape($createifnotfound)."')";
1506  $result = $this->db->query($sql);
1507  if ($result) {
1508  return $createifnotfound;
1509  } else {
1510  $this->error = $this->db->lasterror();
1511  return -2;
1512  }
1513  } else {
1514  return '';
1515  }
1516  } else {
1517  return $obj->value;
1518  }
1519  } else {
1520  // Erreur SQL
1521  $this->error = $this->db->lasterror();
1522  return -1;
1523  }
1524  }
1525 
1534  public function updateSoldeCP($userID = '', $nbHoliday = '', $fk_type = '')
1535  {
1536  global $user, $langs;
1537 
1538  $error = 0;
1539 
1540  if (empty($userID) && empty($nbHoliday) && empty($fk_type)) {
1541  $langs->load("holiday");
1542 
1543  // Si mise à jour pour tout le monde en début de mois
1544  $now = dol_now();
1545 
1546  $month = date('m', $now);
1547  $newdateforlastupdate = dol_print_date($now, '%Y%m%d%H%M%S');
1548 
1549  // Get month of last update
1550  $lastUpdate = $this->getConfCP('lastUpdate', $newdateforlastupdate);
1551  $monthLastUpdate = $lastUpdate[4].$lastUpdate[5];
1552  //print 'month: '.$month.' lastUpdate:'.$lastUpdate.' monthLastUpdate:'.$monthLastUpdate;exit;
1553 
1554  // 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.
1555  if ($month != $monthLastUpdate) {
1556  $this->db->begin();
1557 
1558  $users = $this->fetchUsers(false, false, ' AND u.statut > 0');
1559  $nbUser = count($users);
1560 
1561  $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_config SET";
1562  $sql .= " value = '".$this->db->escape($newdateforlastupdate)."'";
1563  $sql .= " WHERE name = 'lastUpdate'";
1564  $result = $this->db->query($sql);
1565 
1566  $typeleaves = $this->getTypes(1, 1);
1567 
1568  // Update each user counter
1569  foreach ($users as $userCounter) {
1570  $nbDaysToAdd = (isset($typeleaves[$userCounter['type']]['newbymonth']) ? $typeleaves[$userCounter['type']]['newbymonth'] : 0);
1571  if (empty($nbDaysToAdd)) {
1572  continue;
1573  }
1574 
1575  dol_syslog("We update leave type id ".$userCounter['type']." for user id ".$userCounter['rowid'], LOG_DEBUG);
1576 
1577  $nowHoliday = $userCounter['nb_holiday'];
1578  $newSolde = $nowHoliday + $nbDaysToAdd;
1579 
1580  // We add a log for each user
1581  $this->addLogCP($user->id, $userCounter['rowid'], $langs->trans('HolidaysMonthlyUpdate'), $newSolde, $userCounter['type']);
1582 
1583  $result = $this->updateSoldeCP($userCounter['rowid'], $newSolde, $userCounter['type']);
1584 
1585  if ($result < 0) {
1586  $error++;
1587  break;
1588  }
1589  }
1590 
1591  if (!$error) {
1592  $this->db->commit();
1593  return 1;
1594  } else {
1595  $this->db->rollback();
1596  return -1;
1597  }
1598  }
1599 
1600  return 0;
1601  } else {
1602  // Mise à jour pour un utilisateur
1603  $nbHoliday = price2num($nbHoliday, 5);
1604 
1605  $sql = "SELECT nb_holiday FROM ".MAIN_DB_PREFIX."holiday_users";
1606  $sql .= " WHERE fk_user = ".(int) $userID." AND fk_type = ".(int) $fk_type;
1607  $resql = $this->db->query($sql);
1608  if ($resql) {
1609  $num = $this->db->num_rows($resql);
1610 
1611  if ($num > 0) {
1612  // Update for user
1613  $sql = "UPDATE ".MAIN_DB_PREFIX."holiday_users SET";
1614  $sql .= " nb_holiday = ".((float) $nbHoliday);
1615  $sql .= " WHERE fk_user = ".(int) $userID." AND fk_type = ".(int) $fk_type;
1616  $result = $this->db->query($sql);
1617  if (!$result) {
1618  $error++;
1619  $this->errors[] = $this->db->lasterror();
1620  }
1621  } else {
1622  // Insert for user
1623  $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users(nb_holiday, fk_user, fk_type) VALUES (";
1624  $sql .= ((float) $nbHoliday);
1625  $sql .= ", ".(int) $userID.", ".(int) $fk_type.")";
1626  $result = $this->db->query($sql);
1627  if (!$result) {
1628  $error++;
1629  $this->errors[] = $this->db->lasterror();
1630  }
1631  }
1632  } else {
1633  $this->errors[] = $this->db->lasterror();
1634  $error++;
1635  }
1636 
1637  if (!$error) {
1638  return 1;
1639  } else {
1640  return -1;
1641  }
1642  }
1643  }
1644 
1651  public function getCheckOption($name)
1652  {
1653 
1654  $sql = "SELECT value";
1655  $sql .= " FROM ".MAIN_DB_PREFIX."holiday_config";
1656  $sql .= " WHERE name = '".$this->db->escape($name)."'";
1657 
1658  $result = $this->db->query($sql);
1659 
1660  if ($result) {
1661  $obj = $this->db->fetch_object($result);
1662 
1663  // Si la valeur est 1 on retourne checked
1664  if ($obj->value) {
1665  return 'checked';
1666  }
1667  }
1668  }
1669 
1670 
1678  public function createCPusers($single = false, $userid = '')
1679  {
1680  // do we have to add balance for all users ?
1681  if (!$single) {
1682  dol_syslog(get_class($this).'::createCPusers');
1683  $arrayofusers = $this->fetchUsers(false, true);
1684 
1685  foreach ($arrayofusers as $users) {
1686  $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users";
1687  $sql .= " (fk_user, nb_holiday)";
1688  $sql .= " VALUES (".((int) $users['rowid'])."', '0')";
1689 
1690  $resql = $this->db->query($sql);
1691  if (!$resql) {
1692  dol_print_error($this->db);
1693  }
1694  }
1695  } else {
1696  $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_users";
1697  $sql .= " (fk_user, nb_holiday)";
1698  $sql .= " VALUES (".((int) $userid)."', '0')";
1699 
1700  $resql = $this->db->query($sql);
1701  if (!$resql) {
1702  dol_print_error($this->db);
1703  }
1704  }
1705  }
1706 
1713  public function deleteCPuser($user_id)
1714  {
1715 
1716  $sql = "DELETE FROM ".MAIN_DB_PREFIX."holiday_users";
1717  $sql .= " WHERE fk_user = ".((int) $user_id);
1718 
1719  $this->db->query($sql);
1720  }
1721 
1722 
1730  public function getCPforUser($user_id, $fk_type = 0)
1731  {
1732  $sql = "SELECT nb_holiday";
1733  $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users";
1734  $sql .= " WHERE fk_user = ".(int) $user_id;
1735  if ($fk_type > 0) {
1736  $sql .= " AND fk_type = ".(int) $fk_type;
1737  }
1738 
1739  dol_syslog(get_class($this).'::getCPforUser user_id='.$user_id.' type_id='.$fk_type, LOG_DEBUG);
1740  $result = $this->db->query($sql);
1741  if ($result) {
1742  $obj = $this->db->fetch_object($result);
1743  //return number_format($obj->nb_holiday,2);
1744  if ($obj) {
1745  return $obj->nb_holiday;
1746  } else {
1747  return null;
1748  }
1749  } else {
1750  return null;
1751  }
1752  }
1753 
1762  public function fetchUsers($stringlist = true, $type = true, $filters = '')
1763  {
1764  global $conf;
1765 
1766  dol_syslog(get_class($this)."::fetchUsers", LOG_DEBUG);
1767 
1768  if ($stringlist) {
1769  if ($type) {
1770  // If user of Dolibarr
1771  $sql = "SELECT";
1772  if (isModEnabled('multicompany') && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
1773  $sql .= " DISTINCT";
1774  }
1775  $sql .= " u.rowid";
1776  $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
1777 
1778  if (isModEnabled('multicompany') && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
1779  $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
1780  $sql .= " WHERE ((ug.fk_user = u.rowid";
1781  $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
1782  $sql .= " OR u.entity = 0)"; // Show always superadmin
1783  } else {
1784  $sql .= " WHERE u.entity IN (".getEntity('user').")";
1785  }
1786  $sql .= " AND u.statut > 0";
1787  $sql .= " AND u.employee = 1"; // We only want employee users for holidays
1788  if ($filters) {
1789  $sql .= $filters;
1790  }
1791 
1792  $resql = $this->db->query($sql);
1793 
1794  // Si pas d'erreur SQL
1795  if ($resql) {
1796  $i = 0;
1797  $num = $this->db->num_rows($resql);
1798  $stringlist = '';
1799 
1800  // Boucles du listage des utilisateurs
1801  while ($i < $num) {
1802  $obj = $this->db->fetch_object($resql);
1803 
1804  if ($i == 0) {
1805  $stringlist .= $obj->rowid;
1806  } else {
1807  $stringlist .= ', '.$obj->rowid;
1808  }
1809 
1810  $i++;
1811  }
1812  // Retoune le tableau des utilisateurs
1813  return $stringlist;
1814  } else {
1815  // Erreur SQL
1816  $this->error = "Error ".$this->db->lasterror();
1817  return -1;
1818  }
1819  } else {
1820  // We want only list of vacation balance for user ids
1821  $sql = "SELECT DISTINCT cpu.fk_user";
1822  $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u";
1823  $sql .= " WHERE cpu.fk_user = u.rowid";
1824  if ($filters) {
1825  $sql .= $filters;
1826  }
1827 
1828  $resql = $this->db->query($sql);
1829 
1830  // Si pas d'erreur SQL
1831  if ($resql) {
1832  $i = 0;
1833  $num = $this->db->num_rows($resql);
1834  $stringlist = '';
1835 
1836  // Boucles du listage des utilisateurs
1837  while ($i < $num) {
1838  $obj = $this->db->fetch_object($resql);
1839 
1840  if ($i == 0) {
1841  $stringlist .= $obj->fk_user;
1842  } else {
1843  $stringlist .= ', '.$obj->fk_user;
1844  }
1845 
1846  $i++;
1847  }
1848  // Retoune le tableau des utilisateurs
1849  return $stringlist;
1850  } else {
1851  // Erreur SQL
1852  $this->error = "Error ".$this->db->lasterror();
1853  return -1;
1854  }
1855  }
1856  } else {
1857  // Si faux donc return array
1858  // List for Dolibarr users
1859  if ($type) {
1860  // If we need users of Dolibarr
1861  $sql = "SELECT";
1862  if (isModEnabled('multicompany') && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
1863  $sql .= " DISTINCT";
1864  }
1865  $sql .= " u.rowid, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut, u.fk_user";
1866  $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
1867 
1868  if (isModEnabled('multicompany') && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) {
1869  $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
1870  $sql .= " WHERE ((ug.fk_user = u.rowid";
1871  $sql .= " AND ug.entity IN (".getEntity('usergroup')."))";
1872  $sql .= " OR u.entity = 0)"; // Show always superadmin
1873  } else {
1874  $sql .= " WHERE u.entity IN (".getEntity('user').")";
1875  }
1876 
1877  $sql .= " AND u.statut > 0";
1878  $sql .= " AND u.employee = 1"; // We only want employee users for holidays
1879  if ($filters) {
1880  $sql .= $filters;
1881  }
1882 
1883  $resql = $this->db->query($sql);
1884 
1885  // Si pas d'erreur SQL
1886  if ($resql) {
1887  $i = 0;
1888  $tab_result = $this->holiday;
1889  $num = $this->db->num_rows($resql);
1890 
1891  // Boucles du listage des utilisateurs
1892  while ($i < $num) {
1893  $obj = $this->db->fetch_object($resql);
1894 
1895  $tab_result[$i]['rowid'] = $obj->rowid; // rowid of user
1896  $tab_result[$i]['id'] = $obj->rowid; // id of user
1897  $tab_result[$i]['name'] = $obj->lastname; // deprecated
1898  $tab_result[$i]['lastname'] = $obj->lastname;
1899  $tab_result[$i]['firstname'] = $obj->firstname;
1900  $tab_result[$i]['gender'] = $obj->gender;
1901  $tab_result[$i]['status'] = $obj->statut;
1902  $tab_result[$i]['employee'] = $obj->employee;
1903  $tab_result[$i]['photo'] = $obj->photo;
1904  $tab_result[$i]['fk_user'] = $obj->fk_user; // rowid of manager
1905  //$tab_result[$i]['type'] = $obj->type;
1906  //$tab_result[$i]['nb_holiday'] = $obj->nb_holiday;
1907 
1908  $i++;
1909  }
1910  // Retoune le tableau des utilisateurs
1911  return $tab_result;
1912  } else {
1913  // Erreur SQL
1914  $this->errors[] = "Error ".$this->db->lasterror();
1915  return -1;
1916  }
1917  } else {
1918  // List of vacation balance users
1919  $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";
1920  $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u";
1921  $sql .= " WHERE cpu.fk_user = u.rowid";
1922  if ($filters) {
1923  $sql .= $filters;
1924  }
1925 
1926  $resql = $this->db->query($sql);
1927 
1928  // Si pas d'erreur SQL
1929  if ($resql) {
1930  $i = 0;
1931  $tab_result = $this->holiday;
1932  $num = $this->db->num_rows($resql);
1933 
1934  // Boucles du listage des utilisateurs
1935  while ($i < $num) {
1936  $obj = $this->db->fetch_object($resql);
1937 
1938  $tab_result[$i]['rowid'] = $obj->rowid; // rowid of user
1939  $tab_result[$i]['id'] = $obj->rowid; // id of user
1940  $tab_result[$i]['name'] = $obj->lastname; // deprecated
1941  $tab_result[$i]['lastname'] = $obj->lastname;
1942  $tab_result[$i]['firstname'] = $obj->firstname;
1943  $tab_result[$i]['gender'] = $obj->gender;
1944  $tab_result[$i]['status'] = $obj->statut;
1945  $tab_result[$i]['employee'] = $obj->employee;
1946  $tab_result[$i]['photo'] = $obj->photo;
1947  $tab_result[$i]['fk_user'] = $obj->fk_user; // rowid of manager
1948 
1949  $tab_result[$i]['type'] = $obj->fk_type;
1950  $tab_result[$i]['nb_holiday'] = $obj->nb_holiday;
1951 
1952  $i++;
1953  }
1954  // Retoune le tableau des utilisateurs
1955  return $tab_result;
1956  } else {
1957  // Erreur SQL
1958  $this->error = "Error ".$this->db->lasterror();
1959  return -1;
1960  }
1961  }
1962  }
1963  }
1964 
1965 
1966  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1974  {
1975  // phpcs:enable
1976  $users_validator = array();
1977 
1978  $sql = "SELECT DISTINCT ur.fk_user";
1979  $sql .= " FROM ".MAIN_DB_PREFIX."user_rights as ur, ".MAIN_DB_PREFIX."rights_def as rd";
1980  $sql .= " WHERE ur.fk_id = rd.id and rd.module = 'holiday' AND rd.perms = 'approve'"; // Permission 'Approve';
1981  $sql .= "UNION";
1982  $sql .= " SELECT DISTINCT ugu.fk_user";
1983  $sql .= " FROM ".MAIN_DB_PREFIX."usergroup_user as ugu, ".MAIN_DB_PREFIX."usergroup_rights as ur, ".MAIN_DB_PREFIX."rights_def as rd";
1984  $sql .= " WHERE ugu.fk_usergroup = ur.fk_usergroup AND ur.fk_id = rd.id and rd.module = 'holiday' AND rd.perms = 'approve'"; // Permission 'Approve';
1985  //print $sql;
1986 
1987  dol_syslog(get_class($this)."::fetch_users_approver_holiday sql=".$sql);
1988  $result = $this->db->query($sql);
1989  if ($result) {
1990  $num_rows = $this->db->num_rows($result); $i = 0;
1991  while ($i < $num_rows) {
1992  $objp = $this->db->fetch_object($result);
1993  array_push($users_validator, $objp->fk_user);
1994  $i++;
1995  }
1996  return $users_validator;
1997  } else {
1998  $this->error = $this->db->lasterror();
1999  dol_syslog(get_class($this)."::fetch_users_approver_holiday Error ".$this->error, LOG_ERR);
2000  return -1;
2001  }
2002  }
2003 
2004 
2010  public function countActiveUsers()
2011  {
2012  $sql = "SELECT count(u.rowid) as compteur";
2013  $sql .= " FROM ".MAIN_DB_PREFIX."user as u";
2014  $sql .= " WHERE u.statut > 0";
2015 
2016  $result = $this->db->query($sql);
2017  $objet = $this->db->fetch_object($result);
2018 
2019  return $objet->compteur;
2020  }
2026  public function countActiveUsersWithoutCP()
2027  {
2028 
2029  $sql = "SELECT count(u.rowid) as compteur";
2030  $sql .= " FROM ".MAIN_DB_PREFIX."user as u LEFT OUTER JOIN ".MAIN_DB_PREFIX."holiday_users hu ON (hu.fk_user=u.rowid)";
2031  $sql .= " WHERE u.statut > 0 AND hu.fk_user IS NULL";
2032 
2033  $result = $this->db->query($sql);
2034  $objet = $this->db->fetch_object($result);
2035 
2036  return $objet->compteur;
2037  }
2038 
2046  public function verifNbUsers($userDolibarrWithoutCP, $userCP)
2047  {
2048  if (empty($userCP)) {
2049  $userCP = 0;
2050  }
2051  dol_syslog(get_class($this).'::verifNbUsers userDolibarr='.$userDolibarrWithoutCP.' userCP='.$userCP);
2052  return 1;
2053  }
2054 
2055 
2066  public function addLogCP($fk_user_action, $fk_user_update, $label, $new_solde, $fk_type)
2067  {
2068  global $conf, $langs;
2069 
2070  $error = 0;
2071 
2072  $prev_solde = price2num($this->getCPforUser($fk_user_update, $fk_type), 5);
2073  $new_solde = price2num($new_solde, 5);
2074  //print "$prev_solde == $new_solde";
2075 
2076  if ($prev_solde == $new_solde) {
2077  return 0;
2078  }
2079 
2080  $this->db->begin();
2081 
2082  // Insert request
2083  $sql = "INSERT INTO ".MAIN_DB_PREFIX."holiday_logs (";
2084  $sql .= "date_action,";
2085  $sql .= "fk_user_action,";
2086  $sql .= "fk_user_update,";
2087  $sql .= "type_action,";
2088  $sql .= "prev_solde,";
2089  $sql .= "new_solde,";
2090  $sql .= "fk_type";
2091  $sql .= ") VALUES (";
2092  $sql .= " '".$this->db->idate(dol_now())."',";
2093  $sql .= " ".((int) $fk_user_action).",";
2094  $sql .= " ".((int) $fk_user_update).",";
2095  $sql .= " '".$this->db->escape($label)."',";
2096  $sql .= " ".((float) $prev_solde).",";
2097  $sql .= " ".((float) $new_solde).",";
2098  $sql .= " ".((int) $fk_type);
2099  $sql .= ")";
2100 
2101  $resql = $this->db->query($sql);
2102  if (!$resql) {
2103  $error++; $this->errors[] = "Error ".$this->db->lasterror();
2104  }
2105 
2106  if (!$error) {
2107  $this->optRowid = $this->db->last_insert_id(MAIN_DB_PREFIX."holiday_logs");
2108  }
2109 
2110  // Commit or rollback
2111  if ($error) {
2112  foreach ($this->errors as $errmsg) {
2113  dol_syslog(get_class($this)."::addLogCP ".$errmsg, LOG_ERR);
2114  $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
2115  }
2116  $this->db->rollback();
2117  return -1 * $error;
2118  } else {
2119  $this->db->commit();
2120  return $this->optRowid;
2121  }
2122  }
2123 
2131  public function fetchLog($order, $filter)
2132  {
2133  $sql = "SELECT";
2134  $sql .= " cpl.rowid,";
2135  $sql .= " cpl.date_action,";
2136  $sql .= " cpl.fk_user_action,";
2137  $sql .= " cpl.fk_user_update,";
2138  $sql .= " cpl.type_action,";
2139  $sql .= " cpl.prev_solde,";
2140  $sql .= " cpl.new_solde,";
2141  $sql .= " cpl.fk_type";
2142  $sql .= " FROM ".MAIN_DB_PREFIX."holiday_logs as cpl";
2143  $sql .= " WHERE cpl.rowid > 0"; // To avoid error with other search and criteria
2144 
2145  // Filtrage de séléction
2146  if (!empty($filter)) {
2147  $sql .= " ".$filter;
2148  }
2149 
2150  // Ordre d'affichage
2151  if (!empty($order)) {
2152  $sql .= " ".$order;
2153  }
2154 
2155  dol_syslog(get_class($this)."::fetchLog", LOG_DEBUG);
2156  $resql = $this->db->query($sql);
2157 
2158  // Si pas d'erreur SQL
2159  if ($resql) {
2160  $i = 0;
2161  $tab_result = $this->logs;
2162  $num = $this->db->num_rows($resql);
2163 
2164  // Si pas d'enregistrement
2165  if (!$num) {
2166  return 2;
2167  }
2168 
2169  // On liste les résultats et on les ajoutent dans le tableau
2170  while ($i < $num) {
2171  $obj = $this->db->fetch_object($resql);
2172 
2173  $tab_result[$i]['rowid'] = $obj->rowid;
2174  $tab_result[$i]['id'] = $obj->rowid;
2175  $tab_result[$i]['date_action'] = $obj->date_action;
2176  $tab_result[$i]['fk_user_action'] = $obj->fk_user_action;
2177  $tab_result[$i]['fk_user_update'] = $obj->fk_user_update;
2178  $tab_result[$i]['type_action'] = $obj->type_action;
2179  $tab_result[$i]['prev_solde'] = $obj->prev_solde;
2180  $tab_result[$i]['new_solde'] = $obj->new_solde;
2181  $tab_result[$i]['fk_type'] = $obj->fk_type;
2182 
2183  $i++;
2184  }
2185  // Retourne 1 et ajoute le tableau à la variable
2186  $this->logs = $tab_result;
2187  return 1;
2188  } else {
2189  // Erreur SQL
2190  $this->error = "Error ".$this->db->lasterror();
2191  return -1;
2192  }
2193  }
2194 
2195 
2203  public function getTypes($active = -1, $affect = -1)
2204  {
2205  global $mysoc;
2206 
2207  $sql = "SELECT rowid, code, label, affect, delay, newbymonth";
2208  $sql .= " FROM ".MAIN_DB_PREFIX."c_holiday_types";
2209  $sql .= " WHERE (fk_country IS NULL OR fk_country = ".((int) $mysoc->country_id).')';
2210  if ($active >= 0) {
2211  $sql .= " AND active = ".((int) $active);
2212  }
2213  if ($affect >= 0) {
2214  $sql .= " AND affect = ".((int) $affect);
2215  }
2216  $sql .= " ORDER BY sortorder";
2217 
2218  $result = $this->db->query($sql);
2219  if ($result) {
2220  $num = $this->db->num_rows($result);
2221  if ($num) {
2222  while ($obj = $this->db->fetch_object($result)) {
2223  $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);
2224  }
2225 
2226  return $types;
2227  }
2228  } else {
2229  dol_print_error($this->db);
2230  }
2231 
2232  return array();
2233  }
2234 
2235 
2242  public function info($id)
2243  {
2244  global $conf;
2245 
2246  $sql = "SELECT f.rowid, f.statut as status,";
2247  $sql .= " f.date_create as datec,";
2248  $sql .= " f.tms as date_modification,";
2249  $sql .= " f.date_valid as datev,";
2250  $sql .= " f.date_approval as datea,";
2251  $sql .= " f.date_refuse as dater,";
2252  $sql .= " f.fk_user_create as fk_user_creation,";
2253  $sql .= " f.fk_user_modif as fk_user_modification,";
2254  $sql .= " f.fk_user_valid as fk_user_validation,";
2255  $sql .= " f.fk_user_approve as fk_user_approval_done,";
2256  $sql .= " f.fk_validator as fk_user_approval_expected,";
2257  $sql .= " f.fk_user_refuse as fk_user_refuse";
2258  $sql .= " FROM ".MAIN_DB_PREFIX."holiday as f";
2259  $sql .= " WHERE f.rowid = ".((int) $id);
2260  $sql .= " AND f.entity = ".$conf->entity;
2261 
2262  $resql = $this->db->query($sql);
2263  if ($resql) {
2264  if ($this->db->num_rows($resql)) {
2265  $obj = $this->db->fetch_object($resql);
2266 
2267  $this->id = $obj->rowid;
2268 
2269  $this->date_creation = $this->db->jdate($obj->datec);
2270  $this->date_modification = $this->db->jdate($obj->date_modification);
2271  $this->date_validation = $this->db->jdate($obj->datev);
2272  $this->date_approval = $this->db->jdate($obj->datea);
2273 
2274  if (!empty($obj->fk_user_creation)) {
2275  $cuser = new User($this->db);
2276  $cuser->fetch($obj->fk_user_creation);
2277  $this->user_creation = $cuser;
2278  }
2279  if (!empty($obj->fk_user_valid)) {
2280  $vuser = new User($this->db);
2281  $vuser->fetch($obj->fk_user_valid);
2282  $this->user_validation = $vuser;
2283  }
2284  if (!empty($obj->fk_user_modification)) {
2285  $muser = new User($this->db);
2286  $muser->fetch($obj->fk_user_modification);
2287  $this->user_modification = $muser;
2288  }
2289 
2290  if ($obj->status == Holiday::STATUS_APPROVED || $obj->status == Holiday::STATUS_CANCELED) {
2291  if ($obj->fk_user_approval_done) {
2292  $auser = new User($this->db);
2293  $auser->fetch($obj->fk_user_approval_done);
2294  $this->user_approve = $auser;
2295  }
2296  }
2297  }
2298  $this->db->free($resql);
2299  } else {
2300  dol_print_error($this->db);
2301  }
2302  }
2303 
2304 
2312  public function initAsSpecimen()
2313  {
2314  global $user, $langs;
2315 
2316  // Initialise parameters
2317  $this->id = 0;
2318  $this->specimen = 1;
2319 
2320  $this->fk_user = $user->id;
2321  $this->description = 'SPECIMEN description';
2322  $this->date_debut = dol_now();
2323  $this->date_fin = dol_now() + (24 * 3600);
2324  $this->date_valid = dol_now();
2325  $this->fk_validator = $user->id;
2326  $this->halfday = 0;
2327  $this->fk_type = 1;
2328  $this->statut = Holiday::STATUS_VALIDATED;
2329  }
2330 
2331  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2337  public function load_state_board()
2338  {
2339  // phpcs:enable
2340  global $user;
2341 
2342  $this->nb = array();
2343 
2344  $sql = "SELECT count(h.rowid) as nb";
2345  $sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
2346  $sql .= " WHERE h.statut > 1";
2347  $sql .= " AND h.entity IN (".getEntity('holiday').")";
2348  if (empty($user->rights->expensereport->readall)) {
2349  $userchildids = $user->getAllChildIds(1);
2350  $sql .= " AND (h.fk_user IN (".$this->db->sanitize(join(',', $userchildids)).")";
2351  $sql .= " OR h.fk_validator IN (".$this->db->sanitize(join(',', $userchildids))."))";
2352  }
2353 
2354  $resql = $this->db->query($sql);
2355  if ($resql) {
2356  while ($obj = $this->db->fetch_object($resql)) {
2357  $this->nb["holidays"] = $obj->nb;
2358  }
2359  $this->db->free($resql);
2360  return 1;
2361  } else {
2362  dol_print_error($this->db);
2363  $this->error = $this->db->error();
2364  return -1;
2365  }
2366  }
2367 
2368  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2375  public function load_board($user)
2376  {
2377  // phpcs:enable
2378  global $conf, $langs;
2379 
2380  if ($user->socid) {
2381  return -1; // protection pour eviter appel par utilisateur externe
2382  }
2383 
2384  $now = dol_now();
2385 
2386  $sql = "SELECT h.rowid, h.date_debut";
2387  $sql .= " FROM ".MAIN_DB_PREFIX."holiday as h";
2388  $sql .= " WHERE h.statut = 2";
2389  $sql .= " AND h.entity IN (".getEntity('holiday').")";
2390  if (empty($user->rights->expensereport->read_all)) {
2391  $userchildids = $user->getAllChildIds(1);
2392  $sql .= " AND (h.fk_user IN (".$this->db->sanitize(join(',', $userchildids)).")";
2393  $sql .= " OR h.fk_validator IN (".$this->db->sanitize(join(',', $userchildids))."))";
2394  }
2395 
2396  $resql = $this->db->query($sql);
2397  if ($resql) {
2398  $langs->load("members");
2399 
2400  $response = new WorkboardResponse();
2401  $response->warning_delay = $conf->holiday->approve->warning_delay / 60 / 60 / 24;
2402  $response->label = $langs->trans("HolidaysToApprove");
2403  $response->labelShort = $langs->trans("ToApprove");
2404  $response->url = DOL_URL_ROOT.'/holiday/list.php?search_status=2&amp;mainmenu=hrm&amp;leftmenu=holiday';
2405  $response->img = img_object('', "holiday");
2406 
2407  while ($obj = $this->db->fetch_object($resql)) {
2408  $response->nbtodo++;
2409 
2410  if ($this->db->jdate($obj->date_debut) < ($now - $conf->holiday->approve->warning_delay)) {
2411  $response->nbtodolate++;
2412  }
2413  }
2414 
2415  return $response;
2416  } else {
2417  dol_print_error($this->db);
2418  $this->error = $this->db->error();
2419  return -1;
2420  }
2421  }
2422 }
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.
getCheckOption($name)
Retourne un checked si vrai.
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='')
Créer les entrées pour chaque utilisateur au moment de la configuration.
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)
getNomUrl($withpicto=0, $save_lastsearch_value=-1, $notooltip=0)
Return clicable name (with picto eventually)
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.
deleteCPuser($user_id)
Supprime un utilisateur du module Congés Payés.
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.
fetchUsers($stringlist=true, $type=true, $filters='')
Get list of Users or list of vacation balance.
LibStatut($status, $mode=0, $startdate='')
Returns the label of a status.
Class to manage Dolibarr users.
Definition: user.class.php:47
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') &&!empty($user->rights->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)) $resql
Social contributions to pay.
Definition: index.php:745
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:61
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields.
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.
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.
div float
Buy price without taxes.
Definition: style.css.php:913
$conf db
API class for accounts.
Definition: inc.php:41