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