diff --git a/class/timesheet.class.php b/class/timesheet.class.php index 310ad8c..3eede11 100644 --- a/class/timesheet.class.php +++ b/class/timesheet.class.php @@ -126,8 +126,8 @@ class TimeSheet extends SaturneObject 'fk_user_creat' => ['type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'picto' => 'user', 'enabled' => 1, 'position' => 160, 'notnull' => 1, 'visible' => 0, 'foreignkey' => 'user.rowid'], 'fk_user_modif' => ['type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'picto' => 'user', 'enabled' => 1, 'position' => 170, 'notnull' => 0, 'visible' => 0, 'foreignkey' => 'user.rowid'], 'fk_user_assign' => ['type' => 'integer:User:user/class/user.class.php:1:(t.employee:=:1:AND:t.fk_soc:IS:NULL:AND:t.statut:=:1)', 'label' => 'UserAssign', 'picto' => 'user', 'enabled' => 1, 'position' => 90, 'notnull' => 1, 'visible' => 1, 'index' => 1, 'css' => 'maxwidth500 widthcentpercentminusxx', 'validate' => 1, 'foreignkey' => 'user.rowid'], - 'fk_project' => ['type' => 'integer:Project:projet/class/project.class.php:1', 'label' => 'Project', 'picto' => 'company', 'enabled' => '$conf->project->enabled', 'position' => 80, 'notnull' => 0, 'visible' => 1, 'index' => 1, 'css' => 'maxwidth500 widthcentpercentminusxx', 'validate' => 1, 'foreignkey' => 'projet.rowid'], - 'fk_soc' => ['type' => 'integer:Societe:societe/class/societe.class.php:1', 'label' => 'ThirdParty', 'picto' => 'project', 'enabled' => '$conf->societe->enabled', 'position' => 120, 'notnull' => 0, 'visible' => 1, 'index' => 1, 'css' => 'maxwidth500 widthcentpercentminusxx', 'validate' => 1, 'foreignkey' => 'societe.rowid'], + 'fk_project' => ['type' => 'integer:Project:projet/class/project.class.php:1', 'label' => 'Project', 'picto' => 'project', 'enabled' => '$conf->project->enabled', 'position' => 80, 'notnull' => 0, 'visible' => 1, 'index' => 1, 'css' => 'maxwidth500 widthcentpercentminusxx', 'validate' => 1, 'foreignkey' => 'projet.rowid'], + 'fk_soc' => ['type' => 'integer:Societe:societe/class/societe.class.php:1', 'label' => 'ThirdParty', 'picto' => 'company', 'enabled' => '$conf->societe->enabled', 'position' => 120, 'notnull' => 0, 'visible' => 1, 'index' => 1, 'css' => 'maxwidth500 widthcentpercentminusxx', 'validate' => 1, 'foreignkey' => 'societe.rowid'], ]; /** @@ -470,9 +470,9 @@ class TimeSheetLine extends SaturneObject public ?float $qty; /** - * @var int Rang. + * @var int|null Rang. */ - public int $rang; + public ?int $rang; /** * @var string Description. diff --git a/core/modules/modDoliSIRH.class.php b/core/modules/modDoliSIRH.class.php index 9aaaec1..60de8f5 100644 --- a/core/modules/modDoliSIRH.class.php +++ b/core/modules/modDoliSIRH.class.php @@ -161,7 +161,7 @@ public function __construct($db) $this->hidden = false; // List of module class names as string that must be enabled if this module is enabled. Example: array('always1'=>'modModuleToEnable1','always2'=>'modModuleToEnable2', 'FR1'=>'modModuleToEnableFR'...). - $this->depends = ['modProjet', 'modBookmark', 'modHoliday', 'modFckeditor', 'modSalaries', 'modProduct', 'modService', 'modSociete', 'modECM', 'modCategorie', 'modSaturne', 'modCron']; + $this->depends = ['modProjet', 'modBookmark', 'modHoliday', 'modFckeditor', 'modSalaries', 'modProduct', 'modService', 'modSociete', 'modECM', 'modCategorie', 'modSaturne', 'modCron', 'modAgenda']; $this->requiredby = []; // List of module class names as string to disable if this one is disabled. Example: array('modModuleToDisable1', ...). $this->conflictwith = []; // List of module class names as string this module is in conflict with. Example: array('modModuleToDisable1', ...). diff --git a/langs/fr_FR/dolisirh.lang b/langs/fr_FR/dolisirh.lang index 38e5da1..5d10062 100644 --- a/langs/fr_FR/dolisirh.lang +++ b/langs/fr_FR/dolisirh.lang @@ -103,7 +103,7 @@ ErrorServiceTime = Le temps du(des) service(s) est nul SetupDefaultDataNotCreated = Vous n'avez pas créé les données par défaut de DOLISIRH HowToSetupDefaultData = Pour configurer les données par défaut de DOLISIRH, veuillez cliquer sur ce lien : ConfigDefaultData = Configuration des données par défaut de DOLISIRH -EnableDoliSIRH = Veuillez activer le module DoliSIRH pour accéder à cette page +EnableDolisirh = Veuillez activer le module DoliSIRH pour accéder à cette page CertificateUserResponsible = Responsable des certificats CertificateUserResponsibleDescription = Cette option permet définir l'utilisateur responsable des certificats des différents participants @@ -187,20 +187,8 @@ FacturerecsCategoriesArea = Espace des tags/catégories des factures récu # # SetEventMessage - Notice info -TimeSheetMustBeDraft = La navette doit être en brouillon pour accéder à cette fonctionnalité -TimeSheetMustBeDraftToValidate = La navette est déjà validée -TimeSheetMustBeValidated = La navette doit être validée pour la rouvrir -TimeSheetMustBeValidatedToSign = La navette doit être validée pour que les signataires puissent signer AllSignatoriesMustHaveSignedAndDiffTimeSetAt0 = Tous les signataires doivent avoir signé et l'utilisateur assigné doit avoir consommée toutes ses heures de travail pour verrouiller la navette -TimeSheetMustBeLockedToSendEmail = La navette doit être verrouillée pour envoyer un email -TimeSheetMustBeLocked = La navette doit être verrouillée afin de permettre la génération -TimeSheetMustBeLockedGenerated = La navette doit être verrouillée et le document généré afin de pouvoir l'archiver -ValidateTimeSheet = Valider la navette -ConfirmValidateTimeSheet = Êtes-vous sûr de vouloir valider la navette ?
La validation permet aux signataires de signer le document mais empêche l'ajout de nouveaux signataires ou la modification de la navette.

N'oubliez pas de vérifier les quantités des produits ou services liés. -ReOpenTimeSheet = Ouvrir à nouveau la navette -ConfirmReOpenTimeSheet = Êtes-vous sûr de vouloir rouvrir la navette ? La réouverture permet la modification de la navette et l'ajout de nouveaux signataires mais toutes les signatures du document seront perdues. -LockTimeSheet = Verrouiller la navette -ConfirmLockTimeSheet = Êtes-vous sûr de vouloir verrouiller la navette ?
Ce verrouillage permet de figer les données et la génération du document. +ConfirmValidateTimeSheet =

N'oubliez pas de vérifier les quantités des produits ou services liés. TimeSpentPerfect = Parfait, toutes tes heures de travail ont été consommées TimeSpentMustBeCompleted = Attention, toutes tes heures de travail n'ont pas été consommées (%s - %s)
Va sur ton pointage de temps du mois de %s pour arranger cela TimeSpentDiff = Attention, tu as consommé trop d'heures de travail (%s - %s)
Va sur ton pointage de temps du mois de %s pour arranger cela @@ -218,6 +206,7 @@ GoToConfigProjectPage = Aller sur la page de configurati # Data - Donnée TimeSheet = Navette Timesheet = Navette +TheTimesheet = La navette NewTimeSheet = Nouvelle navette NewTimesheet = Nouvelle navette ModifyTimeSheet = Modifier la navette diff --git a/lib/dolisirh_timespent.lib.php b/lib/dolisirh_timespent.lib.php index 3be84d5..9a1c2c6 100644 --- a/lib/dolisirh_timespent.lib.php +++ b/lib/dolisirh_timespent.lib.php @@ -104,6 +104,7 @@ function load_time_spent_on_tasks_within_range(int $timestampStart, int $timesta $timeSpentOnTasks = ['days' => 0, 'hours' => 0, 'minutes' => 0, 'total' => 0]; $timeSpentList = $task->fetchAllTimeSpent($userTmp, 'AND (ptt.task_date >= "' . $db->idate($timestampStart) . '" AND ptt.task_date < "' . $db->idate($timestampEnd) . '")'); if (is_array($timeSpentList) && !empty($timeSpentList)) { + $workingDays = []; foreach ($timeSpentList as $timeSpent) { $hours = floor($timeSpent->timespent_duration / 3600); $minutes = floor($timeSpent->timespent_duration / 60); @@ -120,9 +121,10 @@ function load_time_spent_on_tasks_within_range(int $timestampStart, int $timesta $timeSpentOnTasks[$timeSpent->fk_task]['task_label'] = $timeSpent->task_label; $timeSpentOnTasks[$timeSpent->fk_task][dol_print_date($timeSpent->timespent_date, 'day')] += $timeSpent->timespent_duration; + $workingDays[$timeSpent->timespent_date] = 1; } } - $timeSpentOnTasks['days'] = count($daysAvailable); + $timeSpentOnTasks['days'] = is_array($workingDays) && !empty($workingDays) ? count($workingDays) : 0; } return $timeSpentOnTasks; diff --git a/view/timesheet/timesheet_card.php b/view/timesheet/timesheet_card.php index eaba6e4..214f059 100644 --- a/view/timesheet/timesheet_card.php +++ b/view/timesheet/timesheet_card.php @@ -16,12 +16,12 @@ */ /** - * \file view/timesheet/timesheet_card.php - * \ingroup dolisirh - * \brief Page to create/edit/view timesheet + * \file view/timesheet/timesheet_card.php + * \ingroup dolisirh + * \brief Page to create/edit/view timesheet. */ -// Load DoliSIRH environment +// Load DoliSIRH environment. if (file_exists('../../dolisirh.main.inc.php')) { require_once __DIR__ . '/../../dolisirh.main.inc.php'; } elseif (file_exists('../../../dolisirh.main.inc.php')) { @@ -30,33 +30,34 @@ die('Include of dolisirh main fails'); } -// Libraries -require_once DOL_DOCUMENT_ROOT .'/core/lib/files.lib.php'; -require_once DOL_DOCUMENT_ROOT .'/core/lib/functions2.lib.php'; -require_once DOL_DOCUMENT_ROOT .'/product/class/product.class.php'; -require_once DOL_DOCUMENT_ROOT .'/holiday/class/holiday.class.php'; +// Load Dolibarr libraries. +require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; +// Load Saturne libraries. +require_once __DIR__ . '/../../../saturne/class/saturnesignature.class.php'; + +// load DoliSIRH libraries. +require_once __DIR__ . '/../../lib/dolisirh_function.lib.php'; +require_once __DIR__ . '/../../lib/dolisirh_timespent.lib.php'; +require_once __DIR__ . '/../../lib/dolisirh_timesheet.lib.php'; require_once __DIR__ . '/../../class/timesheet.class.php'; require_once __DIR__ . '/../../class/dolisirhdocuments/timesheetdocument.class.php'; require_once __DIR__ . '/../../class/workinghours.class.php'; -require_once __DIR__ . '/../../lib/dolisirh_timesheet.lib.php'; -require_once __DIR__ . '/../../lib/dolisirh_function.lib.php'; - -require_once __DIR__ . '/../../../saturne/class/saturnesignature.class.php'; -// Global variables definitions -global $conf, $db, $hookmanager, $langs, $mysoc, $user; +// Global variables definitions. +global $conf, $db, $hookmanager, $langs, $moduleNameLowerCase, $mysoc, $user; -// Load translation files required by the page +// Load translation files required by the page. saturne_load_langs(); -// Get parameters +// Get parameters. $id = GETPOST('id', 'int'); $ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); $cancel = GETPOST('cancel', 'aZ09'); -$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'timesheetcard'; // To manage different context of search +$contextPage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'timesheetcard'; // To manage different context of search. $backtopage = GETPOST('backtopage', 'alpha'); $backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); $lineid = GETPOST('lineid', 'int'); @@ -64,349 +65,272 @@ $month = (GETPOST('month', 'int') ? GETPOST('month', 'int') : date('m')); $day = (GETPOST('day', 'int') ? GETPOST('day', 'int') : date('d')); -// Initialize technical objects -$object = new TimeSheet($db); -$objectline = new TimeSheetLine($db); -$signatory = new SaturneSignature($db, 'dolisirh'); -$timesheetdocument = new TimeSheetDocument($db); -$extrafields = new ExtraFields($db); -$project = new Project($db); -$product = new Product($db); -$workinghours = new Workinghours($db); -$holiday = new Holiday($db); -$task = new Task($db); -$usertmp = new User($db); +// Initialize technical objects. +$object = new TimeSheet($db); +$objectLine = new TimeSheetLine($db); +$signatory = new SaturneSignature($db, $moduleNameLowerCase, $object->element); +$document = new TimeSheetDocument($db); +$extraFields = new ExtraFields($db); +$product = new Product($db); +$workingHours = new Workinghours($db); +$task = new Task($db); +$userTmp = new User($db); // Initialize view objects $form = new Form($db); -$hookmanager->initHooks(['timesheetcard', 'globalcard']); // Note that conf->hooks_modules contains array +$hookmanager->initHooks(['timesheetcard', 'globalcard']); // Note that conf->hooks_modules contains array. // Fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label($object->table_element); +$extraFields->fetch_name_optionals_label($object->table_element); -$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); +$search_array_options = $extraFields->getOptionalsFromPost($object->table_element, '', 'search_'); // Initialize array of search criterias -$search_all = GETPOST('search_all', 'alpha'); -$search = []; +$searchAll = GETPOST('search_all', 'alpha'); +$search = []; foreach ($object->fields as $key => $val) { - if (GETPOST('search_'.$key, 'alpha')) { - $search[$key] = GETPOST('search_'.$key, 'alpha'); - } + if (GETPOST('search_' . $key, 'alpha')) { + $search[$key] = GETPOST('search_' . $key, 'alpha'); + } } if (empty($action) && empty($id) && empty($ref)) { - $action = 'view'; + $action = 'view'; } // Load object -include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be included, not include_once. +require_once DOL_DOCUMENT_ROOT . '/core/actions_fetchobject.inc.php'; // Must be included, not include_once. $upload_dir = $conf->dolisirh->multidir_output[$object->entity ?? 1]; +$now = dol_now(); + // Security check - Protection if external user -$permissiontoread = $user->rights->dolisirh->timesheet->read; +$permissionToRead = $user->rights->dolisirh->timesheet->read; $permissiontoadd = $user->rights->dolisirh->timesheet->write; -$permissiontodelete = $user->rights->dolisirh->timesheet->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT); -saturne_check_access($permissiontoread); +$permissiontodelete = $user->rights->dolisirh->timesheet->delete || ($permissiontoadd && isset($object->status) && $object->status == TimeSheet::STATUS_DRAFT); +saturne_check_access($permissionToRead); /* - * Actions + * Actions. */ $parameters = []; -$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks. if ($reshook < 0) { - setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } if (empty($reshook)) { - $error = 0; - - $backurlforlist = dol_buildpath('/dolisirh/view/timesheet/timesheet_list.php', 1); - - if (empty($backtopage) || ($cancel && empty($id))) { - if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { - if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) { - $backtopage = $backurlforlist; - } else { - $backtopage = dol_buildpath('/dolisirh/view/timesheet/timesheet_card.php', 1).'?id='.((!empty($id) && $id > 0) ? $id : '__ID__'); - } - } - } - - $triggermodname = 'TIMESHEET_MODIFY'; // Name of trigger action code to execute when we modify record - - if (($action == 'add' || $action == 'update') && $permissiontoadd && !$cancel) { - $usertmp->fetch(GETPOST('fk_user_assign')); - $date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int')); - $date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int')); - $filter = ' AND ptt.task_date BETWEEN ' . "'" .dol_print_date($date_start, 'dayrfc') . "'" . ' AND ' . "'" . dol_print_date($date_end, 'dayrfc'). "'"; - $alltimespent = $task->fetchAllTimeSpent($usertmp, $filter); - foreach ($alltimespent as $timespent) { - $task->fetchObjectLinked(null, '', $timespent->timespent_id, 'project_task_time'); - if (isset($task->linkedObjects['dolisirh_timesheet'])) { - $error++; - } - } - - if ($date_start > $date_end) { - setEventMessages($langs->trans('ErrorDateTimeSheet', dol_print_date($date_start, 'dayreduceformat'), dol_print_date($date_end, 'dayreduceformat')), null, 'errors'); - if ($action == 'add') { - $action = 'create'; - } elseif ($action == 'update') { - $action = 'edit'; - } - } - - if ($conf->global->DOLISIRH_TIMESHEET_CHECK_DATE_END > 0) { - if ($date_end > dol_now()) { - setEventMessages($langs->trans('ErrorDateEndTimeSheet', dol_print_date($date_end, 'dayreduceformat'), dol_print_date(dol_now(), 'dayreduceformat')), null, 'errors'); - if ($action == 'add') { - $action = 'create'; - } elseif ($action == 'update') { - $action = 'edit'; - } - } - } - - if ($error > 0) { - setEventMessages($langs->trans('ErrorLinkedElementTimeSheetTimeSpent', $usertmp->getFullName($langs), dol_print_date($date_start, 'dayreduceformat'), dol_print_date($date_end, 'dayreduceformat')), null, 'errors'); - if ($action == 'add') { - $action = 'create'; - } elseif ($action == 'update') { - $action = 'edit'; - } - } - } - - // Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen - $conf->global->MAIN_DISABLE_PDF_AUTOUPDATE = 1; - include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php'; - - // Action to build doc - if ($action == 'builddoc' && $permissiontoadd) { - $outputlangs = $langs; - $newlang = ''; - - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) $newlang = GETPOST('lang_id', 'aZ09'); - if ( ! empty($newlang)) { - $outputlangs = new Translate('', $conf); - $outputlangs->setDefaultLang($newlang); + $error = 0; + + $backurlforlist = dol_buildpath('/dolisirh/view/timesheet/timesheet_list.php', 1); + + if (empty($backtopage) || ($cancel && empty($id))) { + if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { + if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) { + $backtopage = $backurlforlist; + } else { + $backtopage = dol_buildpath('/dolisirh/view/timesheet/timesheet_card.php', 1) . '?id=' . ((!empty($id) && $id > 0) ? $id : '__ID__'); + } } + } - // To be sure vars is defined - if (empty($hidedetails)) $hidedetails = 0; - if (empty($hidedesc)) $hidedesc = 0; - if (empty($hideref)) $hideref = 0; - if (empty($moreparams)) $moreparams = null; + if (($action == 'add' || $action == 'update') && $permissiontoadd && !$cancel) { + $userTmp->fetch(GETPOST('fk_user_assign')); + $dateStart = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int')); + $dateEnd = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int')); + $filter = ' AND ptt.task_date BETWEEN ' . "'" . dol_print_date($dateStart, 'dayrfc') . "'" . ' AND ' . "'" . dol_print_date($dateEnd, 'dayrfc') . "'"; + $timeSpents = $task->fetchAllTimeSpent($userTmp, $filter); + foreach ($timeSpents as $timespent) { + $task->fetchObjectLinked(null, '', $timespent->timespent_id, 'project_task_time'); + if (isset($task->linkedObjects['dolisirh_timesheet'])) { + $error++; + } + } - $model = GETPOST('model', 'alpha'); + if ($dateStart > $dateEnd) { + setEventMessages($langs->trans('ErrorDateTimeSheet', dol_print_date($dateStart, 'dayreduceformat'), dol_print_date($dateEnd, 'dayreduceformat')), [], 'errors'); + if ($action == 'add') { + $action = 'create'; + } elseif ($action == 'update') { + $action = 'edit'; + } + } - $moreparams['object'] = $object; - $moreparams['user'] = $user; + if (getDolGlobalInt('DOLISIRH_TIMESHEET_CHECK_DATE_END')) { + if ($dateEnd > $now) { + setEventMessages($langs->trans('ErrorDateEndTimeSheet', dol_print_date($dateEnd, 'dayreduceformat'), dol_print_date($now, 'dayreduceformat')), [], 'errors'); + if ($action == 'add') { + $action = 'create'; + } elseif ($action == 'update') { + $action = 'edit'; + } + } + } - $result = $timesheetdocument->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams); - if ($result <= 0) { - setEventMessages($object->error, $object->errors, 'errors'); - $action = ''; - } else { - if (empty($donotredirect)) { - setEventMessages($langs->trans('FileGenerated') . ' - ' . $timesheetdocument->last_main_doc, null); - $urltoredirect = $_SERVER['REQUEST_URI']; - $urltoredirect = preg_replace('/#builddoc$/', '', $urltoredirect); - $urltoredirect = preg_replace('/action=builddoc&?/', '', $urltoredirect); // To avoid infinite loop - header('Location: ' . $urltoredirect . '#builddoc'); - exit; + if ($error > 0) { + setEventMessages($langs->trans('ErrorLinkedElementTimeSheetTimeSpent', $userTmp->getFullName($langs), dol_print_date($dateStart, 'dayreduceformat'), dol_print_date($dateEnd, 'dayreduceformat')), [], 'errors'); + if ($action == 'add') { + $action = 'create'; + } elseif ($action == 'update') { + $action = 'edit'; } } } - // Delete file in doc form - if ($action == 'remove_file' && $permissiontodelete) { - if ( ! empty($upload_dir)) { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + // Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen. + $conf->global->MAIN_DISABLE_PDF_AUTOUPDATE = 1; + $triggermodname = 'TIMESHEET_MODIFY'; // Name of trigger action code to execute when we modify record. + require_once DOL_DOCUMENT_ROOT . '/core/actions_addupdatedelete.inc.php'; + + // Actions save_project. + require_once __DIR__ . '/../../../saturne/core/tpl/actions/edit_project_action.tpl.php'; + + // Actions builddoc, forcebuilddoc, remove_file. + require_once __DIR__ . '/../../../saturne/core/tpl/documents/documents_action.tpl.php'; - $langs->load('other'); - $filetodelete = GETPOST('file', 'alpha'); - $file = $upload_dir . '/' . $filetodelete; - $ret = dol_delete_file($file, 0, 0, 0, $object); - if ($ret) setEventMessages($langs->trans('FileWasRemoved', $filetodelete), null, 'mesgs'); - else setEventMessages($langs->trans('ErrorFailToDeleteFile', $filetodelete), null, 'errors'); + // Action to generate pdf from odt file. + require_once __DIR__ . '/../../../saturne/core/tpl/documents/saturne_manual_pdf_generation_action.tpl.php'; - // Make a redirect to avoid to keep the remove_file into the url that create side effects - $urltoredirect = $_SERVER['REQUEST_URI']; - $urltoredirect = preg_replace('/#builddoc$/', '', $urltoredirect); - $urltoredirect = preg_replace('/action=remove_file&?/', '', $urltoredirect); + // Action to add line. + if ($action == 'addline' && $permissiontoadd) { + // Get parameters. + $qty = GETPOST('qty'); + $prodEntryMode = GETPOST('prod_entry_mode'); - header('Location: ' . $urltoredirect); - exit; + if ($prodEntryMode == 'free') { + $productType = GETPOST('type'); + $description = GETPOST('dp_desc', 'restricthtml'); + + // Check parameters. + if ($productType < 0) { + setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), [], 'errors'); + $error++; + } + if (dol_strlen($description) < 0) { + setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), [], 'errors'); + $error++; + } + + $objectLine->description = $description; + $objectLine->product_type = $productType; + } elseif ($prodEntryMode == 'predef') { + $productID = GETPOST('idprod'); + if ($productID > 0) { + $product->fetch($productID); + $objectLine->fk_product = $productID; + $objectLine->product_type = 0; + } else { + $error++; + } } else { - setEventMessages('BugFoundVarUploaddirnotDefined', null, 'errors'); + $error++; + } + + // Initialize object timesheet line. + $objectLine->date_creation = $object->db->idate($now); + $objectLine->qty = $qty; + $objectLine->rang = 0; + $objectLine->fk_timesheet = $id; + $objectLine->fk_parent_line = 0; + + if (!$error) { + $result = $objectLine->create($user); + if ($result > 0) { + // Creation timesheet line OK. + $urlToGo = str_replace('__ID__', $result, $backtopage); + $urlToGo = preg_replace('/--IDFORBACKTOPAGE--/', $id, $urlToGo); // New method to autoselect project after a New on another form object creation. + header('Location: ' . $urlToGo); + exit; + } elseif (!empty($objectLine->errors)) { + // Creation timesheet line KO. + setEventMessages('', $objectLine->errors, 'errors'); + } else { + setEventMessages($objectLine->error, [], 'errors'); + } + } + } + + // Action to edit line. + if ($action == 'updateline' && $permissiontoadd) { + // Get parameters. + $qty = GETPOST('qty'); + $description = GETPOST('product_desc', 'restricthtml'); + + $objectLine->fetch($lineid); + + // Initialize object timesheet line. + $objectLine->qty = $qty; + $objectLine->description = $description; + + if (!$error) { + $result = $objectLine->update($user); + if ($result > 0) { + // Update timesheet line OK. + $urlToGo = str_replace('__ID__', $result, $backtopage); + $urlToGo = preg_replace('/--IDFORBACKTOPAGE--/', $id, $urlToGo); // New method to autoselect project after a New on another form object creation. + header('Location: ' . $urlToGo); + exit; + } elseif (!empty($objectLine->errors)) { + // Update timesheet line KO. + setEventMessages('', $objectLine->errors, 'errors'); + } else { + setEventMessages($objectLine->error, [], 'errors'); + } + } + } + + // Action to set status STATUS_LOCKED. + if ($action == 'confirm_set_Lock' && $permissiontoadd) { + $errorLinked = 0; + $object->fetch($id); + if (!$error) { + $userTmp->fetch($object->fk_user_assign); + $filter = ' AND ptt.task_date BETWEEN ' . "'" . dol_print_date($object->date_start, 'dayrfc') . "'" . ' AND ' . "'" . dol_print_date($object->date_end, 'dayrfc') . "'"; + $timeSpents = $task->fetchAllTimeSpent($userTmp, $filter); + foreach ($timeSpents as $timespent) { + $task->fetchObjectLinked(null, '', $timespent->timespent_id, 'project_task_time'); + if (!isset($task->linkedObjects['dolisirh_timesheet'])) { + $task->id = $timespent->timespent_id; + $task->element = 'project_task_time'; + $task->add_object_linked('dolisirh_timesheet', $object->id); + } else { + $errorLinked++; + } + } + if ($errorLinked == 0) { + $object->setLocked($user, false); + // Set locked OK + $urlToGo = str_replace('__ID__', $id, $backtopage); + $urlToGo = preg_replace('/--IDFORBACKTOPAGE--/', $id, $urlToGo); // New method to autoselect project after a New on another form object creation. + header('Location: ' . $urlToGo); + exit; + } + } elseif (!empty($object->errors)) { + // Set locked KO. + setEventMessages('', $object->errors, 'errors'); + } else { + setEventMessages($object->error, [], 'errors'); + } + + if ($errorLinked > 0) { + setEventMessages($langs->trans('ErrorLinkedElementTimeSheetTimeSpent', $userTmp->getFullName($langs), dol_print_date($object->date_start, 'dayreduceformat'), dol_print_date($object->date_end, 'dayreduceformat')), [], 'errors'); } } - if ($action == 'set_thirdparty' && $permissiontoadd) { - $object->setValueFrom('fk_soc', GETPOST('fk_soc', 'int'), '', '', 'date', '', $user, $triggermodname); - } - - if ($action == 'classin' && $permissiontoadd) { - $object->setProject(GETPOST('projectid', 'int')); - } - - // Action to add line - if ($action == 'addline' && $permissiontoadd) { - // Get parameters - $qty = GETPOST('qty'); - $prod_entry_mode = GETPOST('prod_entry_mode'); - - $now = dol_now(); - - if ($prod_entry_mode == 'free') { - $product_type = GETPOST('type'); - $description = GETPOST('dp_desc', 'restricthtml'); - - // Check parameters - if ($product_type < 0) { - setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors'); - $error++; - } - if (empty($description)) { - setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Description')), null, 'errors'); - $error++; - } - - $objectline->description = $description; - $objectline->product_type = $product_type; - } elseif ($prod_entry_mode == 'predef') { - $product_id = GETPOST('idprod'); - if ($product_id > 0) { - $product->fetch($product_id); - $objectline->fk_product = $product_id; - $objectline->product_type = 0; - } else { - $error++; - } - } else { - $error++; - } - - // Initialize object timesheet line - $objectline->date_creation = $object->db->idate($now); - $objectline->qty = $qty; - $objectline->rang = 0; - $objectline->fk_timesheet = $id; - $objectline->fk_parent_line = 0; - - if ( ! $error) { - $result = $objectline->create($user); - if ($result > 0) { - // Creation timesheet line OK - $urltogo = str_replace('__ID__', $result, $backtopage); - $urltogo = preg_replace('/--IDFORBACKTOPAGE--/', $id, $urltogo); // New method to autoselect project after a New on another form object creation - header('Location: ' . $urltogo); - exit; - } else { - // Creation timesheet line KO - if ( ! empty($objectline->errors)) setEventMessages(null, $objectline->errors, 'errors'); - else setEventMessages($objectline->error, null, 'errors'); - } - } - } - - // Action to edit line - if ($action == 'updateline' && $permissiontoadd) { - // Get parameters - $qty = GETPOST('qty'); - $description = GETPOST('product_desc', 'restricthtml'); - - $objectline->fetch($lineid); - - // Initialize object timesheet line - $objectline->qty = $qty; - $objectline->description = $description; - - if ( ! $error) { - $result = $objectline->update($user, false); - if ($result > 0) { - // Update timesheet line OK - $urltogo = str_replace('__ID__', $result, $backtopage); - $urltogo = preg_replace('/--IDFORBACKTOPAGE--/', $parent_id, $urltogo); // New method to autoselect project after a New on another form object creation - header('Location: ' . $urltogo); - exit; - } else { - // Update timesheet line KO - if ( ! empty($objectline->errors)) setEventMessages(null, $objectline->errors, 'errors'); - else setEventMessages($objectline->error, null, 'errors'); - } - } - } - - // Action to set status STATUS_LOCKED - if ($action == 'confirm_setLocked' && $permissiontoadd) { - $errorlinked = 0; - $object->fetch($id); - if ( ! $error) { - $usertmp->fetch($object->fk_user_assign); - $filter = ' AND ptt.task_date BETWEEN ' . "'" .dol_print_date($object->date_start, 'dayrfc') . "'" . ' AND ' . "'" . dol_print_date($object->date_end, 'dayrfc'). "'"; - $alltimespent = $task->fetchAllTimeSpent($usertmp, $filter); - foreach ($alltimespent as $timespent) { - $task->fetchObjectLinked(null, '', $timespent->timespent_id, 'project_task_time'); - if (!isset($task->linkedObjects['dolisirh_timesheet'])) { - $task->id = $timespent->timespent_id; - $task->element = 'project_task_time'; - $task->add_object_linked('dolisirh_timesheet', $object->id); - } else { - $errorlinked++; - } - } - if ($errorlinked == 0) { - $object->setLocked($user, false); - // Set locked OK - $urltogo = str_replace('__ID__', $result, $backtopage); - $urltogo = preg_replace('/--IDFORBACKTOPAGE--/', $id, $urltogo); // New method to autoselect project after a New on another form object creation - header('Location: ' . $urltogo); - exit; - } - } else { - // Set locked KO - if ( ! empty($object->errors)) setEventMessages(null, $object->errors, 'errors'); - else setEventMessages($object->error, null, 'errors'); - } - - if ($errorlinked > 0) { - setEventMessages($langs->trans('ErrorLinkedElementTimeSheetTimeSpent', $usertmp->getFullName($langs), dol_print_date($object->date_start, 'dayreduceformat'), dol_print_date($object->date_end, 'dayreduceformat')), null, 'errors'); - } - } - - // Action to set status STATUS_ARCHIVED - if ($action == 'setArchived' && $permissiontoadd) { - $object->fetch($id); - if ( ! $error) { - $result = $object->setArchived($user, false); - if ($result > 0) { - // Set Archived OK - $urltogo = str_replace('__ID__', $result, $backtopage); - $urltogo = preg_replace('/--IDFORBACKTOPAGE--/', $id, $urltogo); // New method to autoselect project after a New on another form object creation - header('Location: ' . $urltogo); - exit; - } else { - // Set Archived KO - if ( ! empty($object->errors)) setEventMessages(null, $object->errors, 'errors'); - else setEventMessages($object->error, null, 'errors'); - } - } - } - - // Actions to send emails - $triggersendname = strtoupper($object->element) . '_SENTBYMAIL'; - $autocopy = 'MAIN_MAIL_AUTOCOPY_' . strtoupper($object->element) . '_TO'; - include DOL_DOCUMENT_ROOT . '/core/actions_sendmails.inc.php'; + // Action confirm_archive. + require_once __DIR__ . '/../../../saturne/core/tpl/signature/signature_action_workflow.tpl.php'; + + // Actions to send emails. + $triggersendname = strtoupper($object->element) . '_SENTBYMAIL'; + $autocopy = 'MAIN_MAIL_AUTOCOPY_' . strtoupper($object->element) . '_TO'; + require_once DOL_DOCUMENT_ROOT . '/core/actions_sendmails.inc.php'; } /* - * View + * View. */ $title = $langs->trans(ucfirst($object->element)); @@ -414,106 +338,107 @@ saturne_header(0, '', $title, $help_url); -// Part to create +// Part to create; if ($action == 'create') { - if (empty($permissiontoadd)) { - accessforbidden($langs->trans('NotEnoughPermissions'), 0); - exit; - } + if (empty($permissiontoadd)) { + accessforbidden($langs->trans('NotEnoughPermissions'), 0); + exit; + } - print load_fiche_titre($langs->trans('New' . ucfirst($object->element)), '', 'object_' . $object->picto); + print load_fiche_titre($langs->trans('New' . ucfirst($object->element)), '', 'object_' . $object->picto); - print '
'; - print ''; - print ''; - if ($backtopage) { - print ''; - } - if ($backtopageforcancel) { - print ''; - } + print ''; + print ''; + print ''; + if ($backtopage) { + print ''; + } + if ($backtopageforcancel) { + print ''; + } - print dol_get_fiche_head(); + print dol_get_fiche_head(); - print ''; + print '
'; - if ($conf->global->DOLISIRH_TIMESHEET_PREFILL_DATE) { + $specialCaseMonth = 0; + if (getDolGlobalInt('DOLISIRH_TIMESHEET_PREFILL_DATE')) { if ($month == 01) { $specialCaseMonth = 12; $year--; } } - $object->fields['label']['default'] = $langs->trans('TimeSheet') . ' ' . dol_print_date(dol_mktime(0, 0, 0, (!empty($conf->global->DOLISIRH_TIMESHEET_PREFILL_DATE) ? (($month != 01) ? $month - 1 : $specialCaseMonth) : $month), $day, $year), "%B %Y") . ' ' . $user->getFullName($langs, 0, 0); - $object->fields['fk_project']['default'] = $conf->global->DOLISIRH_HR_PROJECT; - $object->fields['fk_user_assign']['default'] = $user->id; + $object->fields['label']['default'] = $langs->trans('TimeSheet') . ' ' . dol_print_date(dol_mktime(0, 0, 0, (!empty($conf->global->DOLISIRH_TIMESHEET_PREFILL_DATE) ? (($month != 01) ? $month - 1 : $specialCaseMonth) : $month), $day, $year), '%B %Y') . ' ' . $user->getFullName($langs, 0, 0); + $object->fields['fk_project']['default'] = $conf->global->DOLISIRH_HR_PROJECT; + $object->fields['fk_user_assign']['default'] = $user->id; - $date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int')); - $date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int')); + $dateStart = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int')); + $dateEnd = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int')); - $_POST['date_start'] = $date_start; - $_POST['date_end'] = $date_end; + $_POST['date_start'] = $dateStart; + $_POST['date_end'] = $dateEnd; - if ($conf->global->DOLISIRH_TIMESHEET_PREFILL_DATE && empty($_POST['date_start']) && empty($_POST['date_end'])) { - $firstday = dol_get_first_day($year, (($month != 01) ? $month - 1 : $specialCaseMonth)); - $firstday = dol_getdate($firstday); + if (getDolGlobalInt('DOLISIRH_TIMESHEET_PREFILL_DATE') && empty($_POST['date_start']) && empty($_POST['date_end'])) { + $firstDay = dol_get_first_day($year, (($month != 01) ? $month - 1 : $specialCaseMonth)); + $firstDay = dol_getdate($firstDay); - $_POST['date_startday'] = $firstday['mday']; - $_POST['date_startmonth'] = $firstday['mon']; - $_POST['date_startyear'] = $firstday['year']; + $_POST['date_startday'] = $firstDay['mday']; + $_POST['date_startmonth'] = $firstDay['mon']; + $_POST['date_startyear'] = $firstDay['year']; - $lastday = dol_get_last_day($year, (($month != 01) ? $month - 1 : $specialCaseMonth)); - $lastday = dol_getdate($lastday); + $lastDay = dol_get_last_day($year, (($month != 01) ? $month - 1 : $specialCaseMonth)); + $lastDay = dol_getdate($lastDay); - $_POST['date_endday'] = $lastday['mday']; - $_POST['date_endmonth'] = $lastday['mon']; - $_POST['date_endyear'] = $lastday['year']; - } + $_POST['date_endday'] = $lastDay['mday']; + $_POST['date_endmonth'] = $lastDay['mon']; + $_POST['date_endyear'] = $lastDay['year']; + } - // Common attributes - include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php'; + // Common attributes. + require_once DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php'; - // Categories - if (isModEnabled('categorie')) { - print ''; - } + // Categories. + if (isModEnabled('categorie')) { + print ''; + } - // Other attributes - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php'; + // Other attributes. + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php'; - print '
'.$langs->trans('Categories').''; - $cate_arbo = $form->select_all_categories('timesheet', '', 'parent', 64, 0, 1); - print img_picto('', 'category') . $form->multiselectarray('categories', $cate_arbo, GETPOST('categories', 'array'), '', 0, 'quatrevingtpercent widthcentpercentminusx'); - print '
' . $langs->trans('Categories') . ''; + $cateArbo = $form->select_all_categories($object->element, '', 'parent', 64, 0, 1); + print img_picto('', 'category') . $form::multiselectarray('categories', $cateArbo, GETPOST('categories', 'array'), '', 0, 'quatrevingtpercent widthcentpercentminusx'); + print '
'; + print ''; - print dol_get_fiche_end(); + print dol_get_fiche_end(); - print $form->buttonsSaveCancel('Create'); + print $form->buttonsSaveCancel('Create'); - print '
'; + print ''; } -// Part to edit record +// Part to edit record. if (($id || $ref) && $action == 'edit') { - print load_fiche_titre($langs->trans('Modify' . ucfirst($object->element)), '', 'object_' . $object->picto); - - print '
'; - print ''; - print ''; - print ''; - if ($backtopage) { - print ''; - } - if ($backtopageforcancel) { - print ''; - } + print load_fiche_titre($langs->trans('Modify' . ucfirst($object->element)), '', 'object_' . $object->picto); + + print ''; + print ''; + print ''; + print ''; + if ($backtopage) { + print ''; + } + if ($backtopageforcancel) { + print ''; + } - print dol_get_fiche_head(); + print dol_get_fiche_head(); - print ''; + print '
'; - $dateStart = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int')); - $dateEnd = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int')); + $dateStart = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int')); + $dateEnd = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int')); $dateStart = (!empty($dateStart) ? $dateStart : $object->date_start); $dateEnd = (!empty($dateEnd) ? $dateEnd : $object->date_end); @@ -529,432 +454,448 @@ $_POST['date_endmonth'] = $dateEnd['mon']; $_POST['date_endyear'] = $dateEnd['year']; - $object->fields['note_public']['visible'] = 1; - $object->fields['note_private']['visible'] = 1; - - // Common attributes - include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_edit.tpl.php'; - - // Tags-Categories - if (isModEnabled('categorie')) { - print ''; - } + // Common attributes. + require_once DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_edit.tpl.php'; + + // Tags-Categories. + if (isModEnabled('categorie')) { + print ''; + } - // Other attributes - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php'; + // Other attributes. + require_once DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php'; - print '
' . $langs->trans('Categories') . ''; - $cate_arbo = $form->select_all_categories('timesheet', '', 'parent', 64, 0, 1); - $c = new Categorie($db); - $cats = $c->containing($object->id, 'timesheet'); - $arrayselected = []; - if (is_array($cats)) { - foreach ($cats as $cat) { - $arrayselected[] = $cat->id; - } - } - print img_picto('', 'category').$form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, 'quatrevingtpercent widthcentpercentminusx'); - print '
' . $langs->trans('Categories') . ''; + $cate_arbo = $form->select_all_categories($object->element, '', 'parent', 64, 0, 1); + $categorie = new Categorie($db); + $cats = $categorie->containing($object->id, $object->element); + $arraySelected = []; + if (is_array($cats)) { + foreach ($cats as $cat) { + $arraySelected[] = $cat->id; + } + } + print img_picto('', 'category') . $form::multiselectarray('categories', $cate_arbo, $arraySelected, '', 0, 'quatrevingtpercent widthcentpercentminusx'); + print '
'; + print ''; - print dol_get_fiche_end(); + print dol_get_fiche_end(); - print $form->buttonsSaveCancel(); + print $form->buttonsSaveCancel(); - print '
'; + print ''; } -// Part to show record +// Part to show record. if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { - $res = $object->fetch_optionals(); + $object->fetch_optionals(); saturne_get_fiche_head($object, 'card', $title); saturne_banner_tab($object); - $formconfirm = ''; - - // setDraft confirmation - if (($action == 'setDraft' && (empty($conf->use_javascript_ajax) || !empty($conf->dol_use_jmobile))) || (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile))) { - $formconfirm .= $form->formconfirm($_SERVER['PHP_SELF'] . '?id=' . $object->id, $langs->trans('ReOpenTimeSheet'), $langs->trans('ConfirmReOpenTimeSheet', $object->ref), 'confirm_setdraft', '', 'yes', 'actionButtonInProgress', 350, 600); - } - // setPendingSignature confirmation - if (($action == 'setPendingSignature' && (empty($conf->use_javascript_ajax) || !empty($conf->dol_use_jmobile))) || (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile))) { - $formconfirm .= $form->formconfirm($_SERVER['PHP_SELF'] . '?id=' . $object->id, $langs->trans('ValidateTimeSheet'), $langs->trans('ConfirmValidateTimeSheet', $object->ref), 'confirm_validate', '', 'yes', 'actionButtonPendingSignature', 350, 600); - } - // setLocked confirmation - if (($action == 'setLocked' && (empty($conf->use_javascript_ajax) || !empty($conf->dol_use_jmobile))) || (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile))) { - $formconfirm .= $form->formconfirm($_SERVER['PHP_SELF'] . '?id=' . $object->id, $langs->trans('LockTimeSheet'), $langs->trans('ConfirmLockTimeSheet', $object->ref), 'confirm_setLocked', '', 'yes', 'actionButtonLock', 350, 600); - } - // Confirmation to delete - if ($action == 'delete') { - $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?id=' . $object->id, $langs->trans('DeleteTimeSheet'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 'yes', 1); - } - // Confirmation to delete line - if ($action == 'ask_deleteline') { - $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?id=' . $object->id . '&lineid=' . $lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 0, 1); - } - // Confirmation remove file - if ($action == 'removefile') { - $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?id=' . $object->id . '&file=' . GETPOST('file') . '&entity=' . $conf->entity, $langs->trans('RemoveFileTimeSheet'), $langs->trans('ConfirmRemoveFileTimeSheet'), 'remove_file', '', 'yes', 1, 350, 600); - } - - // Call Hook formConfirm - $parameters = ['formConfirm' => $formconfirm, 'lineid' => $lineid]; - $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook - if (empty($reshook)) { - $formconfirm .= $hookmanager->resPrint; - } elseif ($reshook > 0) { - $formconfirm = $hookmanager->resPrint; - } - - // Print form confirm - print $formconfirm; - - print '
'; - print '
'; - print ''; - - // Common attributes + $formConfirm = ''; + + // Draft confirmation + if (($action == 'draft' && (empty($conf->use_javascript_ajax) || !empty($conf->dol_use_jmobile))) || (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile))) { + $formConfirm .= $form->formconfirm($_SERVER['PHP_SELF'] . '?id=' . $object->id, $langs->trans('ReOpenObject', $langs->transnoentities('The' . ucfirst($object->element))), $langs->trans('ConfirmReOpenObject', $langs->transnoentities('The' . ucfirst($object->element)), $langs->transnoentities('The' . ucfirst($object->element))), 'confirm_setdraft', '', 'yes', 'actionButtonInProgress', 350, 600); + } + // Pending signature confirmation + if (($action == 'pending_signature' && (empty($conf->use_javascript_ajax) || !empty($conf->dol_use_jmobile))) || (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile))) { + $formConfirm .= $form->formconfirm($_SERVER['PHP_SELF'] . '?id=' . $object->id, $langs->trans('ValidateObject', $langs->transnoentities('The' . ucfirst($object->element))), $langs->trans('ConfirmValidateObject', $langs->transnoentities('The' . ucfirst($object->element)), $langs->transnoentities('The' . ucfirst($object->element))) . $langs->trans('ConfirmValidateTimeSheet'), 'confirm_validate', '', 'yes', 'actionButtonPendingSignature', 350, 600); + } + // Lock confirmation + if (($action == 'lock' && (empty($conf->use_javascript_ajax) || !empty($conf->dol_use_jmobile))) || (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile))) { + $formConfirm .= $form->formconfirm($_SERVER['PHP_SELF'] . '?id=' . $object->id, $langs->trans('LockObject', $langs->transnoentities('The' . ucfirst($object->element))), $langs->trans('ConfirmLockObject', $langs->transnoentities('The' . ucfirst($object->element))), 'confirm_set_Lock', '', 'yes', 'actionButtonLock', 350, 600); + } + // Delete confirmation + if ($action == 'delete') { + $formConfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?id=' . $object->id, $langs->trans('DeleteObject', $langs->transnoentities('The' . ucfirst($object->element))), $langs->trans('ConfirmDeleteObject', $langs->transnoentities('The' . ucfirst($object->element))), 'confirm_delete', '', 'yes', 1); + } + // Delete line confirmation + if ($action == 'ask_deleteline') { + $formConfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?id=' . $object->id . '&lineid=' . $lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 0, 1); + } + // Remove file confirmation + if ($action == 'removefile') { + $formConfirm = $form->formconfirm($_SERVER['PHP_SELF'] . '?id=' . $object->id . '&file=' . GETPOST('file') . '&entity=' . $conf->entity, $langs->trans('RemoveFileTimeSheet'), $langs->trans('ConfirmRemoveFileTimeSheet'), 'remove_file', '', 'yes', 1, 350, 600); + } + + // Call Hook formConfirm. + $parameters = ['formConfirm' => $formConfirm, 'lineid' => $lineid]; + $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook. + if (empty($reshook)) { + $formConfirm .= $hookmanager->resPrint; + } elseif ($reshook > 0) { + $formConfirm = $hookmanager->resPrint; + } + + // Print form confirm. + print $formConfirm; + + if ($conf->browser->layout == 'phone') { + $onPhone = 1; + } else { + $onPhone = 0; + } + + print '
'; + print '
'; + print '
'; + + // Common attributes unset($object->fields['label']); // Hide field already shown in banner - unset($object->fields['fk_project']); // Hide field already shown in banner - unset($object->fields['fk_soc']); // Hide field already shown in banner - - include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_view.tpl.php'; - - // Categories - if (isModEnabled('categorie')) { - print ''; - } - - $now = dol_now(); - $datestart = dol_getdate($object->date_start, false, 'Europe/Paris'); - - // Due to Dolibarr issue in common field add we do substract 12 hours in timestamp - $firstdaytoshow = $object->date_start - 12 * 3600; - $lastdaytoshow = $object->date_end - 12 * 3600; - - $start_date = dol_print_date($firstdaytoshow, 'dayreduceformat'); - $end_date = dol_print_date($lastdaytoshow, 'dayreduceformat'); - - $daysInRange = dolisirh_num_between_days($firstdaytoshow, $lastdaytoshow, 1); - - $isavailable = array(); - for ($idw = 0; $idw < $daysInRange; $idw++) { - $dayInLoop = dol_time_plus_duree($firstdaytoshow, $idw, 'd'); - if (is_day_available($dayInLoop, $user->id)) { - $isavailable[$dayInLoop] = array('morning'=>1, 'afternoon'=>1); - } else if (date('N', $dayInLoop) >= 6) { - $isavailable[$dayInLoop] = array('morning'=>false, 'afternoon'=>false, 'morning_reason'=>'week_end', 'afternoon_reason'=>'week_end'); - } else { - $isavailable[$dayInLoop] = array('morning'=>false, 'afternoon'=>false, 'morning_reason'=>'public_holiday', 'afternoon_reason'=>'public_holiday'); - } - } - - $workingHours = $workinghours->fetchCurrentWorkingHours($object->fk_user_assign, 'user'); - - $timeSpendingInfos = load_time_spending_infos_within_range($firstdaytoshow, dol_time_plus_duree($lastdaytoshow, 1, 'd'), $workingHours, $isavailable, $object->fk_user_assign); - - // Planned working time - $planned_working_time = $timeSpendingInfos['planned']; - - print ''; - - // Hours passed - $passed_working_time = $timeSpendingInfos['passed']; - - print ''; - - //Difference between passed and working hours - $difftotaltime = $timeSpendingInfos['difference']; - - if ($difftotaltime < 0) { - $morecssHours = colorStringToArray($conf->global->DOLISIRH_EXCEEDED_TIME_SPENT_COLOR); - $morecssnotice = 'error'; - $noticetitle = $langs->trans('TimeSpentDiff', dol_print_date($firstdaytoshow, 'dayreduceformat'), dol_print_date($lastdaytoshow, 'dayreduceformat'), dol_print_date(dol_mktime(0, 0, 0, $datestart['mon'], $datestart['mday'], $datestart['year']), '%B %Y')); - } elseif ($difftotaltime > 0) { - $morecssHours = colorStringToArray($conf->global->DOLISIRH_NOT_EXCEEDED_TIME_SPENT_COLOR); - $morecssnotice = 'warning'; - $noticetitle = $langs->trans('TimeSpentMustBeCompleted', dol_print_date($firstdaytoshow, 'dayreduceformat'), dol_print_date($lastdaytoshow, 'dayreduceformat'), dol_print_date(dol_mktime(0, 0, 0, $datestart['mon'], $datestart['mday'], $datestart['year']), '%B %Y')); - } elseif ($difftotaltime == 0) { - $morecssHours = colorStringToArray($conf->global->DOLISIRH_PERFECT_TIME_SPENT_COLOR); - $morecssnotice = 'success'; - $noticetitle = $langs->trans('TimeSpentPerfect'); - } - - //Working hours - $working_time = $timeSpendingInfos['spent']; - - if ($planned_working_time['days'] > $working_time['days']) { - $morecssDays = colorStringToArray($conf->global->DOLISIRH_EXCEEDED_TIME_SPENT_COLOR); - } else if ($planned_working_time['days'] < $working_time['days']){ - $morecssDays = colorStringToArray($conf->global->DOLISIRH_NOT_EXCEEDED_TIME_SPENT_COLOR); - } else { - $morecssDays = colorStringToArray($conf->global->DOLISIRH_PERFECT_TIME_SPENT_COLOR); - } - - print ''; - - //Difference between working hours & planned working hours - print ''; - - // Other attributes. Fields from hook formObjectOptions and Extrafields. - include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; - - print '
' . $langs->trans('Categories') . ''; - print $form->showCategories($object->id, 'timesheet', 1); - print '
'; - print $langs->trans('Total'); - print ' - '; - print $langs->trans('ExpectedWorkingHoursMonthTimeSheet', $start_date, $end_date); - print ' : '; - print (($planned_working_time['minutes'] != 0) ? convertSecondToTime($planned_working_time['minutes'] * 60, 'allhourmin') : '00:00') . ''; - print '' . ' - ' . $langs->trans('ExpectedWorkingDayMonth') . ' ' . $planned_working_time['days'] . ''; - print ''; - print '
'; - print $langs->trans('Total'); - print ' - '; - print $langs->trans('SpentWorkingHoursMonth', $start_date, $end_date); - print ' : ' . (($passed_working_time['minutes'] != 0) ? convertSecondToTime($passed_working_time['minutes'] * 60, 'allhourmin') : '00:00') . ''; - print '
'; - print $langs->trans('Total'); - print ' - '; - print $langs->trans('ConsumedWorkingHoursMonth', $start_date, $end_date); - print ' : '.convertSecondToTime($working_time['total'], 'allhourmin').''; - print '' . ' - ' . $langs->trans('ConsumedWorkingDayMonth') . ' '; - print $working_time['days'] . ''; - print ''; - print '
'; - print $langs->trans('Total'); - print ' - '; - print $langs->trans('DiffSpentAndConsumedWorkingHoursMonth', $start_date, $end_date); - print ' : '; - print (($difftotaltime != 0) ? convertSecondToTime(abs($difftotaltime * 60), 'allhourmin') : '00:00').''; - print ''; - print '
'; - print '
'; - print '
'; - - $usertmp->fetch($object->fk_user_assign); - - print '
'; ?> - - -
-
-
trans('ErrorConfigWorkingHours') ?>
-
- trans('GoToWorkingHours', $usertmp->getFullName($langs)) ?> -
- -
-
-
-
- trans('GoToTimeSpent', dol_print_date(dol_mktime(0, 0, 0, $datestart['mon'], $datestart['mday'], $datestart['year']), '%B %Y')) ?> -
- + unset($object->fields['fk_project']); // Hide field already shown in banner + unset($object->fields['fk_soc']); // Hide field already shown in banner + + require_once DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_view.tpl.php'; + + // Categories. + if (isModEnabled('categorie')) { + print '' . $langs->trans('Categories') . ''; + print $form->showCategories($object->id, $object->element, 1); + print ''; + } + + $dateStart = dol_getdate($object->date_start, false, 'Europe/Paris'); + + // Due to Dolibarr issue in common field add we do substract 12 hours in timestamp. + $firstDayToShow = $object->date_start - 12 * 3600; + $lastDayToShow = $object->date_end - 12 * 3600; + + $startDate = dol_print_date($firstDayToShow, 'dayreduceformat'); + $endDate = dol_print_date($lastDayToShow, 'dayreduceformat'); + + $daysInRange = dolisirh_num_between_days($firstDayToShow, $lastDayToShow, 1); + + $isAvailable = []; + for ($idw = 0; $idw < $daysInRange; $idw++) { + $dayInLoop = dol_time_plus_duree($firstDayToShow, $idw, 'd'); + if (is_day_available($dayInLoop, $user->id)) { + $isAvailable[$dayInLoop] = ['morning' => 1, 'afternoon' => 1]; + } elseif (date('N', $dayInLoop) >= 6) { + $isAvailable[$dayInLoop] = ['morning' => false, 'afternoon' => false, 'morning_reason' => 'week_end', 'afternoon_reason' => 'week_end']; + } else { + $isAvailable[$dayInLoop] = ['morning' => false, 'afternoon' => false, 'morning_reason' => 'public_holiday', 'afternoon_reason' => 'public_holiday']; + } + } + + $workingHours = $workingHours->fetchCurrentWorkingHours($object->fk_user_assign, 'user'); + + $timeSpendingInfos = load_time_spending_infos_within_range($firstDayToShow, dol_time_plus_duree($lastDayToShow, 1, 'd'), $workingHours, $isAvailable, $object->fk_user_assign); + + // Planned working time. + $plannedWorkingTime = $timeSpendingInfos['planned']; + + print ''; + print $langs->trans('Total'); + print ' - '; + print $langs->trans('ExpectedWorkingHoursMonthTimeSheet', $startDate, $endDate); + print ' : '; + print (($plannedWorkingTime['minutes'] != 0) ? convertSecondToTime($plannedWorkingTime['minutes'] * 60, 'allhourmin') : '00:00') . ''; + print '' . ' - ' . $langs->trans('ExpectedWorkingDayMonth') . ' ' . $plannedWorkingTime['days'] . ''; + print ''; + print ''; + + // Hours passed. + $passedWorkingTime = $timeSpendingInfos['passed']; + + print ''; + print $langs->trans('Total'); + print ' - '; + print $langs->trans('SpentWorkingHoursMonth', $startDate, $endDate); + print ' : ' . (($passedWorkingTime['minutes'] != 0) ? convertSecondToTime($passedWorkingTime['minutes'] * 60, 'allhourmin') : '00:00') . ''; + print ''; + + // Difference between passed and working hours. + $diffTotalTime = $timeSpendingInfos['difference']; + + if ($diffTotalTime < 0) { + $moreCssHours = colorStringToArray($conf->global->DOLISIRH_EXCEEDED_TIME_SPENT_COLOR); + $moreCssNotice = 'error'; + $noticeTitle = $langs->trans('TimeSpentDiff', dol_print_date($firstDayToShow, 'dayreduceformat'), dol_print_date($lastDayToShow, 'dayreduceformat'), dol_print_date(dol_mktime(0, 0, 0, $dateStart['mon'], $dateStart['mday'], $dateStart['year']), '%B %Y')); + } elseif ($diffTotalTime > 0) { + $moreCssHours = colorStringToArray($conf->global->DOLISIRH_NOT_EXCEEDED_TIME_SPENT_COLOR); + $moreCssNotice = 'warning'; + $noticeTitle = $langs->trans('TimeSpentMustBeCompleted', dol_print_date($firstDayToShow, 'dayreduceformat'), dol_print_date($lastDayToShow, 'dayreduceformat'), dol_print_date(dol_mktime(0, 0, 0, $dateStart['mon'], $dateStart['mday'], $dateStart['year']), '%B %Y')); + } elseif ($diffTotalTime == 0) { + $moreCssHours = colorStringToArray($conf->global->DOLISIRH_PERFECT_TIME_SPENT_COLOR); + $moreCssNotice = 'success'; + $noticeTitle = $langs->trans('TimeSpentPerfect'); + } else { + $moreCssHours = ''; + $moreCssNotice = ''; + $noticeTitle = ''; + } + + // Working hours. + $workingTime = $timeSpendingInfos['spent']; + if ($plannedWorkingTime['days'] > $workingTime['days']) { + $morecssDays = colorStringToArray($conf->global->DOLISIRH_EXCEEDED_TIME_SPENT_COLOR); + } elseif ($plannedWorkingTime['days'] < $workingTime['days']){ + $morecssDays = colorStringToArray($conf->global->DOLISIRH_NOT_EXCEEDED_TIME_SPENT_COLOR); + } else { + $morecssDays = colorStringToArray($conf->global->DOLISIRH_PERFECT_TIME_SPENT_COLOR); + } + + print ''; + print $langs->trans('Total'); + print ' - '; + print $langs->trans('ConsumedWorkingHoursMonth', $startDate, $endDate); + print ' : ' . convertSecondToTime($workingTime['total'], 'allhourmin') . ''; + print '' . ' - ' . $langs->trans('ConsumedWorkingDayMonth') . ' '; + print $workingTime['days'] . ''; + print ''; + print ''; + + // Difference between working hours & planned working hours. + print ''; + print $langs->trans('Total'); + print ' - '; + print $langs->trans('DiffSpentAndConsumedWorkingHoursMonth', $startDate, $endDate); + print ' : '; + print (($diffTotalTime != 0) ? convertSecondToTime(abs($diffTotalTime * 60), 'allhourmin') : '00:00') . ''; + print ''; + print ''; + + // Other attributes. Fields from hook formObjectOptions and Extrafields. + require_once DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + + print ''; + print ''; + print ''; + + $userTmp->fetch($object->fk_user_assign); + + print '
'; ?> + + +
+
+
trans('ErrorConfigWorkingHours') ?>
+
+ trans('GoToWorkingHours', $userTmp->getFullName($langs)) ?> +
+ +
+
+
+
+ trans('GoToTimeSpent', dol_print_date(dol_mktime(0, 0, 0, $dateStart['mon'], $dateStart['mday'], $dateStart['year']), '%B %Y')) ?> +
+ global->DOLISIRH_HR_PROJECT) || empty($conf->global->DOLISIRH_HOLIDAYS_TASK) || empty($conf->global->DOLISIRH_PAID_HOLIDAYS_TASK) || empty($conf->global->DOLISIRH_PAID_HOLIDAYS_TASK) || empty($conf->global->DOLISIRH_PAID_HOLIDAYS_TASK) - || empty($conf->global->DOLISIRH_PUBLIC_HOLIDAY_TASK) || empty($conf->global-> DOLISIRH_RTT_TASK) || empty($conf->global->DOLISIRH_INTERNAL_MEETING_TASK) || empty($conf->global->DOLISIRH_INTERNAL_TRAINING_TASK) || empty($conf->global->DOLISIRH_EXTERNAL_TRAINING_TASK) - || empty($conf->global->DOLISIRH_AUTOMATIC_TIMESPENDING_TASK) || empty($conf->global->DOLISIRH_MISCELLANEOUS_TASK)) : ?> + || empty($conf->global->DOLISIRH_PUBLIC_HOLIDAY_TASK) || empty($conf->global-> DOLISIRH_RTT_TASK) || empty($conf->global->DOLISIRH_INTERNAL_MEETING_TASK) || empty($conf->global->DOLISIRH_INTERNAL_TRAINING_TASK) || empty($conf->global->DOLISIRH_EXTERNAL_TRAINING_TASK) + || empty($conf->global->DOLISIRH_AUTOMATIC_TIMESPENDING_TASK) || empty($conf->global->DOLISIRH_MISCELLANEOUS_TASK)) : ?>
trans('ErrorConfigProjectPage') ?>
- trans('GoToConfigProjectPage') ?> + trans('GoToConfigProjectPage') ?>
- table_element_line)) { - // Show object lines - $result = $object->getLinesArray(); - - print '
- - - - - - '; - - if (!empty($conf->use_javascript_ajax) && $object->status == 0) { - include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php'; - } - - print '
'; - if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) { - print ''; - } - - if (!empty($object->lines)) { - if ($permissiontoadd) { - $user->rights->timesheet = new stdClass(); - $user->rights->timesheet->creer = 1; - $object->statut = $object::STATUS_DRAFT; - if ($object->status >= $object::STATUS_VALIDATED) { - $disableedit = 1; - $disableremove = 1; - $disablemove = 1; - } - } - $object->printObjectLines($action, $mysoc, null, GETPOST('lineid', 'int'), 1); ?> - - status == 0 && $permissiontoadd && $action != 'selectlines') { - if ($action != 'editline') { - // Add products/services form - $object->socid = 0; - $parameters = array(); - $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook - if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - if (empty($reshook)) $object->formAddObjectLine(1, $mysoc, $soc); ?> - - lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) { - print '
'; - } - print '
'; - - print "
\n"; - } - - // Buttons for actions - if ($action != 'presend' && $action != 'editline') { - print '
'."\n"; - $parameters = array(); - $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook - if ($reshook < 0) { - setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - } - - if (empty($reshook) && $permissiontoadd) { - // Modify - if ($object->status == $object::STATUS_DRAFT) { - print '' . $langs->trans('Modify') . ''; - } else { - print '' . $langs->trans('Modify') . ''; + table_element_line)) { + // Show object lines. + $result = $object->getLinesArray(); + + print '
+ + + + + + '; + + if (!empty($conf->use_javascript_ajax) && $object->status == 0) { + include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php'; + } + + print '
'; + if (!empty($object->lines) || ($object->status == TimeSheet::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) { + print ''; + } + + if (!empty($object->lines)) { + if ($permissiontoadd) { + $user->rights->timesheet = new stdClass(); + $user->rights->timesheet->creer = 1; + $object->statut = TimeSheet::STATUS_DRAFT; + if ($object->status >= TimeSheet::STATUS_VALIDATED) { + $disableedit = 1; + $disableremove = 1; + $disablemove = 1; + } } + $object->printObjectLines($action, $mysoc, null, $lineid, 1); ?> + + status == TimeSheet::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines') { + if ($action != 'editline') { + // Add products/services form. + $parameters = []; + $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + if (empty($reshook)) { + $object->formAddObjectLine(1, $mysoc, $mysoc); + } ?> + + lines) || ($object->status == TimeSheet::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) { + print '
'; + } + print '
'; + + print '
'; + } + + // Buttons for actions. + if ($action != 'presend' && $action != 'editline') { + print '
'; + $parameters = []; + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook. + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } - // Validate - if ($object->status == $object::STATUS_DRAFT && $planned_working_time['minutes'] != 0) { - print '' . $langs->trans('Validate') . ''; + if (empty($reshook) && $permissiontoadd) { + // Modify. + $displayButton = $onPhone ? '' : '' . ' ' . $langs->trans('Modify'); + if ($object->status == TimeSheet::STATUS_DRAFT) { + print '' . $displayButton . ''; } else { - print '' . $langs->trans('Validate') . ''; + print '' . $displayButton . ''; } - // ReOpen - if ($object->status == $object::STATUS_VALIDATED) { - print '' . $langs->trans('ReOpenDoli') . ''; + // Validate. + $displayButton = $onPhone ? '' : '' . ' ' . $langs->trans('Validate'); + if ($object->status == TimeSheet::STATUS_DRAFT && $plannedWorkingTime['minutes'] != 0) { + print '' . $displayButton . ''; } else { - print '' . $langs->trans('ReOpenDoli') . ''; + print '' . $displayButton . ''; } - // Sign - if ($object->status == $object::STATUS_VALIDATED && !$signatory->checkSignatoriesSignatures($object->id, 'timesheet')) { - print '' . $langs->trans('Sign') . ''; + // ReOpen. + $displayButton = $onPhone ? '' : '' . ' ' . $langs->trans('ReOpenDoli'); + if ($object->status == TimeSheet::STATUS_VALIDATED) { + print '' . $displayButton . ''; } else { - print '' . $langs->trans('Sign') . ''; + print '' . $displayButton . ''; } - // Lock - if ($object->status == $object::STATUS_VALIDATED && $signatory->checkSignatoriesSignatures($object->id, 'timesheet') && $difftotaltime == 0 && $diffworkinghoursMonth == 0) { - print '' . $langs->trans('Lock') . ''; + // Sign. + $displayButton = $onPhone ? '' : '' . ' ' . $langs->trans('Sign'); + if ($object->status == TimeSheet::STATUS_VALIDATED && !$signatory->checkSignatoriesSignatures($object->id, $object->element)) { + print '' . $displayButton . ''; } else { - print '' . $langs->trans('Lock') . ''; + print '' . $displayButton . ''; } - // Send - //@TODO changer le send to - //print '' . $langs->trans('SendMail') . ''; - - // Archive - if ($object->status == $object::STATUS_LOCKED && !empty(dol_dir_list($upload_dir . '/timesheetdocument/' . dol_sanitizeFileName($object->ref)))) { - print '' . $langs->trans('Archive') . ''; + // Lock. + $displayButton = $onPhone ? '' : '' . ' ' . $langs->trans('Lock'); + if ($object->status == TimeSheet::STATUS_VALIDATED && $signatory->checkSignatoriesSignatures($object->id, $object->element) && $diffTotalTime == 0) { + print '' . $displayButton . ''; } else { - print '' . $langs->trans('Archive') . ''; + print '' . $displayButton . ''; } - // Delete (need delete permission, or if draft, just need create/modify permission) - //print dolGetButtonAction($langs->trans('Delete'), '', 'delete', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=delete&token='.newToken(), '', $permissiontodelete || ($object->status == $object::STATUS_DRAFT && $permissiontoadd)); - } - print '
'."\n"; - } - - // Select mail models is same action as presend - if (GETPOST('modelselected')) { - $action = 'presend'; - } + // Send email. + $displayButton = $onPhone ? '' : '' . ' ' . $langs->trans('SendMail') . ' '; + if ($object->status == TimeSheet::STATUS_LOCKED) { + $fileParams = dol_most_recent_file($upload_dir . '/' . $object->element . 'document' . '/' . $object->ref); + $file = $fileParams['fullname']; + if (file_exists($file) && !strstr($fileParams['name'], 'specimen')) { + $forcebuilddoc = 0; + } else { + $forcebuilddoc = 1; + } + print dolGetButtonAction($displayButton, '', 'default', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=presend&forcebuilddoc=' . $forcebuilddoc . '&mode=init#formmailbeforetitle'); + } else { + print '' . $displayButton . ''; + } - if ($action != 'presend') { - print '
'; - print ''; // ancre + // Archive. + $displayButton = $onPhone ? '' : '' . ' ' . $langs->trans('Archive'); + if ($object->status == TimeSheet::STATUS_LOCKED && !empty(dol_dir_list($upload_dir . '/timesheetdocument/' . dol_sanitizeFileName($object->ref)))) { + print '' . $displayButton . ''; + } else { + print '' . $displayButton . ''; + } - $includedocgeneration = 1; + // Delete (need delete permission, or if draft, just need create/modify permission). + $displayButton = $onPhone ? '' : '' . ' ' . $langs->trans('Delete'); + print dolGetButtonAction($displayButton, '', 'delete', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=delete&token=' . newToken(), '', $permissiontodelete || ($object->status == TimeSheet::STATUS_DRAFT)); + } + print '
'; + } - // Documents - if ($includedocgeneration) { - $objref = dol_sanitizeFileName($object->ref); - $dir_files = $object->element . 'document/' . $objref; - $filedir = $upload_dir . '/' . $dir_files; - $urlsource = $_SERVER['PHP_SELF']. '?id=' .$object->id; - $genallowed = $permissiontoadd; // If you can read, you can build the PDF to read content - $delallowed = $permissiontodelete; // If you can create/edit, you can remove a file on card + // Select mail models is same action as presend. + if (GETPOST('modelselected')) { + $action = 'presend'; + } - print saturne_show_documents('dolisirh:TimeSheetDocument', $dir_files, $filedir, $urlsource, $genallowed, $object->status == $object::STATUS_LOCKED ? $delallowed : 0, $conf->global->DOLISIRH_TIMESHEETDOCUMENT_DEFAULT_MODEL, 1, 0, 0, 0, 0, '', '', '', $langs->defaultlang, $object, 0, 'removefile', $object->status == $object::STATUS_LOCKED && empty(dol_dir_list($filedir)), $langs->trans('TimeSheetMustBeLocked')); - } + if ($action != 'presend') { + print '
'; + // Documents. + $objRef = dol_sanitizeFileName($object->ref); + $dirFiles = $object->element . 'document/' . $objRef; + $fileDir = $upload_dir . '/' . $dirFiles; + $urlSource = $_SERVER['PHP_SELF'] . '?id=' . $object->id; - print '
'; + print saturne_show_documents('dolisirh:' . ucfirst($object->element) . 'Document', $dirFiles, $fileDir, $urlSource, $permissiontoadd, $permissiontodelete, $conf->global->DOLISIRH_TIMESHEETDOCUMENT_DEFAULT_MODEL, 1, 0, 0, 0, 0, '', '', '', $langs->defaultlang, $object, 0, 'remove_file', $object->status == TimeSheet::STATUS_LOCKED && empty(dol_dir_list($fileDir)), $langs->trans('ObjectMustBeLockedToGenerate', ucfirst($langs->transnoentities('The' . ucfirst($object->element))))); - $MAXEVENT = 10; + print '
'; - $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-list-alt imgforviewmode', dol_buildpath('/dolisirh/view/timesheet/timesheet_agenda.php', 1).'?id='.$object->id); + $moreHtmlCenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', dol_buildpath('/saturne/view/saturne_agenda.php', 1) . '?id=' . $object->id . '&module_name=DoliSIRH&object_type=' . $object->element); - // List of actions on element - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; - $formactions = new FormActions($db); - $somethingshown = $formactions->showactions($object, $object->element.'@'.$object->module, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlcenter); + // List of actions on element. + require_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; + $formActions = new FormActions($db); + $formActions->showactions($object, $object->element . '@' . $object->module, 0, 1, '', 10, '', $moreHtmlCenter); - print '
'; - } + print '
'; + } - //Select mail models is same action as presend - if (GETPOST('modelselected')) { - $action = 'presend'; - } + //Select mail models is same action as presend. + if (GETPOST('modelselected')) { + $action = 'presend'; + } - // Presend form - $modelmail = 'timesheet'; - $defaulttopic = 'InformationMessage'; - $diroutput = $conf->dolisirh->dir_output; - $trackid = 'timesheet'.$object->id; + // Presend form. + $modelmail = $object->element; + $defaulttopic = 'InformationMessage'; + $diroutput = $conf->dolisirh->dir_output; + $trackid = $object->element . $object->id; - include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; + require_once DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; } -// End of page +// End of page. llxFooter(); $db->close(); diff --git a/view/timesheet/timesheet_list.php b/view/timesheet/timesheet_list.php index c5fa529..3d09a6a 100644 --- a/view/timesheet/timesheet_list.php +++ b/view/timesheet/timesheet_list.php @@ -1,6 +1,5 @@ - * Copyright (C) ---Put here your own copyright and developer email--- +/* Copyright (C) 2021-2023 EVARISK * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,765 +16,687 @@ */ /** - * \file timesheet_list.php - * \ingroup dolisirh - * \brief List page for timesheet + * \file view/timesheet/timesheet_list.php + * \ingroup dolisirh + * \brief List page for timesheet. */ -//if (! defined('NOREQUIREDB')) define('NOREQUIREDB', '1'); // Do not create database handler $db -//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER', '1'); // Do not load object $user -//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1'); // Do not load object $mysoc -//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN', '1'); // Do not load object $langs -//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION', '1'); // Do not check injection attack on GET parameters -//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION', '1'); // Do not check injection attack on POST parameters -//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK', '1'); // Do not check CSRF attack (test on referer + on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on). -//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on) -//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK', '1'); // Do not check style html tag into posted data -//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1'); // If there is no need to load and show top and left menu -//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1'); // If we don't need to load the html.form.class.php -//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1'); // Do not load ajax.lib.php library -//if (! defined("NOLOGIN")) define("NOLOGIN", '1'); // If this page is public (can be called outside logged session). This include the NOIPCHECK too. -//if (! defined('NOIPCHECK')) define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip -//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT', 'auto'); // Force lang to a particular value -//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule'); // Force authentication handler -//if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN', 1); // The main.inc.php does not make a redirect if not logged, instead show simple error message -//if (! defined("FORCECSP")) define('FORCECSP', 'none'); // Disable all Content Security Policies -//if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET -//if (! defined('NOBROWSERNOTIF')) define('NOBROWSERNOTIF', '1'); // Disable browser notification -//if (! defined('NOSESSION')) define('NOSESSION', '1'); // On CLI mode, no need to use web sessions - -// Load Dolibarr environment -$res = 0; -// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined) -if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) { - $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"; -} -// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME -$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1; -while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) { - $i--; $j--; -} -if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) { - $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php"; -} -if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) { - $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php"; -} -// Try main.inc.php using relative path -if (!$res && file_exists("../main.inc.php")) { - $res = @include "../main.inc.php"; -} -if (!$res && file_exists("../../main.inc.php")) { - $res = @include "../../main.inc.php"; -} -if (!$res && file_exists("../../../main.inc.php")) { - $res = @include "../../../main.inc.php"; -} -if (!$res && file_exists("../../../../main.inc.php")) { - $res = @include "../../../../main.inc.php"; -} -if (!$res) { - die("Include of main fails"); +// Load DoliSIRH environment. +if (file_exists('../../dolisirh.main.inc.php')) { + require_once __DIR__ . '/../../dolisirh.main.inc.php'; +} elseif (file_exists('../../../dolisirh.main.inc.php')) { + require_once __DIR__ . '/../../../dolisirh.main.inc.php'; +} else { + die('Include of dolisirh main fails'); } +// Load Dolibarr libraries. require_once DOL_DOCUMENT_ROOT . '/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php'; -if (!empty($conf->categorie->enabled)) { - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcategory.class.php'; - require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; +if (isModEnabled('categorie')) { + require_once DOL_DOCUMENT_ROOT . '/core/class/html.formcategory.class.php'; + require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php'; } -// load dolisirh libraries +// load DoliSIRH libraries. require_once __DIR__ . '/../../class/timesheet.class.php'; -// for other modules -//dol_include_once('/othermodule/class/otherobject.class.php'); +// Global variables definitions. +global $conf, $db, $hookmanager, $langs, $user; -// Load translation files required by the page -$langs->loadLangs(array("dolisirh@dolisirh", "other")); +// Load translation files required by the page. +saturne_load_langs(); -$action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ... -$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists) -$show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk actions ? -$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation -$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button -$toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list -$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'timesheetlist'; // To manage different context of search +// Get parameters. +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view'; +$confirm = GETPOST('confirm', 'alpha'); +$cancel = GETPOST('cancel', 'alpha'); $backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page -$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') -$id = GETPOST('id', 'int'); +// Get list parameters. +$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists) +$show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk actions ? +$toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'timesheetlist'; // To manage different context of search +$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') +$mode = GETPOST('mode', 'aZ'); -// Load variable for pagination -$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; +// Get pagination parameters. +$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST('sortfield', 'aZ09comma'); $sortorder = GETPOST('sortorder', 'aZ09comma'); -$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); -if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) { - // If $page is not defined, or '' or -1 or if we click on clear filters - $page = 0; +$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST('page', 'int'); + +if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // If $page is not defined, or '' or -1 or if we click on clear filters. + $page = 0; } -$offset = $limit * $page; + +$offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; -if (!empty($conf->categorie->enabled)) { - $search_category_array = GETPOST("search_category_timesheet_list", "array"); +if (isModEnabled('categorie')) { + $search_category_array = GETPOST('search_category_timesheet_list', 'array'); } -// Initialize technical objects -$object = new TimeSheet($db); +// Initialize technical objects. +$object = new TimeSheet($db); $extrafields = new ExtraFields($db); -$diroutputmassaction = $conf->dolisirh->dir_output.'/temp/massgeneration/'.$user->id; -$hookmanager->initHooks(array('timesheetlist')); // Note that conf->hooks_modules contains array -// Fetch optionals attributes and labels +// Initialize view objects. +$form = new Form($db); + +$hookmanager->initHooks(['timesheetlist']); // Note that conf->hooks_modules contains array. + +// Fetch optionals attributes and labels. $extrafields->fetch_name_optionals_label($object->table_element); -//$extrafields->fetch_name_optionals_label($object->table_element_line); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); -// Default sort order (if not yet defined by previous GETPOST) +// Default sort order (if not yet defined by previous GETPOST). if (!$sortfield) { - reset($object->fields); // Reset is required to avoid key() to return null. - $sortfield = "t.".key($object->fields); // Set here default search field. By default 1st field in definition. + reset($object->fields); // Reset is required to avoid key() to return null. + $sortfield = 't.' . key($object->fields); // Set here default search field. By default, 1st field in definition. } if (!$sortorder) { - $sortorder = "ASC"; + $sortorder = 'ASC'; } -// Initialize array of search criterias -$search_all = GETPOST('search_all', 'alphanohtml'); -$search = array(); +// Initialize array of search criterias. +$search_all = GETPOST('search_all') ? GETPOST('search_all') : GETPOST('sall'); +$search = []; foreach ($object->fields as $key => $val) { - if (GETPOST('search_'.$key, 'alpha') !== '') { - $search[$key] = GETPOST('search_'.$key, 'alpha'); - } - if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { - $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_'.$key.'_dtstartmonth', 'int'), GETPOST('search_'.$key.'_dtstartday', 'int'), GETPOST('search_'.$key.'_dtstartyear', 'int')); - $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int')); - } + if (GETPOST('search_' . $key, 'alpha') !== '') { + $search[$key] = GETPOST('search_' . $key, 'alpha'); + } + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key . '_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_' . $key . '_dtstartmonth', 'int'), GETPOST('search_' . $key . '_dtstartday', 'int'), GETPOST('search_' . $key . '_dtstartyear', 'int')); + $search[$key . '_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_' . $key . '_dtendmonth', 'int'), GETPOST('search_' . $key . '_dtendday', 'int'), GETPOST('search_' . $key . '_dtendyear', 'int')); + } } -// List of fields to search into when doing a "search in all" -$fieldstosearchall = array(); +// List of fields to search into when doing a "search in all". +$fieldstosearchall = []; foreach ($object->fields as $key => $val) { - if (!empty($val['searchall'])) { - $fieldstosearchall['t.'.$key] = $val['label']; - } + if (!empty($val['searchall'])) { + $fieldstosearchall['t.' . $key] = $val['label']; + } } -// Definition of array of fields for columns -$arrayfields = array(); +// Definition of array of fields for columns. +$arrayfields = []; foreach ($object->fields as $key => $val) { - // If $val['visible']==0, then we never show the field - if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); - $arrayfields['t.'.$key] = array( - 'label'=>$val['label'], - 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), - 'position'=>$val['position'], - 'help'=> isset($val['help']) ? $val['help'] : '' - ); - } + // If $val['visible']==0, then we never show the field + if (!empty($val['visible'])) { + $visible = (int)dol_eval($val['visible'], 1); + $arrayfields['t.' . $key] = [ + 'label' => $val['label'], + 'checked' => (($visible < 0) ? 0 : 1), + 'enabled' => ($visible != 3 && dol_eval($val['enabled'], 1)), + 'position' => $val['position'], + 'help' => $val['help'] ?? '' + ]; + } } + // Extra fields -include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; +include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_list_array_fields.tpl.php'; $object->fields = dol_sort_array($object->fields, 'position'); -$arrayfields = dol_sort_array($arrayfields, 'position'); - -// There is several ways to check permission. -// Set $enablepermissioncheck to 1 to enable a minimum low level of checks -$enablepermissioncheck = 0; -if ($enablepermissioncheck) { - $permissiontoread = $user->rights->dolisirh->timesheet->read; - $permissiontoadd = $user->rights->dolisirh->timesheet->write; - $permissiontodelete = $user->rights->dolisirh->timesheet->delete; -} else { - $permissiontoread = 1; - $permissiontoadd = 1; - $permissiontodelete = 1; -} - -// Security check (enable the most restrictive one) -if ($user->socid > 0) accessforbidden(); -//if ($user->socid > 0) accessforbidden(); -//$socid = 0; if ($user->socid > 0) $socid = $user->socid; -//$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); -//restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); -if (empty($conf->dolisirh->enabled)) accessforbidden('Moule not enabled'); -if (!$permissiontoread) accessforbidden(); - +$arrayfields = dol_sort_array($arrayfields, 'position'); +// Security check (enable the most restrictive one) - Protection if external user +$permissiontoread = $user->rights->dolisirh->timesheet->read; +$permissiontoadd = $user->rights->dolisirh->timesheet->write; +$permissiontodelete = $user->rights->dolisirh->timesheet->delete; +saturne_check_access($permissiontoread); /* * Actions */ -if (GETPOST('cancel', 'alpha')) { - $action = 'list'; - $massaction = ''; -} -if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { - $massaction = ''; -} - -$parameters = array(); -$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +$parameters = []; +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks. if ($reshook < 0) { - setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } if (empty($reshook)) { - // Selection of new fields - include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; - - // Purge search criteria - if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers - foreach ($object->fields as $key => $val) { - $search[$key] = ''; - if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { - $search[$key.'_dtstart'] = ''; - $search[$key.'_dtend'] = ''; - } - } - $toselect = array(); - $search_array_options = array(); - $search_category_array = array(); - } - if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') - || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) { - $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation - } - - // Mass actions - $objectclass = 'TimeSheet'; - $objectlabel = 'TimeSheet'; - $uploaddir = $conf->dolisirh->dir_output; - include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; + if (GETPOST('cancel', 'alpha')) { + $action = 'list'; + $massaction = ''; + } + if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { + $massaction = ''; + } + + // Selection of new fields. + include DOL_DOCUMENT_ROOT . '/core/actions_changeselectedfields.inc.php'; + + // Purge search criteria. + if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers. + foreach ($object->fields as $key => $val) { + $search[$key] = ''; + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key.'_dtstart'] = ''; + $search[$key.'_dtend'] = ''; + } + } + $toselect = []; + $search_array_options = []; + $search_category_array = []; + } + if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') + || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) { + $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation. + } + + // Mass actions. + $objectclass = 'TimeSheet'; + $objectlabel = 'TimeSheet'; + $uploaddir = $conf->dolisirh->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; } - - /* * View */ -$form = new Form($db); - -$now = dol_now(); - -//$help_url="EN:Module_TimeSheet|FR:Module_TimeSheet_FR|ES:Módulo_TimeSheet"; +$title = $langs->trans('TimeSheetList'); $help_url = 'FR:Module_DoliSIRH'; -$title = $langs->trans('TimeSheetList'); -$morejs = array("/dolisirh/js/dolisirh.js"); -$morecss = array("/dolisirh/css/dolisirh.css"); - -// Build and execute select +// Build and execute select. // -------------------------------------------------------------------- $sql = 'SELECT '; $sql .= $object->getFieldList('t'); -// Add fields from extrafields +// Add fields from extrafields. if (!empty($extrafields->attributes[$object->table_element]['label'])) { - foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { - $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : ''); - } + foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { + $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ', ef.' . $key . ' as options_' . $key . ', ' : ''); + } } -// Add fields from hooks -$parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook + +// Add fields from hooks. +$parameters = []; +$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook. $sql .= preg_replace('/^,/', '', $hookmanager->resPrint); $sql = preg_replace('/,\s*$/', '', $sql); -$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t"; +$sql .= ' FROM ' . MAIN_DB_PREFIX.$object->table_element . ' as t'; if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)"; + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . $object->table_element . '_extrafields as ef on (t.rowid = ef.fk_object)'; } -// Add table from hooks -$parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook + +// Add table from hooks. +$parameters = []; +$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook. $sql .= $hookmanager->resPrint; if ($object->ismultientitymanaged == 1) { - $sql .= " WHERE t.entity IN (".getEntity($object->element).")"; + $sql .= ' WHERE t.entity IN (' . getEntity($object->element) . ')'; } else { - $sql .= " WHERE 1 = 1"; + $sql .= ' WHERE 1 = 1'; } + foreach ($search as $key => $val) { - if (array_key_exists($key, $object->fields)) { - if ($key == 'status' && $search[$key] == -1) { - continue; - } - $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0); - if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) { - if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) { - $search[$key] = ''; - } - $mode_search = 2; - } - if ($search[$key] != '') { - $sql .= natural_search($key, $search[$key], (($key == 'status') ? 2 : $mode_search)); - } - } else { - if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') { - $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key); - if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) { - if (preg_match('/_dtstart$/', $key)) { - $sql .= " AND t.".$columnName." >= '".$db->idate($search[$key])."'"; - } - if (preg_match('/_dtend$/', $key)) { - $sql .= " AND t." . $columnName . " <= '" . $db->idate($search[$key]) . "'"; - } - } - } - } + if (array_key_exists($key, $object->fields)) { + if ($key == 'status' && $val == -1) { + continue; + } + $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0); + if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) { + if ($val == '-1' || ($val === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) { + $val = ''; + } + $mode_search = 2; + } + if ($val != '') { + $sql .= natural_search('t.'. $db->escape($key), $val, (($key == 'status') ? 2 : $mode_search)); + } + } elseif (preg_match('/(_dtstart|_dtend)$/', $key) && $val != '') { + $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key); + if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) { + if (preg_match('/_dtstart$/', $key)) { + $sql .= ' AND t.' . $columnName . " >= '" . $db->idate($val) . "'"; + } + if (preg_match('/_dtend$/', $key)) { + $sql .= ' AND t.' . $columnName . " <= '" . $db->idate($val) . "'"; + } + } + } } if ($search_all) { - $sql .= natural_search(array_keys($fieldstosearchall), $search_all); + $sql .= natural_search(array_keys($fieldstosearchall), $search_all); } -if (!empty($conf->categorie->enabled)) { - $sql .= Categorie::getFilterSelectQuery('timesheet', "t.rowid", $search_category_array); +if (isModEnabled('categorie')) { + $sql .= Categorie::getFilterSelectQuery('timesheet', 't.rowid', $search_category_array); } -//$sql.= dolSqlDateFilter("t.field", $search_xxxday, $search_xxxmonth, $search_xxxyear); -// Add where from extra fields -include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; -// Add where from hooks -$parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook -$sql .= $hookmanager->resPrint; +// Add where from extra fields. +include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_list_search_sql.tpl.php'; -/* If a group by is required -$sql .= " GROUP BY "; -foreach($object->fields as $key => $val) { - $sql .= "t.".$key.", "; -} -// Add fields from extrafields -if (!empty($extrafields->attributes[$object->table_element]['label'])) { - foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { - $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : ''); - } -} -// Add where from hooks -$parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook +// Add where from hooks. +$parameters = []; +$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook. $sql .= $hookmanager->resPrint; -$sql = preg_replace('/,\s*$/', '', $sql); -*/ - -// Add HAVING from hooks -/* -$parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object); // Note that $action and $object may have been modified by hook -$sql .= empty($hookmanager->resPrint) ? "" : " HAVING 1=1 ".$hookmanager->resPrint; -*/ -// Count total nb of records -$nbtotalofrecords = ''; +// Count total nb of records. +$nbTotalOfRecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - /* This old and fast method to get and count full list returns all record so use a high amount of memory. - $resql = $db->query($sql); - $nbtotalofrecords = $db->num_rows($resql); - */ - /* The slow method does not consume memory on mysql (not tested on pgsql) */ - /*$resql = $db->query($sql, 0, 'auto', 1); - while ($db->fetch_object($resql)) { - $nbtotalofrecords++; - }*/ - /* The fast and low memory method to get and count full list converts the sql into a sql count */ - $sqlforcount = preg_replace('/^SELECT[a-z0-9\._\s\(\),]+FROM/i', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); - $resql = $db->query($sqlforcount); - $objforcount = $db->fetch_object($resql); - $nbtotalofrecords = $objforcount->nbtotalofrecords; - if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0 - $page = 0; - $offset = 0; - } - $db->free($resql); -} - -// Complete request and execute it with limit + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + $sqlForCount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); + $resql = $db->query($sqlForCount); + if ($resql) { + $objForCount = $db->fetch_object($resql); + $nbTotalOfRecords = $objForCount->nbtotalofrecords; + } else { + dol_print_error($db); + } + + if (($page * $limit) > $nbTotalOfRecords) { // if total of record found is smaller than page * limit, goto and load page 0 + $page = 0; + $offset = 0; + } + $db->free($resql); +} + +// Complete request and execute it with limit. $sql .= $db->order($sortfield, $sortorder); if ($limit) { - $sql .= $db->plimit($limit + 1, $offset); + $sql .= $db->plimit($limit + 1, $offset); } $resql = $db->query($sql); if (!$resql) { - dol_print_error($db); - exit; + dol_print_error($db); + exit; } $num = $db->num_rows($resql); - -// Direct jump if only one record found +// Direct jump if only one record found. if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) { - $obj = $db->fetch_object($resql); - $id = $obj->rowid; - header("Location: ".dol_buildpath('/dolisirh/view/timesheet/timesheet_card.php', 1).'?id='.$id); - exit; + $obj = $db->fetch_object($resql); + $id = $obj->rowid; + header('Location: ' . dol_buildpath('/dolisirh/view/timesheet/timesheet_card.php', 1) . '?id=' . $id); + exit; } - -// Output page +// Output page. // -------------------------------------------------------------------- -llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', ''); - -// Example : Adding jquery code -// print ''; - -$arrayofselected = is_array($toselect) ? $toselect : array(); +saturne_header(0, '', $title, $help_url, '', 0, 0, [], [], '', 'bodyforlist'); + +$arrayofselected = is_array($toselect) ? $toselect : []; $param = ''; -if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { - $param .= '&contextpage='.urlencode($contextpage); +if (!empty($mode)) { + $param .= '&mode=' . urlencode($mode); +} +if (!empty($contextpage) && $contextpage != $_SERVER['PHP_SELF']) { + $param .= '&contextpage=' . urlencode($contextpage); } if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); + $param .= '&limit=' . urlencode($limit); } foreach ($search as $key => $val) { - if (is_array($search[$key]) && count($search[$key])) { - foreach ($search[$key] as $skey) { - if ($skey != '') { - $param .= '&search_'.$key.'[]='.urlencode($skey); - } - } - } elseif ($search[$key] != '') { - $param .= '&search_'.$key.'='.urlencode($search[$key]); - } + if (is_array($val) && count($val)) { + foreach ($val as $skey) { + $param .= '&search_' . $key . '[]=' . urlencode($skey); + } + } elseif (preg_match('/(_dtstart|_dtend)$/', $key) && !empty($val)) { + $param .= '&search_' . $key . 'month=' . ((int) GETPOST('search_' . $key . 'month', 'int')); + $param .= '&search_' . $key . 'day=' . ((int) GETPOST('search_' . $key . 'day', 'int')); + $param .= '&search_' . $key . 'year=' . ((int) GETPOST('search_' . $key . 'year', 'int')); + } elseif ($val != '') { + $param .= '&search_' . $key . '=' . urlencode($val); + } } if ($optioncss != '') { - $param .= '&optioncss='.urlencode($optioncss); + $param .= '&optioncss='.urlencode($optioncss); } -// Add $param from extra fields -include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; -// Add $param from hooks -$parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook +// Add $param from extra fields. +include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_list_search_param.tpl.php'; + +// Add $param from hooks. +$parameters = []; +$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook $param .= $hookmanager->resPrint; -// List of mass actions available -$arrayofmassactions = array( - //'validate'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"), - //'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"), - //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), - //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), -); +// List of mass actions available. +$arrayofmassactions = []; if ($permissiontodelete) { - $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); + $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"') . $langs->trans('Delete'); } -if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) { - $arrayofmassactions = array(); +if (GETPOST('nomassaction', 'int') || in_array($massaction, ['presend', 'predelete'])) { + $arrayofmassactions = []; } $massactionbutton = $form->selectMassAction('', $arrayofmassactions); -print '
'."\n"; +print ''; if ($optioncss != '') { - print ''; + print ''; } -print ''; +print ''; print ''; print ''; -print ''; -print ''; -print ''; -print ''; - -$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/dolisirh/view/timesheet/timesheet_card.php', 1).'?action=create', '', $permissiontoadd); - -print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); - -// Add code for pre mass action (confirmation or email presend form) -$topicmail = "SendTimeSheetRef"; -$modelmail = "timesheet"; -$objecttmp = new TimeSheet($db); -$trackid = 'xxxx'.$object->id; -include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; +print ''; +print ''; +print ''; +print ''; +print ''; + +$newcardbutton = ''; +$newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER['PHP_SELF'] . '?mode=common' . preg_replace('/([&?])*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), ['morecss' => 'reposition']); +$newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER['PHP_SELF'] . '?mode=kanban' . preg_replace('/([&?])*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), ['morecss' => 'reposition']); +$newcardbutton .= dolGetButtonTitleSeparator(); +$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/dolisirh/view/timesheet/timesheet_card.php', 1) . '?action=create', '', $permissiontoadd); + +print_barre_liste($title, $page, $_SERVER['PHP_SELF'], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbTotalOfRecords, 'object_' . $object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); + +// Add code for pre mass action (confirmation or email presend form). +$topicmail = 'SendTimeSheetRef'; +$modelmail = 'timesheet'; +$objecttmp = new Timesheet($db); +$trackid = 'xxxx' . $object->id; +include DOL_DOCUMENT_ROOT . '/core/tpl/massactions_pre.tpl.php'; if ($search_all) { - $setupstring = ''; - foreach ($fieldstosearchall as $key => $val) { - $fieldstosearchall[$key] = $langs->trans($val); - $setupstring .= $key."=".$val.";"; - } - print ''."\n"; - print '
'.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'
'."\n"; + $setupstring = ''; + foreach ($fieldstosearchall as $key => $val) { + $fieldstosearchall[$key] = $langs->trans($val); + $setupstring .= $key . '=' . $val . ';'; + } + print ''; + print '
' . $langs->trans('FilterOnInto', $search_all) . join(', ', $fieldstosearchall) . '
'; } $moreforfilter = ''; -/*$moreforfilter.='
'; -$moreforfilter.= $langs->trans('MyFilter') . ': '; -$moreforfilter.= '
';*/ // Filter on categories -if (!empty($conf->categorie->enabled) && $user->rights->categorie->lire) { - $formcategory = new FormCategory($db); - $moreforfilter .= $formcategory->getFilterBox('timesheet', $search_category_array); +if (isModEnabled('categorie') && $user->rights->categorie->lire) { + $formcategory = new FormCategory($db); + $moreforfilter .= $formcategory->getFilterBox('timesheet', $search_category_array); } -$parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook +$parameters = []; +$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook. if (empty($reshook)) { - $moreforfilter .= $hookmanager->resPrint; + $moreforfilter .= $hookmanager->resPrint; } else { - $moreforfilter = $hookmanager->resPrint; + $moreforfilter = $hookmanager->resPrint; } if (!empty($moreforfilter)) { - print '
'; - print $moreforfilter; - print '
'; + print '
'; + print $moreforfilter; + print '
'; } -$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; -$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields +$varpage = empty($contextpage) ? $_SERVER['PHP_SELF'] : $contextpage; +$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')); // This also change content of $arrayfields. $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); -print '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table -print ''."\n"; - +print '
'; // You can use div-table-responsive-no-min if you don't need reserved height for your table. +print '
'; -// Fields title search +// Fields title search. // -------------------------------------------------------------------- print ''; -foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); - if ($key == 'status') { - $cssforfield .= ($cssforfield ? ' ' : '').'center'; - } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { - $cssforfield .= ($cssforfield ? ' ' : '').'center'; - } elseif (in_array($val['type'], array('timestamp'))) { - $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; - } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { - $cssforfield .= ($cssforfield ? ' ' : '').'right'; - } - if (!empty($arrayfields['t.'.$key]['checked'])) { - print ''; - } +// Action column +if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print ''; } -// Extra fields -include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; - -// Fields from hook -$parameters = array('arrayfields'=>$arrayfields); -$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook +foreach ($object->fields as $key => $val) { + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); + if ($key == 'status') { + $cssforfield .= ($cssforfield ? ' ' : '') . 'center'; + } elseif (in_array($val['type'], ['date', 'datetime', 'timestamp'])) { + $cssforfield .= ($cssforfield ? ' ' : '') . 'center'; + } elseif (in_array($val['type'], ['timestamp'])) { + $cssforfield .= ($cssforfield ? ' ' : '') . 'nowrap'; + } elseif (in_array($val['type'], ['double(24,8)', 'double(6,3)', 'integer', 'real', 'price']) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { + $cssforfield .= ($cssforfield ? ' ' : '') . 'right'; + } + if (!empty($arrayfields['t.' . $key]['checked'])) { + print ''; + } +} + +// Extra fields. +include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_list_search_input.tpl.php'; + +// Fields from hook. +$parameters = ['arrayfields' => $arrayfields]; +$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook. print $hookmanager->resPrint; // Action column -print ''; -print ''."\n"; +if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print ''; +} +print ''; +$totalarray = []; +$totalarray['nbfield'] = 0; -// Fields title label +// Fields title label. // -------------------------------------------------------------------- print ''; -foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); - if ($key == 'status') { - $cssforfield .= ($cssforfield ? ' ' : '').'center'; - } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { - $cssforfield .= ($cssforfield ? ' ' : '').'center'; - } elseif (in_array($val['type'], array('timestamp'))) { - $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; - } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { - $cssforfield .= ($cssforfield ? ' ' : '').'right'; - } - if (!empty($arrayfields['t.'.$key]['checked'])) { - print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''))."\n"; - } +if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER['PHP_SELF'], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch '); } -// Extra fields -include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; -// Hook fields -$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); -$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook +foreach ($object->fields as $key => $val) { + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); + if ($key == 'status') { + $cssforfield .= ($cssforfield ? ' ' : '') . 'center'; + } elseif (in_array($val['type'], ['date', 'datetime', 'timestamp'])) { + $cssforfield .= ($cssforfield ? ' ' : '') . 'center'; + } elseif (in_array($val['type'], ['timestamp'])) { + $cssforfield .= ($cssforfield ? ' ' : '') . 'nowrap'; + } elseif (in_array($val['type'], ['double(24,8)', 'double(6,3)', 'integer', 'real', 'price']) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { + $cssforfield .= ($cssforfield ? ' ' : '') . 'right'; + } + $cssforfield = preg_replace('/small\s*/', '', $cssforfield); // the 'small' css must not be used for the title label + if (!empty($arrayfields['t.' . $key]['checked'])) { + print getTitleFieldOfList($arrayfields['t.' . $key]['label'], 0, $_SERVER['PHP_SELF'], 't.' . $key, '', $param, ($cssforfield ? 'class="' . $cssforfield . '"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield . ' ' : '')); + $totalarray['nbfield']++; + } +} + +// Extra fields. +include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_list_search_title.tpl.php'; + +// Hook fields. +$parameters = ['arrayfields' => $arrayfields, 'param' => $param, 'sortfield' => $sortfield, 'sortorder' => $sortorder, 'totalarray' => &$totalarray]; +$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook. print $hookmanager->resPrint; // Action column -print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; -print ''."\n"; - +if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER['PHP_SELF'], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch '); +} +print ''; -// Detect if we need a fetch on each output line +// Detect if we need a fetch on each output line. $needToFetchEachLine = 0; if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) { - foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) { - if (preg_match('/\$object/', $val)) { - $needToFetchEachLine++; // There is at least one compute field that use $object - } - } + foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) { + if (preg_match('/\$object/', $val)) { + $needToFetchEachLine++; // There is at least one compute field that use $object. + } + } } - -// Loop on record +// Loop on record. // -------------------------------------------------------------------- $i = 0; -$totalarray = array(); +$savnbfield = $totalarray['nbfield'] + 1; +$totalarray = []; $totalarray['nbfield'] = 0; -while ($i < ($limit ? min($num, $limit) : $num)) { - $obj = $db->fetch_object($resql); - if (empty($obj)) { - break; // Should not happen - } - - // Store properties in $object - $object->setVarsFromFetchObj($obj); - - // Show here line of result - print ''; - foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); - if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { - $cssforfield .= ($cssforfield ? ' ' : '').'center'; - } elseif ($key == 'status') { - $cssforfield .= ($cssforfield ? ' ' : '').'center'; - } - - if (in_array($val['type'], array('timestamp'))) { - $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; - } elseif ($key == 'ref') { - $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; - } - - if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status')) && empty($val['arrayofkeyval'])) { - $cssforfield .= ($cssforfield ? ' ' : '').'right'; - } - //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100'; - - if (!empty($arrayfields['t.'.$key]['checked'])) { - print ''; - if ($key == 'status') { - print $object->getLibStatut(5); - } elseif ($key == 'rowid') { - print $object->showOutputField($val, $key, $object->id, ''); - } else { - print $object->showOutputField($val, $key, $object->$key, ''); - } - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - if (!empty($val['isameasure']) && $val['isameasure'] == 1) { - if (!$i) { - $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key; - } - if (!isset($totalarray['val'])) { - $totalarray['val'] = array(); - } - if (!isset($totalarray['val']['t.'.$key])) { - $totalarray['val']['t.'.$key] = 0; - } - $totalarray['val']['t.'.$key] += $object->$key; - } - } - } - // Extra fields - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; - // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); - $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - // Action column - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - - print ''."\n"; - - $i++; -} - -// Show total line -include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php'; - -// If no record found +$imaxinloop = ($limit ? min($num, $limit) : $num); +while ($i < $imaxinloop) { + $obj = $db->fetch_object($resql); + if (empty($obj)) { + break; // Should not happen. + } + + // Store properties in $object. + $object->setVarsFromFetchObj($obj); + + if ($mode == 'kanban') { + if ($i == 0) { + print ''; + } + } else { + // Show here line of result. + $j = 0; + print ''; + // Action column + if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print ''; + } + + foreach ($object->fields as $key => $val) { + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); + if (in_array($val['type'], ['date', 'datetime', 'timestamp'])) { + $cssforfield .= ($cssforfield ? ' ' : '') . 'center'; + } elseif ($key == 'status') { + $cssforfield .= ($cssforfield ? ' ' : '') . 'center'; + } + + if (in_array($val['type'], ['timestamp'])) { + $cssforfield .= ($cssforfield ? ' ' : '') . 'nowrap'; + } elseif ($key == 'ref') { + $cssforfield .= ($cssforfield ? ' ' : '') . 'nowrap'; + } + + if (in_array($val['type'], ['double(24,8)', 'double(6,3)', 'integer', 'real', 'price']) && !in_array($key, ['rowid', 'status']) && empty($val['arrayofkeyval'])) { + $cssforfield .= ($cssforfield ? ' ' : '') . 'right'; + } + //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100'; + + if (!empty($arrayfields['t.' . $key]['checked'])) { + print ''; + if ($key == 'status') { + print $object->getLibStatut(5); + } elseif ($key == 'rowid') { + print $object->showOutputField($val, $key, $object->id); + } else { + print $object->showOutputField($val, $key, $object->$key); + } + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + if (!empty($val['isameasure'])) { + if (!$i) { + $totalarray['pos'][$totalarray['nbfield']] = 't.' . $key; + } + if (!isset($totalarray['val'])) { + $totalarray['val'] = []; + } + if (!isset($totalarray['val']['t.' . $key])) { + $totalarray['val']['t.' . $key] = 0; + } + $totalarray['val']['t.' . $key] += $object->$key; + } + } + } + + // Extra fields. + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_list_print_fields.tpl.php'; + + $parameters = ['arrayfields' => $arrayfields, 'object' => $object, 'obj' => $obj, 'i' => $i, 'totalarray' => &$totalarray]; + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook. + print $hookmanager->resPrint; + // Action column + if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print ''; + } + if (!$i) { + $totalarray['nbfield']++; + } + print ''; + } + $i++; +} + +// Show total line. +include DOL_DOCUMENT_ROOT . '/core/tpl/list_print_total.tpl.php'; + +// If no record found. if ($num == 0) { - $colspan = 1; - foreach ($arrayfields as $key => $val) { - if (!empty($val['checked'])) { - $colspan++; - } - } - print ''; + $colspan = 1; + foreach ($arrayfields as $key => $val) { + if (!empty($val['checked'])) { + $colspan++; + } + } + print ''; } - $db->free($resql); -$parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql); -$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object); // Note that $action and $object may have been modified by hook +$parameters = ['arrayfields' => $arrayfields, 'sql' => $sql]; +$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; -print '
'; - if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) { - print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1); - } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) { - print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', 'maxwidth125', 1); - } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { - print '
'; - print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); - print '
'; - print '
'; - print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); - print '
'; - } elseif ($key == 'lang') { - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; - $formadmin = new FormAdmin($db); - print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth150 maxwidth200', 2); - } else { - print ''; - } - print '
'; + $searchpicto = $form->showFilterButtons('left'); + print $searchpicto; + print ''; + if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) { + print $form->selectarray('search_' . $key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100'); + } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) { + print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', 'maxwidth125', 1); + } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + print '
'; + print $form->selectDate($search[$key . '_dtstart'] ?: '', 'search_' . $key . '_dtstart', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + print '
'; + print '
'; + print $form->selectDate($search[$key . '_dtend'] ?: '', 'search_' . $key . '_dtend', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); + print '
'; + } elseif ($key == 'lang') { + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; + $formadmin = new FormAdmin($db); + print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth150 maxwidth200', 2); + } else { + print ''; + } + print '
'; -$searchpicto = $form->showFilterButtons(); -print $searchpicto; -print '
'; + $searchpicto = $form->showFilterButtons(); + print $searchpicto; + print '
'; - if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined - $selected = 0; - if (in_array($object->id, $arrayofselected)) { - $selected = 1; - } - print ''; - } - print '
'; + print '
'; + } + // Output Kanban + print $object->getKanbanView(); + if ($i == ($imaxinloop - 1)) { + print '
'; + print '
'; + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined. + $selected = 0; + if (in_array($object->id, $arrayofselected)) { + $selected = 1; + } + print ''; + } + print ''; + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined. + $selected = 0; + if (in_array($object->id, $arrayofselected)) { + $selected = 1; + } + print ''; + } + print '
'.$langs->trans("NoRecordFound").'
' . $langs->trans('NoRecordFound') . '
'."\n"; -print '
'."\n"; - -print '
'."\n"; - -if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) { - $hidegeneratedfilelistifempty = 1; - if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) { - $hidegeneratedfilelistifempty = 0; - } - - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; - $formfile = new FormFile($db); - - // Show list of available documents - $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder; - $urlsource .= str_replace('&', '&', $param); - - $filedir = $diroutputmassaction; - $genallowed = $permissiontoread; - $delallowed = $permissiontoadd; - - print $formfile->showdocuments('massfilesarea_dolisirh', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); -} +print ''; +print ''; +print ''; // End of page llxFooter();