dolibarr 25.0.0-alpha
evaluation_card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
4 * Copyright (C) 2021 Greg Rastklan <greg.rastklan@atm-consulting.fr>
5 * Copyright (C) 2021 Jean-Pascal BOUDET <jean-pascal.boudet@atm-consulting.fr>
6 * Copyright (C) 2021 Grégory BLEMAND <gregory.blemand@atm-consulting.fr>
7 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
8 * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
30// Load Dolibarr environment
31require '../main.inc.php';
40require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
41require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
42require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
43require_once DOL_DOCUMENT_ROOT.'/hrm/class/evaluation.class.php';
44require_once DOL_DOCUMENT_ROOT.'/hrm/class/job.class.php';
45require_once DOL_DOCUMENT_ROOT.'/hrm/class/skill.class.php';
46require_once DOL_DOCUMENT_ROOT.'/hrm/class/skillrank.class.php';
47require_once DOL_DOCUMENT_ROOT.'/hrm/lib/hrm_evaluation.lib.php';
48require_once DOL_DOCUMENT_ROOT.'/hrm/lib/hrm_skillrank.lib.php';
49
50
51// Load translation files required by the page
52$langs->loadLangs(array('hrm', 'other', 'products')); // why products?
53
54// Get parameters
55$id = GETPOSTINT('id');
56$ref = GETPOST('ref', 'alpha');
57$action = GETPOST('action', 'aZ09');
58$confirm = GETPOST('confirm', 'alpha');
59$cancel = GETPOST('cancel');
60$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'evaluationcard'; // To manage different context of search
61$backtopage = GETPOST('backtopage', 'alpha');
62$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
63$lineid = GETPOSTINT('lineid');
64
65// Initialize a technical objects
66$object = new Evaluation($db);
67$extrafields = new ExtraFields($db);
68$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id;
69$hookmanager->initHooks(array('evaluationcard', 'globalcard')); // Note that conf->hooks_modules contains array
70
71// Fetch optionals attributes and labels
72$extrafields->fetch_name_optionals_label($object->table_element);
73
74$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
75
76// Initialize array of search criteria
77$search_all = GETPOST("search_all", 'alpha');
78$search = array();
79foreach ($object->fields as $key => $val) {
80 if (GETPOST('search_'.$key, 'alpha')) {
81 $search[$key] = GETPOST('search_'.$key, 'alpha');
82 }
83}
84
85if (empty($action) && empty($id) && empty($ref)) {
86 $action = 'view';
87}
88
89// Load object
90include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be 'include', not 'include_once'.
91
92// Permissions
93$permissiontoread = $user->hasRight('hrm', 'evaluation', 'read');
94$permissiontoadd = $user->hasRight('hrm', 'evaluation', 'write'); // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
95$permissiontovalidate = (getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $user->hasRight('hrm', 'evaluation_advance', 'validate')) || (!getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && $permissiontoadd);
96$permissiontoclose = $user->hasRight('hrm', 'evaluation', 'write');
97$permissiontodelete = $user->hasRight('hrm', 'evaluation', 'delete')/* || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT)*/;
98$permissiondellink = $user->hasRight('hrm', 'evaluation', 'write'); // Used by the include of actions_dellink.inc.php
99$upload_dir = $conf->hrm->multidir_output[isset($object->entity) ? $object->entity : 1].'/evaluation';
100
101// Security check (enable the most restrictive one)
102//if ($user->socid > 0) accessforbidden();
103//if ($user->socid > 0) $socid = $user->socid;
104$isdraft = ($object->status == Evaluation::STATUS_DRAFT) ? 1 : 0;
105restrictedArea($user, $object->element, $object, $object->table_element, '', 'fk_soc', 'rowid', $isdraft);
106if (!isModEnabled("hrm")) {
108}
109if (!$permissiontoread || ($action === 'create' && !$permissiontoadd)) {
111}
112
113/*
114 * Actions
115 */
116
117$parameters = array();
118$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
119if ($reshook < 0) {
120 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
121}
122
123if (empty($reshook)) {
124 $error = 0;
125
126 $backurlforlist = dol_buildpath('/hrm/evaluation_list.php', 1);
127
128 if (empty($backtopage) || ($cancel && empty($id))) {
129 if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
130 if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) { // Test on permission not required
131 $backtopage = $backurlforlist;
132 } else {
133 $backtopage = dol_buildpath('/hrm/evaluation_card.php', 1).'?id='.($id > 0 ? $id : '__ID__');
134 }
135 }
136 }
137
138 if ($action == 'saveSkill' && $permissiontoadd) {
139 $TNote = GETPOST('TNote', 'array');
140 if (!empty($TNote)) {
141 foreach ($object->lines as $line) {
142 $line->rankorder = ($TNote[$line->fk_skill] == "NA" ? -1 : $TNote[$line->fk_skill]);
143 $result = $line->update($user);
144 if ($result < 0) {
145 setEventMessages($line->error, $line->errors, 'errors');
146 }
147 }
148 //setEventMessage($langs->trans("SaveLevelSkill"));
149 }
150
151 $action = 'validate';
152 }
153
154 if ($action == "validate" && $permissiontoadd) {
155 $TNote = GETPOST('TNote', 'array');
156 $emptyTNote = true;
157 foreach ($object->lines as $line) {
158 if (!in_array($TNote[$line->fk_skill], array("0", ""))) {
159 $emptyTNote = false;
160 break;
161 }
162 }
163 if ($emptyTNote) {
164 setEventMessage($langs->trans("WarningEvaluationEmptyValidate"), 'errors');
165 $action = '';
166 }
167 }
168
169 $triggermodname = 'HRM_EVALUATION_MODIFY'; // Name of trigger action code to execute when we modify record
170
171 // Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen
172 include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
173
174 // Actions when linking object each other
175 include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php';
176
177 // Actions when printing a doc from card
178 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
179
180 // Action to move up and down lines of object
181 //include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php';
182
183
184 if ($action == 'set_thirdparty' && $permissiontoadd) {
185 $object->setValueFrom('fk_soc', GETPOSTINT('fk_soc'), '', null, 'date', '', $user, $triggermodname);
186 }
187 if ($action == 'classin' && $permissiontoadd) {
188 $object->setProject(GETPOSTINT('projectid'));
189 }
190
191 // Actions to send emails
192 $triggersendname = 'HRM_EVALUATION_SENTBYMAIL';
193 $autocopy = 'MAIN_MAIL_AUTOCOPY_EVALUATION_TO';
194 $trackid = 'evaluation'.$object->id;
195 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
196
197 if ($action == 'close' && $permissiontoadd) {
198 // save evaldet lines to user;
199 $sk = new SkillRank($db);
200 $SkillrecordsForActiveUser = $sk->fetchAll('ASC', 'fk_skill', 0, 0, "(fk_object:=:".((int) $object->fk_user).") AND (objecttype:=:'".$db->escape(SkillRank::SKILLRANK_TYPE_USER)."')", 'AND');
201 '@phan-var-force SkillRank[] $SkillrecordsForActiveUser';
202
203 $errors = 0;
204 // we go through the evaldets of the eval
205 foreach ($object->lines as $key => $line) {
206 // no reference .. we add the line to use it
207 if (count($SkillrecordsForActiveUser) == 0) {
208 $newSkill = new SkillRank($db);
209 $resCreate = $newSkill->cloneFromCurrentSkill($line, $object->fk_user);
210
211 if ($resCreate <= 0) {
212 $errors++;
213 setEventMessage($langs->trans('ErrorCreateUserSkill', $line->fk_skill));
214 }
215 } else {
216 //check if the skill is present to use it
217 $keyFind = 0;
218 foreach ($SkillrecordsForActiveUser as $k => $sr) {
219 if ($sr->fk_skill == $line->fk_skill) {
220 $keyFind = $k;
221 break;
222 }
223 }
224 //we update the skill user
225 if ($keyFind) {
226 $updSkill = $SkillrecordsForActiveUser[$keyFind];
227
228 $updSkill->rankorder = $line->rankorder;
229 $result = $updSkill->update($user);
230 if ($result < 0) {
231 setEventMessages($updSkill->error, $updSkill->errors, 'errors');
232 }
233 } else { // else we create the skill
234 $newSkill = new SkillRank($db);
235 $resCreate = $newSkill->cloneFromCurrentSkill($line, $object->fk_user);
236 }
237 }
238 }
239 if (empty($errors)) {
240 $object->setStatut(Evaluation::STATUS_CLOSED);
241 setEventMessage('EmployeeSkillsUpdated');
242 }
243 }
244
245 if ($action == 'reopen' && $permissiontoadd) {
246 // no update here we just change the evaluation status
247 $object->setStatut(Evaluation::STATUS_VALIDATED);
248 }
249
250 // Action to build doc
251 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
252
253 // action to remove file
254 if ($action == 'remove_file_comfirm' && $permissiontoadd) {
255 // Delete file in doc form
256 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
257
258 $upload_dir = $conf->hrm->dir_output;
259 $file = $upload_dir.'/'.GETPOST('file');
260 $ret = dol_delete_file($file, 1, 0, 0, $object);
261 if ($ret) {
262 setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs');
263 } else {
264 setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors');
265 }
266 }
267}
268
269
270/*
271 * View
272 */
273
274$form = new Form($db);
275$formfile = new FormFile($db);
276
277$title = $langs->trans("Evaluation");
278$help_url = '';
279$css = array();
280$css[] = '/hrm/css/style.css';
281llxHeader('', $title, $help_url, '', 0, 0, '', $css);
282?>
283<script>
284 $(document).ready(function() {
285 $("#btn_valid").click(function() {
286 console.log("Click on btn_valid");
287 var form = $("#form_save_rank");
288 form.submit();
289 return true;
290 });
291 });
292</script>
293<?php
294
295// Part to create
296if ($action == 'create') {
297 print load_fiche_titre($langs->trans("NewEval"), '', 'object_' . $object->picto);
298
299 print '<form method="POST" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
300 print '<input type="hidden" name="token" value="'.newToken().'">';
301 print '<input type="hidden" name="action" value="add">';
302 if ($backtopage) {
303 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
304 }
305 if ($backtopageforcancel) {
306 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
307 }
308
309 print dol_get_fiche_head(array(), '');
310
311 print '<table class="border centpercent tableforfieldcreate">'."\n";
312
313 // Common attributes
314 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php';
315
316 // Other attributes
317 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
318
319 print '</table>'."\n";
320
321 print dol_get_fiche_end();
322
323 print $form->buttonsSaveCancel("Create", "Cancel");
324
325 print '</form>';
326}
327
328// Part to edit record
329if (($id || $ref) && $action == 'edit') {
330 print load_fiche_titre($langs->trans("Evaluation"), '', 'object_'.$object->picto);
331
332 print '<form method="POST" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
333 print '<input type="hidden" name="token" value="'.newToken().'">';
334 print '<input type="hidden" name="action" value="update">';
335 print '<input type="hidden" name="id" value="'.$object->id.'">';
336 if ($backtopage) {
337 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
338 }
339 if ($backtopageforcancel) {
340 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
341 }
342
343 print dol_get_fiche_head();
344
345 print '<table class="border centpercent tableforfieldedit">'."\n";
346
347 // Common attributes
348 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_edit.tpl.php';
349
350 // Other attributes
351 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php';
352
353 print '</table>';
354
355 print dol_get_fiche_end();
356
357 print $form->buttonsSaveCancel();
358
359 print '</form>';
360}
361
362// Part to show record
363if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
364 $res = $object->fetch_optionals();
365
366 $head = evaluationPrepareHead($object);
367 print dol_get_fiche_head($head, 'card', $langs->trans("Workstation"), -1, $object->picto, 0, '', '', 0, '', 1);
368
369 $formconfirm = '';
370
371 if ($action == 'validate' && $permissiontovalidate) {
372 // Confirm validate proposal
373 $error = 0;
374
375 // We verify whether the object is provisionally numbering
376 $ref = substr($object->ref, 1, 4);
377 if ($ref == 'PROV') {
378 $numref = $object->getNextNumRef();
379 if (empty($numref)) {
380 $error++;
381 setEventMessages($object->error, $object->errors, 'errors');
382 }
383 } else {
384 $numref = (string) $object->ref;
385 }
386
387 $text = $langs->trans('ConfirmValidateEvaluation', $numref);
388 if (isModEnabled('notification')) {
389 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
390 $notify = new Notify($db);
391 $text .= '<br>';
392 $text .= $notify->confirmMessage('HRM_EVALUATION_VALIDATE', 0, $object);
393 }
394
395 if (!$error) {
396 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateEvaluation'), $text, 'confirm_validate', '', 0, 1);
397 }
398 }
399
400 // Confirmation to delete
401 if ($action == 'delete') {
402 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteEvaluation'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1);
403 }
404 // Confirmation to delete line
405 if ($action == 'deleteline') {
406 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1);
407 }
408 // Clone confirmation
409 if ($action == 'clone') {
410 // Create an array for form
411 $formquestion = array();
412 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
413 }
414
415 // Call Hook formConfirm
416 $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
417 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
418 if (empty($reshook)) {
419 $formconfirm .= $hookmanager->resPrint;
420 } elseif ($reshook > 0) {
421 $formconfirm = $hookmanager->resPrint;
422 }
423
424 // Print form confirm
425 print $formconfirm;
426
427
428 // Object card
429 // ------------------------------------------------------------
430 $linkback = '<a href="'.dol_buildpath('/hrm/evaluation_list.php', 1).'?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
431
432 $morehtmlref = '<div class="refidno">';
433 $morehtmlref .= $langs->trans('Label').' : '.$object->label;
434 $u_position = new User(($db));
435 $u_position->fetch($object->fk_user);
436 $morehtmlref .= '<br>'.$u_position->getNomUrl(1);
437 $job = new Job($db);
438 $job->fetch($object->fk_job);
439 $morehtmlref .= '<br>'.$langs->trans('JobProfile').' : '.$job->getNomUrl(1);
440 $morehtmlref .= '</div>';
441
442
443
444 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
445
446
447 print '<div class="fichecenter">';
448 print '<div class="fichehalfleft">';
449 print '<div class="underbanner clearboth"></div>';
450 print '<table class="border centpercent tableforfield">'."\n";
451
452 $object->fields['label']['visible'] = 0; // Already in banner
453 $object->fields['fk_user']['visible'] = 0; // Already in banner
454 $object->fields['fk_job']['visible'] = 0; // Already in banner
455 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
456
457 // Other attributes. Fields from hook formObjectOptions and Extrafields.
458 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
459
460 print '</table>';
461 print '</div>';
462 print '</div>';
463
464 print '<div class="clearboth"></div>';
465
466 print dol_get_fiche_end();
467
468
469 // Lines when evaluation is in edit mode
470
471 if (!empty($object->table_element_line) && $object->status == Evaluation::STATUS_DRAFT) {
472 // Show object lines
473 $result = $object->getLinesArray();
474 if ($result < 0) {
475 dol_print_error($db, $object->error, $object->errors);
476 }
477
478 print '<br>';
479
480 print ' <form name="form_save_rank" id="form_save_rank" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '' : '#line_'.GETPOSTINT('lineid')).'" method="POST">
481 <input type="hidden" name="token" value="' . newToken().'">
482 <input type="hidden" name="action" value="saveSkill">
483 <input type="hidden" name="mode" value="">
484 <input type="hidden" name="page_y" value="">
485 <input type="hidden" name="id" value="' . $object->id.'">
486 ';
487
488 if (!empty($conf->use_javascript_ajax) && $object->status == 0) {
489 include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
490 }
491
492 $conf->modules_parts['tpl']['hrm'] = '/hrm/core/tpl/'; // To use the hrm tpl on this screen
493
494 print '<div class="div-table-responsive-no-min">';
495 if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) {
496 print '<table id="tablelines" class="noborder noshadow centpercent">';
497 }
498
499 // Lines of evaluated skills
500 // $object is Evaluation
501 $object->printObjectLines($action, $mysoc, null, GETPOSTINT('lineid'), 1);
502
503 if (empty($object->lines)) {
504 print '<tr><td colspan="4"><span class="opacitymedium">'.img_warning().' '.$langs->trans("TheJobProfileHasNoSkillsDefinedFixBefore").'</td></tr>';
505 }
506
507 // Form to add new line
508 /*
509 if ($object->status == 0 && $permissiontoadd && $action != 'selectlines') {
510 if ($action != 'editline') {
511 // Add products/services form
512
513 $parameters = array();
514 $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
515 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
516 if (empty($reshook))
517 $object->formAddObjectLine(1, $mysoc, $soc);
518 }
519 }
520 */
521
522 if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) {
523 print '</table>';
524 }
525 print '</div>';
526
527 print "</form>\n";
528
529 print "<br>";
530 }
531
532 // Lines when evaluation is validated
533
534 if ($object->status != Evaluation::STATUS_DRAFT) {
535 // Recovery of skills related to this evaluation
536
537 $sql = 'select';
538 $sql .= ' e.ref,';
539 $sql .= ' e.date_creation,';
540 $sql .= ' e.fk_job,';
541 $sql .= ' j.label as "refjob",';
542 $sql .= ' ed.fk_skill,';
543
544 $sql .= ' sk.label as "skilllabel",';
545 $sql .= ' sk.skill_type,';
546 $sql .= ' sk.description,';
547 $sql .= ' ed.rankorder,';
548 $sql .= ' ed.required_rank,';
549 $sql .= ' ed.rankorder as "userRankForSkill",';
550 $sql .= ' skdet_user.description as "userRankForSkillDesc",';
551 $sql .= ' skdet_required.description as "required_rank_desc"';
552
553 $sql .= ' FROM ' . MAIN_DB_PREFIX . 'hrm_evaluation as e';
554 $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'hrm_evaluationdet as ed ON e.rowid = ed.fk_evaluation';
555 $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'hrm_job as j ON e.fk_job = j.rowid';
556 $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'hrm_skill as sk ON ed.fk_skill = sk.rowid';
557 $sql .= ' INNER JOIN ' . MAIN_DB_PREFIX . 'hrm_skilldet as skdet_user ON (skdet_user.fk_skill = sk.rowid AND skdet_user.rankorder = ed.rankorder)';
558 //$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "hrm_skillrank as skr ON (j.rowid = skr.fk_object AND skr.fk_skill = ed.fk_skill AND skr.objecttype = 'job')";
559 $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'hrm_skilldet as skdet_required ON (skdet_required.fk_skill = sk.rowid AND skdet_required.rankorder = ed.required_rank)';
560 $sql .= " WHERE e.rowid =" . ((int) $object->id);
561
562 // echo $sql;
563
564 $resql = $db->query($sql);
565 $Tab = array();
566
567 if ($resql) {
568 $num = 0;
569 while ($obj = $db->fetch_object($resql)) {
570 $Tab[$num] = new stdClass();
571 $class = '';
572 $Tab[$num]->skill_type = $obj->skill_type;
573 $Tab[$num]->skill_id = $obj->fk_skill;
574 $Tab[$num]->skilllabel = $obj->skilllabel;
575 $Tab[$num]->description = $obj->description;
576 $Tab[$num]->userRankForSkill = '<span title="'.$obj->userRankForSkillDesc.'" class="radio_js_bloc_number TNote_1">' . $obj->userRankForSkill . '</span>';
577
578 $required_rank = $obj->required_rank;
579 $required_rank_desc = $obj->required_rank_desc;
580 if ($required_rank == "-1") {
581 $required_rank = $langs->trans("NA");
582 $required_rank_desc = $langs->trans("NA");
583 } elseif ($required_rank == "0") {
584 $required_rank_desc = $langs->trans('SkillNotRequired');
585 }
586
587 $Tab[$num]->required_rank = '<span title="'.$required_rank_desc.'" class="radio_js_bloc_number TNote_1">' . $required_rank . '</span>';
588
589 if ($obj->userRankForSkill < 0 || $obj->required_rank < 0) {
590 $title = $langs->trans('NA');
591 $class .= 'na';
592 } elseif ($obj->userRankForSkill > $obj->required_rank) {
593 $title = $langs->trans('MaxlevelGreaterThanShort');
594 $class .= 'veryhappy';
595 } elseif ($obj->userRankForSkill == $obj->required_rank) {
596 $title = $langs->trans('MaxLevelEqualToShort');
597 $class .= 'happy';
598 } elseif ($obj->userRankForSkill < $obj->required_rank) {
599 $title = $langs->trans('MaxLevelLowerThanShort');
600 $class .= 'sad';
601 }
602
603 $Tab[$num]->result = '<span title="'.$title.'" class="classfortooltip ' . $class . ' note">&nbsp;</span>';
604
605 $num++;
606 }
607
608 print '<br>';
609
610 print '<div class="div-table-responsive-no-min">';
611 print '<table id="tablelines" class="noborder noshadow centpercent">';
612
613 print '<tr class="liste_titre">';
614 print '<th style="width:auto;text-align:auto" class="liste_titre">' . $langs->trans("TypeSkill") . ' </th>';
615 print '<th style="width:auto;text-align:auto" class="liste_titre">' . $langs->trans("Label") . '</th>';
616 print '<th style="width:auto;text-align:auto" class="liste_titre">' . $langs->trans("Description") . '</th>';
617 print '<th style="width:auto;text-align:center" class="liste_titre">' . $langs->trans("EmployeeRank") . '</th>';
618 print '<th style="width:auto;text-align:center" class="liste_titre">' . $langs->trans("RequiredRank") . '</th>';
619 print '<th style="width:auto;text-align:auto" class="liste_titre">' . $langs->trans("Result") . ' ' .$form->textwithpicto('', GetLegendSkills(), 1) .'</th>';
620 print '</tr>';
621
622 $sk = new Skill($db);
623 foreach ($Tab as $t) {
624 $sk->fetch($t->skill_id);
625
626 print '<tr>';
627 print ' <td>' . dolPrintHTML(Skill::typeCodeToLabel($t->skill_type)) . '</td>';
628 print ' <td class="tdoverflowmax200">' . $sk->getNomUrl(1) . '</td>';
629 print ' <td class="tdoverflowmax200" title="'.dolPrintHTMLForAttribute($t->description).'">' . dolPrintHTML($t->description) . '</td>';
630 print ' <td class="center">' . $t->userRankForSkill . '</td>';
631 print ' <td class="center">' . $t->required_rank . '</td>';
632 print ' <td>' . $t->result . '</td>';
633 print '</tr>';
634 }
635
636 print '</table>';
637 print '</div>'; ?>
638
639 <script>
640
641 $(document).ready(function() {
642 $(".radio_js_bloc_number").tooltip();
643 });
644
645 </script>
646
647 <?php
648 }
649 }
650
651 // Buttons for actions
652 if ($action != 'presend' && $action != 'editline') {
653 print '<div class="tabsAction">'."\n";
654 $parameters = array();
655 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
656 if ($reshook < 0) {
657 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
658 }
659
660 if (empty($reshook)) {
661 // Send
662 if (empty($user->socid)) {
663 print dolGetButtonAction('', $langs->trans('SendMail'), 'email', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&mode=init&token='.newToken().'#formmailbeforetitle');
664 }
665
666 // Back to draft
667 if ($object->status == $object::STATUS_VALIDATED) {
668 print dolGetButtonAction('', $langs->trans('SetToDraft'), 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=confirm_setdraft&confirm=yes&token='.newToken(), '', $permissiontoadd);
669 print dolGetButtonAction('', $langs->trans('Close'), 'close', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=close&token='.newToken(), '', $permissiontodelete || ($object->status == $object::STATUS_CLOSED && $permissiontoclose));
670 } elseif ($object->status != $object::STATUS_CLOSED) {
671 print dolGetButtonAction('', $langs->trans('Modify'), 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&token='.newToken(), '', $permissiontoadd);
672 }
673
674 if ($object->status == $object::STATUS_CLOSED) {
675 print dolGetButtonAction($langs->trans('ReOpen'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken(), '', $permissiontoadd);
676 }
677
678
679 // Validate
680 if ($object->status == $object::STATUS_DRAFT) {
681 if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) {
682 print dolGetButtonAction($langs->trans('Save').'&nbsp;'.$langs->trans('and').'&nbsp;'.$langs->trans('Valid'), '', 'default', '#', 'btn_valid', $permissiontovalidate);
683 } else {
684 $langs->load("errors");
685 print dolGetButtonAction($langs->trans("ErrorAddAtLeastOneLineFirst"), $langs->trans("Validate"), 'default', '#', '', 0);
686 }
687 }
688
689
690 // Delete (need delete permission, or if draft, just need create/modify permission)
691 print dolGetButtonAction($langs->trans('Delete'), $langs->trans('Delete'), 'delete', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=delete&token='.newToken(), '', $permissiontodelete, array('attr' => array('class' => 'reposition')))."\n";
692 }
693
694
695 print '</div>'."\n";
696 }
697
698 // Select mail models is same action as presend
699 if (GETPOST('modelselected')) {
700 $action = 'presend';
701 }
702
703 if ($action != 'presend') {
704 print '<div class="fichecenter"><div class="fichehalfleft">';
705 print '<a name="builddoc"></a>'; // ancre
706
707 $includedocgeneration = 1;
708
709 // Documents
710 if ($user->hasRight('hrm', 'evaluation', 'read')) {
711 $objref = dol_sanitizeFileName($object->ref);
712 $relativepath = $objref.'/'.$objref.'.pdf';
713 $filedir = $conf->hrm->dir_output.'/'.$object->element.'/'.$objref;
714 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
715 $genallowed = $user->hasRight('hrm', 'evaluation', 'read'); // If you can read, you can build the PDF to read content
716 $delallowed = $user->hasRight('hrm', 'evaluation', 'write'); // If you can create/edit, you can remove a file on card
717 print $formfile->showdocuments('hrm:Evaluation', $object->element.'/'.$objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang, '', $object, 0, 'remove_file_comfirm');
718 }
719
720 // Show links to link elements
721 $tmparray = $form->showLinkToObjectBlock($object, array(), array('evaluation'), 1);
722 $linktoelem = $tmparray['linktoelem'];
723 $htmltoenteralink = $tmparray['htmltoenteralink'];
724 print $htmltoenteralink;
725
726 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
727
728
729 print '</div><div class="fichehalfright">';
730
731 $MAXEVENT = 10;
732
733 $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/hrm/evaluation_agenda.php?id='.$object->id);
734
735 // List of actions on element
736 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
737 $formactions = new FormActions($db);
738 $somethingshown = $formactions->showactions($object, $object->element.'@'.$object->module, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlcenter);
739
740 print '</div></div>';
741 }
742
743 //Select mail models is same action as presend
744 /*if (GETPOST('modelselected')) {
745 // $action = 'presend';
746 }*/ // To delete.
747
748 // Presend form
749 $modelmail = 'evaluation';
750 $defaulttopic = 'InformationMessage';
751 $diroutput = $conf->hrm->dir_output;
752 $trackid = 'evaluation'.$object->id;
753
754 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
755}
756
757// End of page
758llxFooter();
759$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
Class for Evaluation.
Class to manage standard extra fields.
Class to manage building of HTML components.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class for Job.
Definition job.class.php:38
Class to manage the table of subscription to notifications.
Class for Skill.
static typeCodeToLabel($code)
Class for SkillRank.
Class to manage Dolibarr users.
global $mysoc
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
evaluationPrepareHead($object)
Prepare array of tabs for Evaluation.
GetLegendSkills()
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
Definition html.lib.php:540
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
Definition html.lib.php:738
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $nodie=0, $mode='')
Check permissions of a user to show a page and an object.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.