dolibarr  13.0.2
card.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2011 Dimitri Mouillard <dmouillard@teclib.com>
3  * Copyright (C) 2012-2016 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2012-2016 Regis Houssin <regis.houssin@inodbox.com>
5  * Copyright (C) 2013 Juanjo Menent <jmenent@2byte.es>
6  * Copyright (C) 2017 Alexandre Spangaro <aspangaro@open-dsi.fr>
7  * Copyright (C) 2014-2017 Ferran Marcet <fmarcet@2byte.es>
8  * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 3 of the License, orwrite
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <https://www.gnu.org/licenses/>.
22  */
23 
30 require '../main.inc.php';
31 require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
34 require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
35 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
36 require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
37 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
38 require_once DOL_DOCUMENT_ROOT.'/core/lib/holiday.lib.php';
39 require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php';
40 require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
41 
42 // Get parameters
43 $action = GETPOST('action', 'aZ09');
44 $cancel = GETPOST('cancel', 'alpha');
45 $confirm = GETPOST('confirm', 'alpha');
46 
47 $id = GETPOST('id', 'int');
48 $ref = GETPOST('ref', 'alpha');
49 $fuserid = (GETPOST('fuserid', 'int') ?GETPOST('fuserid', 'int') : $user->id);
50 
51 // Load translation files required by the page
52 $langs->loadLangs(array("other", "holiday", "mails"));
53 
54 $now = dol_now();
55 
56 $childids = $user->getAllChildIds(1);
57 
58 $morefilter = '';
59 if (!empty($conf->global->HOLIDAY_HIDE_FOR_NON_SALARIES)) $morefilter = 'AND employee = 1';
60 
61 $error = 0;
62 
63 $object = new Holiday($db);
64 
65 $extrafields = new ExtraFields($db);
66 
67 // fetch optionals attributes and labels
68 $extrafields->fetch_name_optionals_label($object->table_element);
69 
70 if (($id > 0) || $ref)
71 {
72  $object->fetch($id, $ref);
73 
74  // Check current user can read this leave request
75  $canread = 0;
76  if (!empty($user->rights->holiday->readall)) $canread = 1;
77  if (!empty($user->rights->holiday->read) && in_array($object->fk_user, $childids)) $canread = 1;
78  if (!$canread)
79  {
81  }
82 }
83 
84 $cancreate = 0;
85 
86 if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->holiday->writeall_advance)) $cancreate = 1;
87 if (!empty($user->rights->holiday->write) && in_array($fuserid, $childids)) $cancreate = 1;
88 
89 $candelete = 0;
90 if (!empty($user->rights->holiday->delete)) $candelete = 1;
91 if ($object->statut == Holiday::STATUS_DRAFT && $user->rights->holiday->write && in_array($object->fk_user, $childids)) $candelete = 1;
92 
93 // Protection if external user
94 if ($user->socid) $socid = $user->socid;
95 $result = restrictedArea($user, 'holiday', $object->id, 'holiday');
96 
97 
98 /*
99  * Actions
100  */
101 
102 $parameters = array('socid' => $socid);
103 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
104 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
105 
106 if (empty($reshook))
107 {
108  if ($cancel)
109  {
110  if (!empty($backtopage))
111  {
112  header("Location: ".$backtopage);
113  exit;
114  }
115  $action = '';
116  }
117 
118  // Add leave request
119  if ($action == 'add')
120  {
121  // If no right to create a request
122  if (!$cancreate)
123  {
124  $error++;
125  setEventMessages($langs->trans('CantCreateCP'), null, 'errors');
126  $action = 'create';
127  }
128 
129  if (!$error)
130  {
131  $object = new Holiday($db);
132 
133  $db->begin();
134 
135  $date_debut = dol_mktime(0, 0, 0, GETPOST('date_debut_month'), GETPOST('date_debut_day'), GETPOST('date_debut_year'));
136  $date_fin = dol_mktime(0, 0, 0, GETPOST('date_fin_month'), GETPOST('date_fin_day'), GETPOST('date_fin_year'));
137  $date_debut_gmt = dol_mktime(0, 0, 0, GETPOST('date_debut_month'), GETPOST('date_debut_day'), GETPOST('date_debut_year'), 1);
138  $date_fin_gmt = dol_mktime(0, 0, 0, GETPOST('date_fin_month'), GETPOST('date_fin_day'), GETPOST('date_fin_year'), 1);
139  $starthalfday = GETPOST('starthalfday');
140  $endhalfday = GETPOST('endhalfday');
141  $type = GETPOST('type');
142  $halfday = 0;
143  if ($starthalfday == 'afternoon' && $endhalfday == 'morning') $halfday = 2;
144  elseif ($starthalfday == 'afternoon') $halfday = -1;
145  elseif ($endhalfday == 'morning') $halfday = 1;
146 
147  $valideur = GETPOST('valideur', 'int');
148  $description = trim(GETPOST('description', 'restricthtml'));
149 
150  // Check that leave is for a user inside the hierarchy or advanced permission for all is set
151  if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->holiday->write))
152  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->id == $fuserid && empty($user->rights->holiday->write))
153  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->id != $fuserid && empty($user->rights->holiday->writeall_advance))
154  ) {
155  $error++;
156  setEventMessages($langs->trans("NotEnoughPermissions"), null, 'errors');
157  } else {
158  if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || empty($user->rights->holiday->writeall_advance)) {
159  if (!in_array($fuserid, $childids)) {
160  $error++;
161  setEventMessages($langs->trans("UserNotInHierachy"), null, 'errors');
162  $action = 'create';
163  }
164  }
165  }
166 
167  // If no type
168  if ($type <= 0)
169  {
170  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
171  $error++;
172  $action = 'create';
173  }
174 
175  // If no start date
176  if (empty($date_debut))
177  {
178  setEventMessages($langs->trans("NoDateDebut"), null, 'errors');
179  $error++;
180  $action = 'create';
181  }
182  // If no end date
183  if (empty($date_fin))
184  {
185  setEventMessages($langs->trans("NoDateFin"), null, 'errors');
186  $error++;
187  $action = 'create';
188  }
189  // If start date after end date
190  if ($date_debut > $date_fin)
191  {
192  setEventMessages($langs->trans("ErrorEndDateCP"), null, 'errors');
193  $error++;
194  $action = 'create';
195  }
196 
197  // Check if there is already holiday for this period
198  $verifCP = $object->verifDateHolidayCP($fuserid, $date_debut, $date_fin, $halfday);
199  if (!$verifCP)
200  {
201  setEventMessages($langs->trans("alreadyCPexist"), null, 'errors');
202  $error++;
203  $action = 'create';
204  }
205 
206  // If there is no Business Days within request
207  $nbopenedday = num_open_day($date_debut_gmt, $date_fin_gmt, 0, 1, $halfday);
208  if ($nbopenedday < 0.5)
209  {
210  setEventMessages($langs->trans("ErrorDureeCP"), null, 'errors'); // No working day
211  $error++;
212  $action = 'create';
213  }
214 
215  // If no validator designated
216  if ($valideur < 1)
217  {
218  setEventMessages($langs->transnoentitiesnoconv('InvalidValidatorCP'), null, 'errors');
219  $error++;
220  }
221 
222  $result = 0;
223 
224  if (!$error)
225  {
226  $object->fk_user = $fuserid;
227  $object->description = $description;
228  $object->fk_validator = $valideur;
229  $object->fk_type = $type;
230  $object->date_debut = $date_debut;
231  $object->date_fin = $date_fin;
232  $object->halfday = $halfday;
233 
234  $result = $object->create($user);
235  if ($result <= 0)
236  {
237  setEventMessages($object->error, $object->errors, 'errors');
238  $error++;
239  }
240  }
241 
242  // If no SQL error we redirect to the request card
243  if (!$error)
244  {
245  $db->commit();
246 
247  header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
248  exit;
249  } else {
250  $db->rollback();
251  }
252  }
253  }
254 
255  if ($action == 'update' && GETPOSTISSET('savevalidator') && !empty($user->rights->holiday->approve))
256  {
257  $object->fetch($id);
258 
259  $object->oldcopy = dol_clone($object);
260 
261  $object->fk_validator = GETPOST('valideur', 'int');
262 
263  if ($object->fk_validator != $object->oldcopy->fk_validator)
264  {
265  $verif = $object->update($user);
266 
267  if ($verif <= 0)
268  {
269  setEventMessages($object->error, $object->errors, 'warnings');
270  $action = 'editvalidator';
271  } else {
272  header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
273  exit;
274  }
275  }
276 
277  $action = '';
278  }
279 
280  if ($action == 'update' && !GETPOSTISSET('savevalidator'))
281  {
282  $date_debut = dol_mktime(0, 0, 0, GETPOST('date_debut_month'), GETPOST('date_debut_day'), GETPOST('date_debut_year'));
283  $date_fin = dol_mktime(0, 0, 0, GETPOST('date_fin_month'), GETPOST('date_fin_day'), GETPOST('date_fin_year'));
284  $date_debut_gmt = dol_mktime(0, 0, 0, GETPOST('date_debut_month'), GETPOST('date_debut_day'), GETPOST('date_debut_year'), 1);
285  $date_fin_gmt = dol_mktime(0, 0, 0, GETPOST('date_fin_month'), GETPOST('date_fin_day'), GETPOST('date_fin_year'), 1);
286  $starthalfday = GETPOST('starthalfday');
287  $endhalfday = GETPOST('endhalfday');
288  $halfday = 0;
289  if ($starthalfday == 'afternoon' && $endhalfday == 'morning') $halfday = 2;
290  elseif ($starthalfday == 'afternoon') $halfday = -1;
291  elseif ($endhalfday == 'morning') $halfday = 1;
292 
293  // If no right to modify a request
294  if (!$user->rights->holiday->write)
295  {
296  setEventMessages($langs->trans("CantUpdate"), null, 'errors');
297  header('Location: '.$_SERVER["PHP_SELF"].'?action=create');
298  exit;
299  }
300 
301  $object->fetch($id);
302 
303  // If under validation
304  if ($object->statut == Holiday::STATUS_DRAFT)
305  {
306  // If this is the requestor or has read/write rights
307  if ($cancreate)
308  {
309  $valideur = GETPOST('valideur', 'int');
310  $description = trim(GETPOST('description', 'restricthtml'));
311 
312  // If no start date
313  if (empty($_POST['date_debut_'])) {
314  header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&error=nodatedebut');
315  exit;
316  }
317 
318  // If no end date
319  if (empty($_POST['date_fin_'])) {
320  header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&error=nodatefin');
321  exit;
322  }
323 
324  // If start date after end date
325  if ($date_debut > $date_fin) {
326  header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&error=datefin');
327  exit;
328  }
329 
330  // If no validator designated
331  if ($valideur < 1) {
332  header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&error=Valideur');
333  exit;
334  }
335 
336  // If there is no Business Days within request
337  $nbopenedday = num_open_day($date_debut_gmt, $date_fin_gmt, 0, 1, $halfday);
338  if ($nbopenedday < 0.5)
339  {
340  header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&error=DureeHoliday');
341  exit;
342  }
343 
344  $object->description = $description;
345  $object->date_debut = $date_debut;
346  $object->date_fin = $date_fin;
347  $object->fk_validator = $valideur;
348  $object->halfday = $halfday;
349 
350  // Update
351  $verif = $object->update($user);
352 
353  if ($verif <= 0)
354  {
355  setEventMessages($object->error, $object->errors, 'warnings');
356  $action = 'edit';
357  } else {
358  header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
359  exit;
360  }
361  } else {
362  setEventMessages($langs->trans("NotEnoughPermissions"), null, 'errors');
363  $action = '';
364  }
365  } else {
366  setEventMessages($langs->trans("ErrorBadStatus"), null, 'errors');
367  $action = '';
368  }
369  }
370 
371  // If delete of request
372  if ($action == 'confirm_delete' && GETPOST('confirm') == 'yes' && $user->rights->holiday->delete)
373  {
374  $error = 0;
375 
376  $db->begin();
377 
378  $object->fetch($id);
379 
380  // If this is a rough draft, approved, canceled or refused
381  if ($object->statut == Holiday::STATUS_DRAFT || $object->statut == Holiday::STATUS_CANCELED || $object->statut == Holiday::STATUS_REFUSED)
382  {
383  // Si l'utilisateur à le droit de lire cette demande, il peut la supprimer
384  if ($candelete)
385  {
386  $result = $object->delete($user);
387  } else {
388  $error++;
389  setEventMessages($langs->trans('ErrorCantDeleteCP'), null, 'errors');
390  $action = '';
391  }
392  }
393 
394  if (!$error)
395  {
396  $db->commit();
397  header('Location: list.php?restore_lastsearch_values=1');
398  exit;
399  } else {
400  $db->rollback();
401  }
402  }
403 
404  // Action validate (+ send email for approval)
405  if ($action == 'confirm_send')
406  {
407  $object->fetch($id);
408 
409  // If draft and owner of leave
410  if ($object->statut == Holiday::STATUS_DRAFT && $cancreate)
411  {
412  $object->oldcopy = dol_clone($object);
413 
414  $object->statut = Holiday::STATUS_VALIDATED;
415 
416  $verif = $object->validate($user);
417 
418  // Si pas d'erreur SQL on redirige vers la fiche de la demande
419  if ($verif > 0)
420  {
421  // To
422  $destinataire = new User($db);
423  $destinataire->fetch($object->fk_validator);
424  $emailTo = $destinataire->email;
425 
426  if (!$emailTo)
427  {
428  dol_syslog("Expected validator has no email, so we redirect directly to finished page without sending email");
429  header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
430  exit;
431  }
432 
433  // From
434  $expediteur = new User($db);
435  $expediteur->fetch($object->fk_user);
436  //$emailFrom = $expediteur->email; Email of user can be an email into another company. Sending will fails, we must use the generic email.
437  $emailFrom = $conf->global->MAIN_MAIL_EMAIL_FROM;
438 
439  // Subject
440  $societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
441  if (!empty($conf->global->MAIN_APPLICATION_TITLE)) $societeName = $conf->global->MAIN_APPLICATION_TITLE;
442 
443  $subject = $societeName." - ".$langs->transnoentitiesnoconv("HolidaysToValidate");
444 
445  // Content
446  $message = $langs->transnoentitiesnoconv("Hello")." ".$destinataire->firstname.",\n";
447  $message .= "\n";
448 
449  $message .= $langs->transnoentities("HolidaysToValidateBody")."\n";
450 
451  $delayForRequest = $object->getConfCP('delayForRequest');
452  //$delayForRequest = $delayForRequest * (60*60*24);
453 
454  $nextMonth = dol_time_plus_duree($now, $delayForRequest, 'd');
455 
456  // Si l'option pour avertir le valideur en cas de délai trop court
457  if ($object->getConfCP('AlertValidatorDelay'))
458  {
459  if ($object->date_debut < $nextMonth)
460  {
461  $message .= "\n";
462  $message .= $langs->transnoentities("HolidaysToValidateDelay", $object->getConfCP('delayForRequest'))."\n";
463  }
464  }
465 
466  // Si l'option pour avertir le valideur en cas de solde inférieur à la demande
467  if ($object->getConfCP('AlertValidatorSolde'))
468  {
469  $nbopenedday = num_open_day($object->date_debut_gmt, $object->date_fin_gmt, 0, 1, $object->halfday);
470  if ($nbopenedday > $object->getCPforUser($object->fk_user, $object->fk_type))
471  {
472  $message .= "\n";
473  $message .= $langs->transnoentities("HolidaysToValidateAlertSolde")."\n";
474  }
475  }
476 
477  $message .= "\n";
478  $message .= "- ".$langs->transnoentitiesnoconv("Name")." : ".dolGetFirstLastname($expediteur->firstname, $expediteur->lastname)."\n";
479  $message .= "- ".$langs->transnoentitiesnoconv("Period")." : ".dol_print_date($object->date_debut, 'day')." ".$langs->transnoentitiesnoconv("To")." ".dol_print_date($object->date_fin, 'day')."\n";
480  $message .= "- ".$langs->transnoentitiesnoconv("Link")." : ".$dolibarr_main_url_root."/holiday/card.php?id=".$object->id."\n\n";
481  $message .= "\n";
482 
483  $trackid = 'leav'.$object->id;
484 
485  $mail = new CMailFile($subject, $emailTo, $emailFrom, $message, array(), array(), array(), '', '', 0, 0, '', '', $trackid);
486 
487  // Envoi du mail
488  $result = $mail->sendfile();
489 
490  if (!$result)
491  {
492  setEventMessages($mail->error, $mail->errors, 'warnings');
493  $action = '';
494  } else {
495  header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
496  exit;
497  }
498  } else {
499  setEventMessages($object->error, $object->errors, 'errors');
500  $action = '';
501  }
502  }
503  }
504 
505  if ($action == 'update_extras')
506  {
507  $object->oldcopy = dol_clone($object);
508 
509  // Fill array 'array_options' with data from update form
510  $ret = $extrafields->setOptionalsFromPost(null, $object, GETPOST('attribute', 'restricthtml'));
511  if ($ret < 0) $error++;
512 
513  if (!$error)
514  {
515  // Actions on extra fields
516  $result = $object->insertExtraFields('HOLIDAY_MODIFY');
517  if ($result < 0)
518  {
519  setEventMessages($object->error, $object->errors, 'errors');
520  $error++;
521  }
522  }
523 
524  if ($error)
525  $action = 'edit_extras';
526  }
527 
528  // Approve leave request
529  if ($action == 'confirm_valid')
530  {
531  $object->fetch($id);
532 
533  // If status is waiting approval and approver is also user
534  if ($object->statut == Holiday::STATUS_VALIDATED && $user->id == $object->fk_validator)
535  {
536  $object->oldcopy = dol_clone($object);
537 
538  $object->date_valid = dol_now();
539  $object->fk_user_valid = $user->id;
540  $object->statut = Holiday::STATUS_APPROVED;
541 
542  $db->begin();
543 
544  $verif = $object->approve($user);
545  if ($verif <= 0)
546  {
547  setEventMessages($object->error, $object->errors, 'errors');
548  $error++;
549  }
550 
551  // Si pas d'erreur SQL on redirige vers la fiche de la demande
552  if (!$error)
553  {
554  // Calculcate number of days consummed
555  $nbopenedday = num_open_day($object->date_debut_gmt, $object->date_fin_gmt, 0, 1, $object->halfday);
556  $soldeActuel = $object->getCpforUser($object->fk_user, $object->fk_type);
557  $newSolde = ($soldeActuel - $nbopenedday);
558 
559  // On ajoute la modification dans le LOG
560  $result = $object->addLogCP($user->id, $object->fk_user, $langs->transnoentitiesnoconv("Holidays"), $newSolde, $object->fk_type);
561  if ($result < 0)
562  {
563  $error++;
564  setEventMessages(null, $object->errors, 'errors');
565  }
566 
567  //Update balance
568  $result = $object->updateSoldeCP($object->fk_user, $newSolde, $object->fk_type);
569  if ($result < 0)
570  {
571  $error++;
572  setEventMessages(null, $object->errors, 'errors');
573  }
574  }
575 
576  if (!$error)
577  {
578  // To
579  $destinataire = new User($db);
580  $destinataire->fetch($object->fk_user);
581  $emailTo = $destinataire->email;
582 
583  if (!$emailTo)
584  {
585  dol_syslog("User that request leave has no email, so we redirect directly to finished page without sending email");
586  } else {
587  // From
588  $expediteur = new User($db);
589  $expediteur->fetch($object->fk_validator);
590  //$emailFrom = $expediteur->email; Email of user can be an email into another company. Sending will fails, we must use the generic email.
591  $emailFrom = $conf->global->MAIN_MAIL_EMAIL_FROM;
592 
593  // Subject
594  $societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
595  if (!empty($conf->global->MAIN_APPLICATION_TITLE)) $societeName = $conf->global->MAIN_APPLICATION_TITLE;
596 
597  $subject = $societeName." - ".$langs->transnoentitiesnoconv("HolidaysValidated");
598 
599  // Content
600  $message = $langs->transnoentitiesnoconv("Hello")." ".$destinataire->firstname.",\n";
601  $message .= "\n";
602 
603  $message .= $langs->transnoentities("HolidaysValidatedBody", dol_print_date($object->date_debut, 'day'), dol_print_date($object->date_fin, 'day'))."\n";
604 
605  $message .= "- ".$langs->transnoentitiesnoconv("ValidatedBy")." : ".dolGetFirstLastname($expediteur->firstname, $expediteur->lastname)."\n";
606 
607  $message .= "- ".$langs->transnoentitiesnoconv("Link")." : ".$dolibarr_main_url_root."/holiday/card.php?id=".$object->id."\n\n";
608  $message .= "\n";
609 
610  $trackid = 'leav'.$object->id;
611 
612  $mail = new CMailFile($subject, $emailTo, $emailFrom, $message, array(), array(), array(), '', '', 0, 0, '', '', $trackid);
613 
614  // Envoi du mail
615  $result = $mail->sendfile();
616 
617  if (!$result)
618  {
619  setEventMessages($mail->error, $mail->errors, 'warnings'); // Show error, but do no make rollback, so $error is not set to 1
620  $action = '';
621  }
622  }
623  }
624 
625  if (!$error)
626  {
627  $db->commit();
628 
629  header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
630  exit;
631  } else {
632  $db->rollback();
633  $action = '';
634  }
635  }
636  }
637 
638  if ($action == 'confirm_refuse' && GETPOST('confirm', 'alpha') == 'yes')
639  {
640  if (!empty($_POST['detail_refuse']))
641  {
642  $object->fetch($id);
643 
644  // Si statut en attente de validation et valideur = utilisateur
645  if ($object->statut == Holiday::STATUS_VALIDATED && $user->id == $object->fk_validator)
646  {
647  $object->date_refuse = dol_print_date('dayhour', dol_now());
648  $object->fk_user_refuse = $user->id;
649  $object->statut = Holiday::STATUS_REFUSED;
650  $object->detail_refuse = GETPOST('detail_refuse', 'alphanohtml');
651 
652  $db->begin();
653 
654  $verif = $object->update($user);
655  if ($verif <= 0)
656  {
657  $error++;
658  setEventMessages($object->error, $object->errors, 'errors');
659  }
660 
661  // Si pas d'erreur SQL on redirige vers la fiche de la demande
662  if (!$error)
663  {
664  // To
665  $destinataire = new User($db);
666  $destinataire->fetch($object->fk_user);
667  $emailTo = $destinataire->email;
668 
669  if (!$emailTo)
670  {
671  dol_syslog("User that request leave has no email, so we redirect directly to finished page without sending email");
672  } else {
673  // From
674  $expediteur = new User($db);
675  $expediteur->fetch($object->fk_validator);
676  //$emailFrom = $expediteur->email; Email of user can be an email into another company. Sending will fails, we must use the generic email.
677  $emailFrom = $conf->global->MAIN_MAIL_EMAIL_FROM;
678 
679  // Subject
680  $societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
681  if (!empty($conf->global->MAIN_APPLICATION_TITLE)) $societeName = $conf->global->MAIN_APPLICATION_TITLE;
682 
683  $subject = $societeName." - ".$langs->transnoentitiesnoconv("HolidaysRefused");
684 
685  // Content
686  $message = $langs->transnoentitiesnoconv("Hello")." ".$destinataire->firstname.",\n";
687  $message .= "\n";
688 
689  $message .= $langs->transnoentities("HolidaysRefusedBody", dol_print_date($object->date_debut, 'day'), dol_print_date($object->date_fin, 'day'))."\n";
690  $message .= GETPOST('detail_refuse', 'alpha')."\n\n";
691 
692  $message .= "- ".$langs->transnoentitiesnoconv("ModifiedBy")." : ".dolGetFirstLastname($expediteur->firstname, $expediteur->lastname)."\n";
693 
694  $message .= "- ".$langs->transnoentitiesnoconv("Link")." : ".$dolibarr_main_url_root."/holiday/card.php?id=".$object->id."\n\n";
695  $message .= "\n";
696 
697  $trackid = 'leav'.$object->id;
698 
699  $mail = new CMailFile($subject, $emailTo, $emailFrom, $message, array(), array(), array(), '', '', 0, 0, '', '', $trackid);
700 
701  // Envoi du mail
702  $result = $mail->sendfile();
703 
704  if (!$result)
705  {
706  setEventMessages($mail->error, $mail->errors, 'warnings'); // Show error, but do no make rollback, so $error is not set to 1
707  $action = '';
708  }
709  }
710  } else {
711  $action = '';
712  }
713 
714  if (!$error)
715  {
716  $db->commit();
717 
718  header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
719  exit;
720  } else {
721  $db->rollback();
722  $action = '';
723  }
724  }
725  } else {
726  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("DetailRefusCP")), null, 'errors');
727  $action = 'refuse';
728  }
729  }
730 
731 
732  // Si Validation de la demande
733  if ($action == 'confirm_draft' && GETPOST('confirm') == 'yes')
734  {
735  $error = 0;
736 
737  $object->fetch($id);
738 
739  $oldstatus = $object->statut;
740  $object->statut = Holiday::STATUS_DRAFT;
741 
742  $result = $object->update($user);
743  if ($result < 0)
744  {
745  $error++;
746  setEventMessages($langs->trans('ErrorBackToDraft').' '.$object->error, $object->errors, 'errors');
747  }
748 
749  if (!$error)
750  {
751  $db->commit();
752 
753  header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
754  exit;
755  } else {
756  $db->rollback();
757  }
758  }
759 
760  // Si confirmation of cancellation
761  if ($action == 'confirm_cancel' && GETPOST('confirm') == 'yes')
762  {
763  $error = 0;
764 
765  $object->fetch($id);
766 
767  // Si statut en attente de validation et valideur = valideur ou utilisateur, ou droits de faire pour les autres
768  if (($object->statut == Holiday::STATUS_VALIDATED || $object->statut == Holiday::STATUS_APPROVED) && ($user->id == $object->fk_validator || in_array($object->fk_user, $childids)
769  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->holiday->writeall_advance))))
770  {
771  $db->begin();
772 
773  $oldstatus = $object->statut;
774  $object->date_cancel = dol_now();
775  $object->fk_user_cancel = $user->id;
776  $object->statut = Holiday::STATUS_CANCELED;
777 
778  $result = $object->update($user);
779 
780  if ($result >= 0 && $oldstatus == Holiday::STATUS_APPROVED) // holiday was already validated, status 3, so we must increase back the balance
781  {
782  // Calculcate number of days consummed
783  $nbopenedday = num_open_day($object->date_debut_gmt, $object->date_fin_gmt, 0, 1, $object->halfday);
784 
785  $soldeActuel = $object->getCpforUser($object->fk_user, $object->fk_type);
786  $newSolde = ($soldeActuel + $nbopenedday);
787 
788  // On ajoute la modification dans le LOG
789  $result1 = $object->addLogCP($user->id, $object->fk_user, $langs->transnoentitiesnoconv("HolidaysCancelation"), $newSolde, $object->fk_type);
790 
791  // Mise à jour du solde
792  $result2 = $object->updateSoldeCP($object->fk_user, $newSolde, $object->fk_type);
793 
794  if ($result1 < 0 || $result2 < 0)
795  {
796  $error++;
797  setEventMessages($langs->trans('ErrorCantDeleteCP').' '.$object->error, $object->errors, 'errors');
798  }
799  }
800 
801  if (!$error)
802  {
803  $db->commit();
804  } else {
805  $db->rollback();
806  }
807 
808  // Si pas d'erreur SQL on redirige vers la fiche de la demande
809  if (!$error && $result > 0)
810  {
811  // To
812  $destinataire = new User($db);
813  $destinataire->fetch($object->fk_user);
814  $emailTo = $destinataire->email;
815 
816  if (!$emailTo)
817  {
818  header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
819  exit;
820  }
821 
822  // From
823  $expediteur = new User($db);
824  $expediteur->fetch($object->fk_user_cancel);
825  //$emailFrom = $expediteur->email; Email of user can be an email into another company. Sending will fails, we must use the generic email.
826  $emailFrom = $conf->global->MAIN_MAIL_EMAIL_FROM;
827 
828  // Subject
829  $societeName = $conf->global->MAIN_INFO_SOCIETE_NOM;
830  if (!empty($conf->global->MAIN_APPLICATION_TITLE)) $societeName = $conf->global->MAIN_APPLICATION_TITLE;
831 
832  $subject = $societeName." - ".$langs->transnoentitiesnoconv("HolidaysCanceled");
833 
834  // Content
835  $message = $langs->transnoentitiesnoconv("Hello")." ".$destinataire->firstname.",\n";
836  $message .= "\n";
837 
838  $message .= $langs->transnoentities("HolidaysCanceledBody", dol_print_date($object->date_debut, 'day'), dol_print_date($object->date_fin, 'day'))."\n";
839  $message .= "- ".$langs->transnoentitiesnoconv("ModifiedBy")." : ".dolGetFirstLastname($expediteur->firstname, $expediteur->lastname)."\n";
840 
841  $message .= "- ".$langs->transnoentitiesnoconv("Link")." : ".$dolibarr_main_url_root."/holiday/card.php?id=".$object->id."\n\n";
842  $message .= "\n";
843 
844  $trackid = 'leav'.$object->id;
845 
846  $mail = new CMailFile($subject, $emailTo, $emailFrom, $message, array(), array(), array(), '', '', 0, 0, '', '', $trackid);
847 
848  // Envoi du mail
849  $result = $mail->sendfile();
850 
851  if (!$result)
852  {
853  setEventMessages($mail->error, $mail->errors, 'warnings');
854  $action = '';
855  } else {
856  header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
857  exit;
858  }
859  }
860  }
861  }
862 
863  /*
864  // Actions when printing a doc from card
865  include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
866 
867  // Actions to send emails
868  $triggersendname = 'HOLIDAY_SENTBYMAIL';
869  $autocopy='MAIN_MAIL_AUTOCOPY_HOLIDAY_TO';
870  $trackid='leav'.$object->id;
871  include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
872 
873  // Actions to build doc
874  $upload_dir = $conf->holiday->dir_output;
875  $permissiontoadd = $user->rights->holiday->creer;
876  include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
877  */
878 }
879 
880 
881 
882 /*
883  * View
884  */
885 
886 $form = new Form($db);
887 $object = new Holiday($db);
888 
889 $listhalfday = array('morning'=>$langs->trans("Morning"), "afternoon"=>$langs->trans("Afternoon"));
890 
891 llxHeader('', $langs->trans('CPTitreMenu'));
892 
893 if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add')
894 {
895  // If user has no permission to create a leave
896  if ((in_array($fuserid, $childids) && empty($user->rights->holiday->write)) || (!in_array($fuserid, $childids) && (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || empty($user->rights->holiday->writeall_advance))))
897  {
898  $errors[] = $langs->trans('CantCreateCP');
899  } else {
900  // Form to add a leave request
901  print load_fiche_titre($langs->trans('MenuAddCP'), '', 'title_hrm.png');
902 
903  // Error management
904  if (GETPOST('error')) {
905  switch (GETPOST('error')) {
906  case 'datefin' :
907  $errors[] = $langs->trans('ErrorEndDateCP');
908  break;
909  case 'SQL_Create' :
910  $errors[] = $langs->trans('ErrorSQLCreateCP').' <b>'.htmlentities($_GET['msg']).'</b>';
911  break;
912  case 'CantCreate' :
913  $errors[] = $langs->trans('CantCreateCP');
914  break;
915  case 'Valideur' :
916  $errors[] = $langs->trans('InvalidValidatorCP');
917  break;
918  case 'nodatedebut' :
919  $errors[] = $langs->trans('NoDateDebut');
920  break;
921  case 'nodatefin' :
922  $errors[] = $langs->trans('NoDateFin');
923  break;
924  case 'DureeHoliday' :
925  $errors[] = $langs->trans('ErrorDureeCP');
926  break;
927  case 'alreadyCP' :
928  $errors[] = $langs->trans('alreadyCPexist');
929  break;
930  }
931 
932  setEventMessages($errors, null, 'errors');
933  }
934 
935 
936  $delayForRequest = $object->getConfCP('delayForRequest');
937  //$delayForRequest = $delayForRequest * (60*60*24);
938 
939  $nextMonth = dol_time_plus_duree($now, $delayForRequest, 'd');
940 
941  print '<script type="text/javascript">
942  function valider()
943  {
944  if(document.demandeCP.date_debut_.value != "")
945  {
946  if(document.demandeCP.date_fin_.value != "")
947  {
948  if(document.demandeCP.valideur.value != "-1") {
949  return true;
950  }
951  else {
952  alert("'.dol_escape_js($langs->transnoentities('InvalidValidatorCP')).'");
953  return false;
954  }
955  }
956  else
957  {
958  alert("'.dol_escape_js($langs->transnoentities('NoDateFin')).'");
959  return false;
960  }
961  }
962  else
963  {
964  alert("'.dol_escape_js($langs->transnoentities('NoDateDebut')).'");
965  return false;
966  }
967  }
968  </script>'."\n";
969 
970  // Formulaire de demande
971  print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'" onsubmit="return valider()" name="demandeCP">'."\n";
972  print '<input type="hidden" name="token" value="'.newToken().'" />'."\n";
973  print '<input type="hidden" name="action" value="add" />'."\n";
974 
975  if (empty($conf->global->HOLIDAY_HIDE_BALANCE)) {
976  print dol_get_fiche_head('', '', '', -1);
977 
978  $out = '';
979  $typeleaves = $object->getTypes(1, 1);
980  foreach ($typeleaves as $key => $val)
981  {
982  $nb_type = $object->getCPforUser($user->id, $val['rowid']);
983  $nb_holiday += $nb_type;
984 
985  $out .= ' - '.($langs->trans($val['code']) != $val['code'] ? $langs->trans($val['code']) : $val['label']).': <strong>'.($nb_type ? price2num($nb_type) : 0).'</strong><br>';
986  //$out .= ' - '.$val['label'].': <strong>'.($nb_type ?price2num($nb_type) : 0).'</strong><br>';
987  }
988  print $langs->trans('SoldeCPUser', round($nb_holiday, 5)).'<br>';
989  print $out;
990 
992  } elseif (!is_numeric($conf->global->HOLIDAY_HIDE_BALANCE)) {
993  print $langs->trans($conf->global->HOLIDAY_HIDE_BALANCE).'<br>';
994  }
995 
997 
998  //print '<span>'.$langs->trans('DelayToRequestCP',$object->getConfCP('delayForRequest')).'</span><br><br>';
999 
1000  print '<table class="border centpercent">';
1001  print '<tbody>';
1002 
1003  // User for leave request
1004  print '<tr>';
1005  print '<td class="titlefield fieldrequired">'.$langs->trans("User").'</td>';
1006  print '<td>';
1007 
1008  if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || empty($user->rights->holiday->writeall_advance))
1009  {
1010  print img_picto('', 'user').$form->select_dolusers(($fuserid ? $fuserid : $user->id), 'fuserid', 0, '', 0, 'hierarchyme', '', '0,'.$conf->entity, 0, 0, $morefilter, 0, '', 'minwidth200 maxwidth500');
1011  //print '<input type="hidden" name="fuserid" value="'.($fuserid?$fuserid:$user->id).'">';
1012  } else {
1013  print img_picto('', 'user').$form->select_dolusers(GETPOST('fuserid', 'int') ? GETPOST('fuserid', 'int') : $user->id, 'fuserid', 0, '', 0, '', '', '0,'.$conf->entity, 0, 0, $morefilter, 0, '', 'minwidth200 maxwidth500');
1014  }
1015  print '</td>';
1016  print '</tr>';
1017 
1018  // Type
1019  print '<tr>';
1020  print '<td class="fieldrequired">'.$langs->trans("Type").'</td>';
1021  print '<td>';
1022  $typeleaves = $object->getTypes(1, -1);
1023  $arraytypeleaves = array();
1024  foreach ($typeleaves as $key => $val)
1025  {
1026  $labeltoshow = ($langs->trans($val['code']) != $val['code'] ? $langs->trans($val['code']) : $val['label']);
1027  $labeltoshow .= ($val['delay'] > 0 ? ' ('.$langs->trans("NoticePeriod").': '.$val['delay'].' '.$langs->trans("days").')' : '');
1028  $arraytypeleaves[$val['rowid']] = $labeltoshow;
1029  }
1030  print $form->selectarray('type', $arraytypeleaves, (GETPOST('type', 'alpha') ?GETPOST('type', 'alpha') : ''), 1, 0, 0, '', 0, 0, 0, '', '', true);
1031  if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1);
1032  print '</td>';
1033  print '</tr>';
1034 
1035  // Date start
1036  print '<tr>';
1037  print '<td class="fieldrequired">';
1038  print $form->textwithpicto($langs->trans("DateDebCP"), $langs->trans("FirstDayOfHoliday"));
1039  print '</td>';
1040  print '<td>';
1041  // Si la demande ne vient pas de l'agenda
1042  if (!GETPOST('date_debut_')) {
1043  print $form->selectDate(-1, 'date_debut_', 0, 0, 0, '', 1, 1);
1044  } else {
1045  $tmpdate = dol_mktime(0, 0, 0, GETPOST('date_debut_month', 'int'), GETPOST('date_debut_day', 'int'), GETPOST('date_debut_year', 'int'));
1046  print $form->selectDate($tmpdate, 'date_debut_', 0, 0, 0, '', 1, 1);
1047  }
1048  print ' &nbsp; &nbsp; ';
1049  print $form->selectarray('starthalfday', $listhalfday, (GETPOST('starthalfday', 'alpha') ?GETPOST('starthalfday', 'alpha') : 'morning'));
1050  print '</td>';
1051  print '</tr>';
1052 
1053  // Date end
1054  print '<tr>';
1055  print '<td class="fieldrequired">';
1056  print $form->textwithpicto($langs->trans("DateFinCP"), $langs->trans("LastDayOfHoliday"));
1057  print '</td>';
1058  print '<td>';
1059  if (!GETPOST('date_fin_')) {
1060  print $form->selectDate(-1, 'date_fin_', 0, 0, 0, '', 1, 1);
1061  } else {
1062  $tmpdate = dol_mktime(0, 0, 0, GETPOST('date_fin_month', 'int'), GETPOST('date_fin_day', 'int'), GETPOST('date_fin_year', 'int'));
1063  print $form->selectDate($tmpdate, 'date_fin_', 0, 0, 0, '', 1, 1);
1064  }
1065  print ' &nbsp; &nbsp; ';
1066  print $form->selectarray('endhalfday', $listhalfday, (GETPOST('endhalfday', 'alpha') ?GETPOST('endhalfday', 'alpha') : 'afternoon'));
1067  print '</td>';
1068  print '</tr>';
1069 
1070  // Approver
1071  print '<tr>';
1072  print '<td class="fieldrequired">'.$langs->trans("ReviewedByCP").'</td>';
1073  print '<td>';
1074 
1075  $object = new Holiday($db);
1076  $include_users = $object->fetch_users_approver_holiday();
1077  if (empty($include_users)) {
1078  print img_warning().' '.$langs->trans("NobodyHasPermissionToValidateHolidays");
1079  } else {
1080  $defaultselectuser = (empty($user->fk_user_holiday_validator) ? $user->fk_user : $user->fk_user_holiday_validator); // Will work only if supervisor has permission to approve so is inside include_users
1081  if (!empty($conf->global->HOLIDAY_DEFAULT_VALIDATOR)) $defaultselectuser = $conf->global->HOLIDAY_DEFAULT_VALIDATOR; // Can force default approver
1082  if (GETPOST('valideur', 'int') > 0) $defaultselectuser = GETPOST('valideur', 'int');
1083  $s = $form->select_dolusers($defaultselectuser, "valideur", 1, '', 0, $include_users, '', '0,'.$conf->entity, 0, 0, '', 0, '', 'minwidth200 maxwidth500');
1084  print img_picto('', 'user').$form->textwithpicto($s, $langs->trans("AnyOtherInThisListCanValidate"));
1085  }
1086 
1087  //print $form->select_dolusers((GETPOST('valideur','int')>0?GETPOST('valideur','int'):$user->fk_user), "valideur", 1, ($user->admin ? '' : array($user->id)), 0, '', 0, 0, 0, 0, '', 0, '', '', 1); // By default, hierarchical parent
1088  print '</td>';
1089  print '</tr>';
1090 
1091  // Description
1092  print '<tr>';
1093  print '<td>'.$langs->trans("DescCP").'</td>';
1094  print '<td class="tdtop">';
1095  $doleditor = new DolEditor('description', GETPOST('description', 'restricthtml'), '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%');
1096  print $doleditor->Create(1);
1097  print '</td></tr>';
1098 
1099  // Other attributes
1100  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
1101 
1102  print '</tbody>';
1103  print '</table>';
1104 
1105  print dol_get_fiche_end();
1106 
1107  print '<div class="center">';
1108  print '<input type="submit" value="'.$langs->trans("SendRequestCP").'" name="bouton" class="button">';
1109  print '&nbsp; &nbsp; ';
1110  print '<input type="button" value="'.$langs->trans("Cancel").'" class="button button-cancel" onclick="history.go(-1)">';
1111  print '</div>';
1112 
1113  print '</from>'."\n";
1114  }
1115 } else {
1116  if ($error) {
1117  print '<div class="tabBar">';
1118  print $error;
1119  print '<br><br><input type="button" value="'.$langs->trans("ReturnCP").'" class="button" onclick="history.go(-1)" />';
1120  print '</div>';
1121  } else {
1122  // Affichage de la fiche d'une demande de congés payés
1123  if (($id > 0) || $ref)
1124  {
1125  $result = $object->fetch($id, $ref);
1126 
1127  $valideur = new User($db);
1128  $valideur->fetch($object->fk_validator);
1129 
1130  $userRequest = new User($db);
1131  $userRequest->fetch($object->fk_user);
1132 
1133  //print load_fiche_titre($langs->trans('TitreRequestCP'));
1134 
1135  // Si il y a une erreur
1136  if (GETPOST('error'))
1137  {
1138  switch (GETPOST('error'))
1139  {
1140  case 'datefin' :
1141  $errors[] = $langs->transnoentitiesnoconv('ErrorEndDateCP');
1142  break;
1143  case 'SQL_Create' :
1144  $errors[] = $langs->transnoentitiesnoconv('ErrorSQLCreateCP').' '.$_GET['msg'];
1145  break;
1146  case 'CantCreate' :
1147  $errors[] = $langs->transnoentitiesnoconv('CantCreateCP');
1148  break;
1149  case 'Valideur' :
1150  $errors[] = $langs->transnoentitiesnoconv('InvalidValidatorCP');
1151  break;
1152  case 'nodatedebut' :
1153  $errors[] = $langs->transnoentitiesnoconv('NoDateDebut');
1154  break;
1155  case 'nodatefin' :
1156  $errors[] = $langs->transnoentitiesnoconv('NoDateFin');
1157  break;
1158  case 'DureeHoliday' :
1159  $errors[] = $langs->transnoentitiesnoconv('ErrorDureeCP');
1160  break;
1161  case 'NoMotifRefuse' :
1162  $errors[] = $langs->transnoentitiesnoconv('NoMotifRefuseCP');
1163  break;
1164  case 'mail' :
1165  $errors[] = $langs->transnoentitiesnoconv('ErrorMailNotSend')."\n".$_GET['error_content'];
1166  break;
1167  }
1168 
1169  setEventMessages($errors, null, 'errors');
1170  }
1171 
1172  // On vérifie si l'utilisateur à le droit de lire cette demande
1173  if ($cancreate)
1174  {
1175  $head = holiday_prepare_head($object);
1176 
1177  if (($action == 'edit' && $object->statut == Holiday::STATUS_DRAFT) || ($action == 'editvalidator'))
1178  {
1179  if ($action == 'edit' && $object->statut == Holiday::STATUS_DRAFT) $edit = true;
1180 
1181  print '<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">'."\n";
1182  print '<input type="hidden" name="token" value="'.newToken().'" />'."\n";
1183  print '<input type="hidden" name="action" value="update"/>'."\n";
1184  print '<input type="hidden" name="id" value="'.$object->id.'" />'."\n";
1185  }
1186 
1187  print dol_get_fiche_head($head, 'card', $langs->trans("CPTitreMenu"), -1, 'holiday');
1188 
1189  $linkback = '<a href="'.DOL_URL_ROOT.'/holiday/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
1190 
1191  dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref');
1192 
1193 
1194  print '<div class="fichecenter">';
1195  print '<div class="fichehalfleft">';
1196  print '<div class="underbanner clearboth"></div>';
1197 
1198  print '<table class="border tableforfield centpercent">';
1199  print '<tbody>';
1200 
1201  // User
1202  print '<tr>';
1203  print '<td class="titlefield">'.$langs->trans("User").'</td>';
1204  print '<td>';
1205  print $userRequest->getNomUrl(-1, 'leave');
1206  print '</td></tr>';
1207 
1208  // Type
1209  print '<tr>';
1210  print '<td>'.$langs->trans("Type").'</td>';
1211  print '<td>';
1212  $typeleaves = $object->getTypes(1, -1);
1213  $labeltoshow = (($typeleaves[$object->fk_type]['code'] && $langs->trans($typeleaves[$object->fk_type]['code']) != $typeleaves[$object->fk_type]['code']) ? $langs->trans($typeleaves[$object->fk_type]['code']) : $typeleaves[$object->fk_type]['label']);
1214  print empty($labeltoshow) ? $langs->trans("TypeWasDisabledOrRemoved", $object->fk_type) : $labeltoshow;
1215  print '</td>';
1216  print '</tr>';
1217 
1218  $starthalfday = ($object->halfday == -1 || $object->halfday == 2) ? 'afternoon' : 'morning';
1219  $endhalfday = ($object->halfday == 1 || $object->halfday == 2) ? 'morning' : 'afternoon';
1220 
1221  if (!$edit)
1222  {
1223  print '<tr>';
1224  print '<td class="nowrap">';
1225  print $form->textwithpicto($langs->trans('DateDebCP'), $langs->trans("FirstDayOfHoliday"));
1226  print '</td>';
1227  print '<td>'.dol_print_date($object->date_debut, 'day');
1228  print ' &nbsp; &nbsp; ';
1229  print '<span class="opacitymedium">'.$langs->trans($listhalfday[$starthalfday]).'</span>';
1230  print '</td>';
1231  print '</tr>';
1232  } else {
1233  print '<tr>';
1234  print '<td class="nowrap">';
1235  print $form->textwithpicto($langs->trans('DateDebCP'), $langs->trans("FirstDayOfHoliday"));
1236  print '</td>';
1237  print '<td>';
1238  print $form->selectDate($object->date_debut, 'date_debut_');
1239  print ' &nbsp; &nbsp; ';
1240  print $form->selectarray('starthalfday', $listhalfday, (GETPOST('starthalfday') ?GETPOST('starthalfday') : $starthalfday));
1241  print '</td>';
1242  print '</tr>';
1243  }
1244 
1245  if (!$edit)
1246  {
1247  print '<tr>';
1248  print '<td class="nowrap">';
1249  print $form->textwithpicto($langs->trans('DateFinCP'), $langs->trans("LastDayOfHoliday"));
1250  print '</td>';
1251  print '<td>'.dol_print_date($object->date_fin, 'day');
1252  print ' &nbsp; &nbsp; ';
1253  print '<span class="opacitymedium">'.$langs->trans($listhalfday[$endhalfday]).'</span>';
1254  print '</td>';
1255  print '</tr>';
1256  } else {
1257  print '<tr>';
1258  print '<td class="nowrap">';
1259  print $form->textwithpicto($langs->trans('DateFinCP'), $langs->trans("LastDayOfHoliday"));
1260  print '</td>';
1261  print '<td>';
1262  print $form->selectDate($object->date_fin, 'date_fin_');
1263  print ' &nbsp; &nbsp; ';
1264  print $form->selectarray('endhalfday', $listhalfday, (GETPOST('endhalfday') ?GETPOST('endhalfday') : $endhalfday));
1265  print '</td>';
1266  print '</tr>';
1267  }
1268 
1269  // Nb of days
1270  print '<tr>';
1271  print '<td>';
1272  $htmlhelp = $langs->trans('NbUseDaysCPHelp');
1273  $includesaturday = (isset($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY) ? $conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY : 1);
1274  $includesunday = (isset($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY) ? $conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY : 1);
1275  if ($includesaturday) $htmlhelp .= '<br>'.$langs->trans("DayIsANonWorkingDay", $langs->trans("Saturday"));
1276  if ($includesunday) $htmlhelp .= '<br>'.$langs->trans("DayIsANonWorkingDay", $langs->trans("Sunday"));
1277  print $form->textwithpicto($langs->trans('NbUseDaysCP'), $htmlhelp);
1278  print '</td>';
1279  print '<td>';
1280  print num_open_day($object->date_debut_gmt, $object->date_fin_gmt, 0, 1, $object->halfday);
1281  print '</td>';
1282  print '</tr>';
1283 
1284  if ($object->statut == Holiday::STATUS_REFUSED)
1285  {
1286  print '<tr>';
1287  print '<td>'.$langs->trans('DetailRefusCP').'</td>';
1288  print '<td>'.$object->detail_refuse.'</td>';
1289  print '</tr>';
1290  }
1291 
1292  // Description
1293  if (!$edit)
1294  {
1295  print '<tr>';
1296  print '<td>'.$langs->trans('DescCP').'</td>';
1297  print '<td>'.nl2br($object->description).'</td>';
1298  print '</tr>';
1299  } else {
1300  print '<tr>';
1301  print '<td>'.$langs->trans('DescCP').'</td>';
1302  print '<td class="tdtop">';
1303  $doleditor = new DolEditor('description', $object->description, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%');
1304  print $doleditor->Create(1);
1305  print '</td></tr>';
1306  }
1307 
1308  // Other attributes
1309  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
1310 
1311  print '</tbody>';
1312  print '</table>'."\n";
1313 
1314  print '</div>';
1315  print '<div class="fichehalfright">';
1316  print '<div class="ficheaddleft">';
1317 
1318  print '<div class="underbanner clearboth"></div>';
1319 
1320  // Info workflow
1321  print '<table class="border tableforfield centpercent">'."\n";
1322  print '<tbody>';
1323 
1324  if (!empty($object->fk_user_create))
1325  {
1326  $userCreate = new User($db);
1327  $userCreate->fetch($object->fk_user_create);
1328  print '<tr>';
1329  print '<td class="titlefield">'.$langs->trans('RequestByCP').'</td>';
1330  print '<td>'.$userCreate->getNomUrl(-1).'</td>';
1331  print '</tr>';
1332  }
1333 
1334  // Approver
1335  if (!$edit && $action != 'editvalidator') {
1336  print '<tr>';
1337  print '<td class="titlefield">';
1338  if ($object->statut == Holiday::STATUS_APPROVED || $object->statut == Holiday::STATUS_CANCELED) print $langs->trans('ApprovedBy');
1339  else print $langs->trans('ReviewedByCP');
1340  print '</td>';
1341  print '<td>'.$valideur->getNomUrl(-1);
1342  $include_users = $object->fetch_users_approver_holiday();
1343  if (is_array($include_users) && in_array($user->id, $include_users) && $object->statut == Holiday::STATUS_VALIDATED)
1344  {
1345  print '<a class="editfielda paddingleft" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=editvalidator">'.img_edit($langs->trans("Edit")).'</a>';
1346  }
1347  print '</td>';
1348  print '</tr>';
1349  } else {
1350  print '<tr>';
1351  print '<td class="titlefield">'.$langs->trans('ReviewedByCP').'</td>';
1352  print '<td>';
1353  $include_users = $object->fetch_users_approver_holiday();
1354  if (!in_array($object->fk_validator, $include_users)) // Add the current validator to the list to not lose it when editing.
1355  {
1356  $include_users[] = $object->fk_validator;
1357  }
1358  if (empty($include_users)) print img_warning().' '.$langs->trans("NobodyHasPermissionToValidateHolidays");
1359  else {
1360  $arrayofvalidatorstoexclude = (($user->admin || ($user->id != $userRequest->id)) ? '' : array($user->id)); // Nobody if we are admin or if we are not the user of the leave.
1361  $s = $form->select_dolusers($object->fk_validator, "valideur", (($action == 'editvalidator') ? 0 : 1), $arrayofvalidatorstoexclude, 0, $include_users);
1362  print $form->textwithpicto($s, $langs->trans("AnyOtherInThisListCanValidate"));
1363  }
1364  if ($action == 'editvalidator')
1365  {
1366  print '<input type="submit" class="button button-save" name="savevalidator" value="'.$langs->trans("Save").'">';
1367  print '<input type="submit" class="button button-cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
1368  }
1369  print '</td>';
1370  print '</tr>';
1371  }
1372 
1373  print '<tr>';
1374  print '<td>'.$langs->trans('DateCreation').'</td>';
1375  print '<td>'.dol_print_date($object->date_create, 'dayhour', 'tzuser').'</td>';
1376  print '</tr>';
1377  if ($object->statut == Holiday::STATUS_APPROVED || $object->statut == Holiday::STATUS_CANCELED) {
1378  print '<tr>';
1379  print '<td>'.$langs->trans('DateValidCP').'</td>';
1380  print '<td>'.dol_print_date($object->date_valid, 'dayhour', 'tzuser').'</td>'; // warning: date_valid is approval date on holiday module
1381  print '</tr>';
1382  }
1383  if ($object->statut == Holiday::STATUS_CANCELED) {
1384  print '<tr>';
1385  print '<td>'.$langs->trans('DateCancelCP').'</td>';
1386  print '<td>'.dol_print_date($object->date_cancel, 'dayhour', 'tzuser').'</td>';
1387  print '</tr>';
1388  }
1389  if ($object->statut == Holiday::STATUS_REFUSED) {
1390  print '<tr>';
1391  print '<td>'.$langs->trans('DateRefusCP').'</td>';
1392  print '<td>'.dol_print_date($object->date_refuse, 'dayhour', 'tzuser').'</td>';
1393  print '</tr>';
1394  }
1395  print '</tbody>';
1396  print '</table>';
1397 
1398  print '</div>';
1399  print '</div>';
1400  print '</div>';
1401 
1402  print '<div class="clearboth"></div>';
1403 
1404  print dol_get_fiche_end();
1405 
1406 
1407  // Confirmation messages
1408  if ($action == 'delete')
1409  {
1410  if ($user->rights->holiday->delete)
1411  {
1412  print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("TitleDeleteCP"), $langs->trans("ConfirmDeleteCP"), "confirm_delete", '', 0, 1);
1413  }
1414  }
1415 
1416  // Si envoi en validation
1417  if ($action == 'sendToValidate' && $object->statut == Holiday::STATUS_DRAFT)
1418  {
1419  print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("TitleToValidCP"), $langs->trans("ConfirmToValidCP"), "confirm_send", '', 1, 1);
1420  }
1421 
1422  // Si validation de la demande
1423  if ($action == 'valid')
1424  {
1425  print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("TitleValidCP"), $langs->trans("ConfirmValidCP"), "confirm_valid", '', 1, 1);
1426  }
1427 
1428  // Si refus de la demande
1429  if ($action == 'refuse')
1430  {
1431  $array_input = array(array('type'=>"text", 'label'=> $langs->trans('DetailRefusCP'), 'name'=>"detail_refuse", 'size'=>"50", 'value'=>""));
1432  print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id."&action=confirm_refuse", $langs->trans("TitleRefuseCP"), $langs->trans('ConfirmRefuseCP'), "confirm_refuse", $array_input, 1, 0);
1433  }
1434 
1435  // Si annulation de la demande
1436  if ($action == 'cancel')
1437  {
1438  print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("TitleCancelCP"), $langs->trans("ConfirmCancelCP"), "confirm_cancel", '', 1, 1);
1439  }
1440 
1441  // Si back to draft
1442  if ($action == 'backtodraft')
1443  {
1444  print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("TitleSetToDraft"), $langs->trans("ConfirmSetToDraft"), "confirm_draft", '', 1, 1);
1445  }
1446 
1447  if (($action == 'edit' && $object->statut == Holiday::STATUS_DRAFT) || ($action == 'editvalidator'))
1448  {
1449  if ($action == 'edit' && $object->statut == Holiday::STATUS_DRAFT)
1450  {
1451  print '<div class="center">';
1452  if ($cancreate && $object->statut == Holiday::STATUS_DRAFT)
1453  {
1454  print '<input type="submit" value="'.$langs->trans("Save").'" class="button button-save">';
1455  }
1456  print '</div>';
1457  }
1458 
1459  print '</form>';
1460  }
1461 
1462  if (!$edit)
1463  {
1464  // Buttons for actions
1465 
1466  print '<div class="tabsAction">';
1467 
1468  if ($cancreate && $object->statut == Holiday::STATUS_DRAFT)
1469  {
1470  print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit" class="butAction">'.$langs->trans("EditCP").'</a>';
1471  }
1472  if ($cancreate && $object->statut == Holiday::STATUS_DRAFT) // If draft
1473  {
1474  print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=sendToValidate" class="butAction">'.$langs->trans("Validate").'</a>';
1475  }
1476  if ($object->statut == Holiday::STATUS_VALIDATED) // If validated
1477  {
1478  if ($user->id == $object->fk_validator)
1479  {
1480  print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=valid" class="butAction">'.$langs->trans("Approve").'</a>';
1481  print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=refuse" class="butAction">'.$langs->trans("ActionRefuseCP").'</a>';
1482  } else {
1483  print '<a href="#" class="butActionRefused classfortooltip" title="'.$langs->trans("NotTheAssignedApprover").'">'.$langs->trans("Approve").'</a>';
1484  print '<a href="#" class="butActionRefused classfortooltip" title="'.$langs->trans("NotTheAssignedApprover").'">'.$langs->trans("ActionRefuseCP").'</a>';
1485  }
1486  }
1487  if (($user->id == $object->fk_validator || in_array($object->fk_user, $childids) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->holiday->writeall_advance))) && ($object->statut == 2 || $object->statut == 3)) // Status validated or approved
1488  {
1489  if (($object->date_debut > dol_now()) || $user->admin) print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=cancel" class="butAction">'.$langs->trans("ActionCancelCP").'</a>';
1490  else print '<a href="#" class="butActionRefused classfortooltip" title="'.$langs->trans("HolidayStarted").'">'.$langs->trans("ActionCancelCP").'</a>';
1491  }
1492  if ($cancreate && $object->statut == Holiday::STATUS_CANCELED)
1493  {
1494  print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=backtodraft" class="butAction">'.$langs->trans("SetToDraft").'</a>';
1495  }
1496  if ($candelete && ($object->statut == Holiday::STATUS_DRAFT || $object->statut == Holiday::STATUS_CANCELED || $object->statut == Holiday::STATUS_REFUSED)) // If draft or canceled or refused
1497  {
1498  print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken().'" class="butActionDelete">'.$langs->trans("DeleteCP").'</a>';
1499  }
1500 
1501  print '</div>';
1502  }
1503  } else {
1504  print '<div class="tabBar">';
1505  print $langs->trans('ErrorUserViewCP');
1506  print '<br><br><input type="button" value="'.$langs->trans("ReturnCP").'" class="button" onclick="history.go(-1)" />';
1507  print '</div>';
1508  }
1509  } else {
1510  print '<div class="tabBar">';
1511  print $langs->trans('ErrorIDFicheCP');
1512  print '<br><br><input type="button" value="'.$langs->trans("ReturnCP").'" class="button" onclick="history.go(-1)" />';
1513  print '</div>';
1514  }
1515 
1516 
1517  // Select mail models is same action as presend
1518  if (GETPOST('modelselected')) {
1519  $action = 'presend';
1520  }
1521 
1522  if ($action != 'presend')
1523  {
1524  print '<div class="fichecenter"><div class="fichehalfleft">';
1525  print '<a name="builddoc"></a>'; // ancre
1526 
1527  $includedocgeneration = 0;
1528 
1529  // Documents
1530  if ($includedocgeneration) {
1531  $objref = dol_sanitizeFileName($object->ref);
1532  $relativepath = $objref.'/'.$objref.'.pdf';
1533  $filedir = $conf->holiday->dir_output.'/'.$object->element.'/'.$objref;
1534  $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
1535  $genallowed = ($user->rights->holiday->read && $object->fk_user == $user->id) || !empty($user->rights->holiday->readall); // If you can read, you can build the PDF to read content
1536  $delallowed = ($user->rights->holiday->write && $object->fk_user == $user->id) || !empty($user->rights->holiday->writeall_advance); // If you can create/edit, you can remove a file on card
1537  print $formfile->showdocuments('holiday:Holiday', $object->element.'/'.$objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang);
1538  }
1539 
1540  // Show links to link elements
1541  //$linktoelem = $form->showLinkToObjectBlock($object, null, array('myobject'));
1542  //$somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
1543 
1544 
1545  print '</div><div class="fichehalfright"><div class="ficheaddleft">';
1546 
1547  $MAXEVENT = 10;
1548 
1549  /*$morehtmlright = '<a href="'.dol_buildpath('/holiday/myobject_agenda.php', 1).'?id='.$object->id.'">';
1550  $morehtmlright .= $langs->trans("SeeAll");
1551  $morehtmlright .= '</a>';*/
1552 
1553  // List of actions on element
1554  include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
1555  $formactions = new FormActions($db);
1556  $somethingshown = $formactions->showactions($object, $object->element, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlright);
1557 
1558  print '</div></div></div>';
1559  }
1560  }
1561 }
1562 
1563 // End of page
1564 llxFooter();
1565 
1566 if (is_object($db)) $db->close();
GETPOST($paramname, $check= 'alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
Class of the module paid holiday.
img_edit($titlealt= 'default', $float=0, $other= '')
Show logo editer/modifier fiche.
if(preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) if(preg_match('/del_([a-z0-9_\-]+)/i', $action, $reg)) if($action== 'set') elseif($action== 'specimen') elseif($action== 'setmodel') elseif($action== 'del') elseif($action== 'setdoc') $formactions
View.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm= 'auto', $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
Class to manage building of HTML components.
holiday_prepare_head($object)
Return array head with list of tabs to view object informations.
Definition: holiday.lib.php:30
</td > param sortfield sortorder printFieldListOption< tdclass="liste_titremaxwidthsearchright"></td ></tr >< trclass="liste_titre">< inputtype="checkbox"onClick="toggle(this)"/> Ref p ref Label p label Duration p duration center DesiredStock p desiredstock right StockLimitShort p seuil_stock_alerte right stock_physique right stock_real_warehouse right Ordered right StockToBuy right SupplierRef right param sortfield sortorder printFieldListTitle warehouseinternal SELECT description FROM product_lang WHERE qty< br > qty qty qty StockTooLow StockTooLow help help help< trclass="oddeven">< td >< inputtype="checkbox"class="check"name="choose'.$i.'"></td >< tdclass="nowrap"> stock</td >< td >< inputtype="hidden"name="desc'.$i.'"value="'.dol_escape_htmltag($objp-> description
Only used if Module[ID]Desc translation string is not found.
Definition: replenish.php:750
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into javascript code.
dol_now($mode= 'auto')
Return date for now.
Class to manage Dolibarr users.
Definition: user.class.php:44
dol_clone($object, $native=0)
Create a clone of instance of object (new instance with same value for properties) With native = 0: P...
img_warning($titlealt= 'default', $moreatt= '', $morecss= 'pictowarning')
Show warning logo.
llxHeader()
Empty header.
Definition: wrapper.php:45
Class to manage standard extra fields.
setEventMessages($mesg, $mesgs, $style= 'mesgs', $messagekey= '')
Set event messages in dol_events session object.
Class to manage generation of HTML components Only common components must be here.
const STATUS_DRAFT
Draft status.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname.
load_fiche_titre($titre, $morehtmlright= '', $picto= 'generic', $pictoisfullpath=0, $id= '', $morecssontable= '', $morehtmlcenter= '')
Load a title with picto.
price2num($amount, $rounding= '', $option=0)
Function that return a number with universal decimal format (decimal separator is &#39;...
Class to send emails (with attachments or not) Usage: $mailfile = new CMailFile($subject,$sendto,$replyto,$message,$filepath,$mimetype,$filename,$cc,$ccc,$deliveryreceipt,$msgishtml,$errors_to,$css,$trackid,$moreinheader,$sendcontext,$replyto); $mailfile-&gt;sendfile();.
img_picto($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt= '', $morecss= '', $marginleftonlyshort=2)
Show picto whatever it&#39;s its name (generic function)
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename= '', $restricttologhandler= '', $logcontext=null)
Write log message into outputs.
num_open_day($timestampStart, $timestampEnd, $inhour=0, $lastday=0, $halfday=0, $country_code= '')
Function to return number of working days (and text of units) between two dates (working days) ...
Definition: date.lib.php:863
restrictedArea($user, $features, $objectid=0, $tableandshare= '', $feature2= '', $dbt_keyfield= 'fk_soc', $dbt_select= 'rowid', $isdraft=0)
Check permissions of a user to show a page and an object.
accessforbidden($message= '', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program Calling this function terminate execution ...
const STATUS_APPROVED
Approved.
dol_sanitizeFileName($str, $newstr= '_', $unaccent=1)
Clean a string to use it as a file name.
print $_SERVER["PHP_SELF"]
Edit parameters.
dol_get_fiche_head($links=array(), $active= '', $title= '', $notab=0, $picto= '', $pictoisfullpath=0, $morehtmlright= '', $morecss= '', $limittoshow=0, $moretabssuffix= '')
Show tabs of a record.
print
Draft customers invoices.
Definition: index.php:89
dol_print_date($time, $format= '', $tzoutput= 'auto', $outputlangs= '', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
const STATUS_VALIDATED
Validated status.
newToken()
Return the value of token currently saved into session with name &#39;newtoken&#39;.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
Class to manage a WYSIWYG editor.
const STATUS_CANCELED
Canceled.
dol_banner_tab($object, $paramid, $morehtml= '', $shownav=1, $fieldid= 'rowid', $fieldref= 'ref', $morehtmlref= '', $moreparam= '', $nodbprefix=0, $morehtmlleft= '', $morehtmlstatus= '', $onlybanner=0, $morehtmlright= '')
Show tab footer of a card.
const STATUS_REFUSED
Refused.
llxFooter()
Empty footer.
Definition: wrapper.php:59
dol_time_plus_duree($time, $duration_value, $duration_unit)
Add a delay to a date.
Definition: date.lib.php:114
if(!defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN'
Draft customers invoices.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin= '1', $morecss= '', $textfordropdown= '')
Show information for admin users or standard users.
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.