dolibarr 23.0.3
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 MDW <mdeweerd@users.noreply.github.com>
8 * Copyright (C) 2024-2025 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 $line->update($user);
144 }
145 //setEventMessage($langs->trans("SaveLevelSkill"));
146 }
147
148 $action = 'validate';
149 }
150
151 if ($action == "validate" && $permissiontoadd) {
152 $TNote = GETPOST('TNote', 'array');
153 $emptyTNote = true;
154 foreach ($object->lines as $line) {
155 if (!in_array($TNote[$line->fk_skill], array("0", ""))) {
156 $emptyTNote = false;
157 break;
158 }
159 }
160 if ($emptyTNote) {
161 setEventMessage($langs->trans("WarningEvaluationEmptyValidate"), 'errors');
162 $action = '';
163 }
164 }
165
166 $triggermodname = 'HRM_EVALUATION_MODIFY'; // Name of trigger action code to execute when we modify record
167
168 // Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen
169 include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
170
171 // Actions when linking object each other
172 include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php';
173
174 // Actions when printing a doc from card
175 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
176
177 // Action to move up and down lines of object
178 //include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php';
179
180
181 if ($action == 'set_thirdparty' && $permissiontoadd) {
182 $object->setValueFrom('fk_soc', GETPOSTINT('fk_soc'), '', null, 'date', '', $user, $triggermodname);
183 }
184 if ($action == 'classin' && $permissiontoadd) {
185 $object->setProject(GETPOSTINT('projectid'));
186 }
187
188 // Actions to send emails
189 $triggersendname = 'HRM_EVALUATION_SENTBYMAIL';
190 $autocopy = 'MAIN_MAIL_AUTOCOPY_EVALUATION_TO';
191 $trackid = 'evaluation'.$object->id;
192 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
193
194 if ($action == 'close' && $permissiontoadd) {
195 // save evaldet lines to user;
196 $sk = new SkillRank($db);
197 $SkillrecordsForActiveUser = $sk->fetchAll('ASC', 'fk_skill', 0, 0, "(fk_object:=:".((int) $object->fk_user).") AND (objecttype:=:'".$db->escape(SkillRank::SKILLRANK_TYPE_USER)."')", 'AND');
198 '@phan-var-force SkillRank[] $SkillrecordsForActiveUser';
199
200 $errors = 0;
201 // we go through the evaldets of the eval
202 foreach ($object->lines as $key => $line) {
203 // no reference .. we add the line to use it
204 if (count($SkillrecordsForActiveUser) == 0) {
205 $newSkill = new SkillRank($db);
206 $resCreate = $newSkill->cloneFromCurrentSkill($line, $object->fk_user);
207
208 if ($resCreate <= 0) {
209 $errors++;
210 setEventMessage($langs->trans('ErrorCreateUserSkill', $line->fk_skill));
211 }
212 } else {
213 //check if the skill is present to use it
214 $find = false;
215 $keyFind = 0;
216 foreach ($SkillrecordsForActiveUser as $k => $sr) {
217 if ($sr->fk_skill == $line->fk_skill) {
218 $keyFind = $k;
219 $find = true;
220 break;
221 }
222 }
223 //we update the skill user
224 if ($find) {
225 $updSkill = $SkillrecordsForActiveUser[$k];
226
227 $updSkill->rankorder = $line->rankorder;
228 $updSkill->update($user);
229 } else { // sinon on ajoute la skill
230 $newSkill = new SkillRank($db);
231 $resCreate = $newSkill->cloneFromCurrentSkill($line, $object->fk_user);
232 }
233 }
234 }
235 if (empty($errors)) {
236 $object->setStatut(Evaluation::STATUS_CLOSED);
237 setEventMessage('EmployeeSkillsUpdated');
238 }
239 }
240
241 if ($action == 'reopen' && $permissiontoadd) {
242 // no update here we just change the evaluation status
243 $object->setStatut(Evaluation::STATUS_VALIDATED);
244 }
245
246 // Action to build doc
247 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
248
249 // action to remove file
250 if ($action == 'remove_file_comfirm' && $permissiontoadd) {
251 // Delete file in doc form
252 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
253
254 $upload_dir = $conf->hrm->dir_output;
255 $file = $upload_dir.'/'.GETPOST('file');
256 $ret = dol_delete_file($file, 0, 0, 0, $object);
257 if ($ret) {
258 setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs');
259 } else {
260 setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors');
261 }
262 }
263}
264
265
266/*
267 * View
268 */
269
270$form = new Form($db);
271$formfile = new FormFile($db);
272
273$title = $langs->trans("Evaluation");
274$help_url = '';
275$css = array();
276$css[] = '/hrm/css/style.css';
277llxHeader('', $title, $help_url, '', 0, 0, '', $css);
278
279print '<script type="text/javascript" language="javascript">
280 $(document).ready(function() {
281 $("#btn_valid").click(function() {
282 console.log("Click on btn_valid");
283 var form = $("#form_save_rank");
284 form.submit();
285 return true;
286 });
287 });
288</script>';
289
290// Part to create
291if ($action == 'create') {
292 print load_fiche_titre($langs->trans("NewEval"), '', 'object_' . $object->picto);
293
294 print '<form method="POST" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
295 print '<input type="hidden" name="token" value="'.newToken().'">';
296 print '<input type="hidden" name="action" value="add">';
297 if ($backtopage) {
298 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
299 }
300 if ($backtopageforcancel) {
301 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
302 }
303
304 print dol_get_fiche_head(array(), '');
305
306 print '<table class="border centpercent tableforfieldcreate">'."\n";
307
308 // Common attributes
309 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php';
310
311 // Other attributes
312 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
313
314 print '</table>'."\n";
315
316 print dol_get_fiche_end();
317
318 print $form->buttonsSaveCancel("Create", "Cancel");
319
320 print '</form>';
321}
322
323// Part to edit record
324if (($id || $ref) && $action == 'edit') {
325 print load_fiche_titre($langs->trans("Evaluation"), '', 'object_'.$object->picto);
326
327 print '<form method="POST" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
328 print '<input type="hidden" name="token" value="'.newToken().'">';
329 print '<input type="hidden" name="action" value="update">';
330 print '<input type="hidden" name="id" value="'.$object->id.'">';
331 if ($backtopage) {
332 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
333 }
334 if ($backtopageforcancel) {
335 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
336 }
337
338 print dol_get_fiche_head();
339
340 print '<table class="border centpercent tableforfieldedit">'."\n";
341
342 // Common attributes
343 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_edit.tpl.php';
344
345 // Other attributes
346 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php';
347
348 print '</table>';
349
350 print dol_get_fiche_end();
351
352 print $form->buttonsSaveCancel();
353
354 print '</form>';
355}
356
357// Part to show record
358if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
359 $res = $object->fetch_optionals();
360
361 $head = evaluationPrepareHead($object);
362 print dol_get_fiche_head($head, 'card', $langs->trans("Workstation"), -1, $object->picto);
363
364 $formconfirm = '';
365
366 if ($action == 'validate' && $permissiontovalidate) {
367 // Confirm validate proposal
368 $error = 0;
369
370 // We verify whether the object is provisionally numbering
371 $ref = substr($object->ref, 1, 4);
372 if ($ref == 'PROV') {
373 $numref = $object->getNextNumRef();
374 if (empty($numref)) {
375 $error++;
376 setEventMessages($object->error, $object->errors, 'errors');
377 }
378 } else {
379 $numref = (string) $object->ref;
380 }
381
382 $text = $langs->trans('ConfirmValidateEvaluation', $numref);
383 if (isModEnabled('notification')) {
384 require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php';
385 $notify = new Notify($db);
386 $text .= '<br>';
387 $text .= $notify->confirmMessage('HRM_EVALUATION_VALIDATE', 0, $object);
388 }
389
390 if (!$error) {
391 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateEvaluation'), $text, 'confirm_validate', '', 0, 1);
392 }
393 }
394
395 // Confirmation to delete
396 if ($action == 'delete') {
397 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteEvaluation'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1);
398 }
399 // Confirmation to delete line
400 if ($action == 'deleteline') {
401 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1);
402 }
403 // Clone confirmation
404 if ($action == 'clone') {
405 // Create an array for form
406 $formquestion = array();
407 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
408 }
409
410 // Call Hook formConfirm
411 $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
412 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
413 if (empty($reshook)) {
414 $formconfirm .= $hookmanager->resPrint;
415 } elseif ($reshook > 0) {
416 $formconfirm = $hookmanager->resPrint;
417 }
418
419 // Print form confirm
420 print $formconfirm;
421
422
423 // Object card
424 // ------------------------------------------------------------
425 $linkback = '<a href="'.dol_buildpath('/hrm/evaluation_list.php', 1).'?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
426
427 $morehtmlref = '<div class="refidno">';
428 $morehtmlref .= $langs->trans('Label').' : '.$object->label;
429 $u_position = new User(($db));
430 $u_position->fetch($object->fk_user);
431 $morehtmlref .= '<br>'.$u_position->getNomUrl(1);
432 $job = new Job($db);
433 $job->fetch($object->fk_job);
434 $morehtmlref .= '<br>'.$langs->trans('JobProfile').' : '.$job->getNomUrl(1);
435 $morehtmlref .= '</div>';
436
437
438
439 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
440
441
442 print '<div class="fichecenter">';
443 print '<div class="fichehalfleft">';
444 print '<div class="underbanner clearboth"></div>';
445 print '<table class="border centpercent tableforfield">'."\n";
446
447 $object->fields['label']['visible'] = 0; // Already in banner
448 $object->fields['fk_user']['visible'] = 0; // Already in banner
449 $object->fields['fk_job']['visible'] = 0; // Already in banner
450 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
451
452 // Other attributes. Fields from hook formObjectOptions and Extrafields.
453 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
454
455 print '</table>';
456 print '</div>';
457 print '</div>';
458
459 print '<div class="clearboth"></div>';
460
461 print dol_get_fiche_end();
462
463
464 // Lines when evaluation is in edit mode
465
466 if (!empty($object->table_element_line) && $object->status == Evaluation::STATUS_DRAFT) {
467 // Show object lines
468 $result = $object->getLinesArray();
469 if ($result < 0) {
470 dol_print_error($db, $object->error, $object->errors);
471 }
472
473 print '<br>';
474
475 print ' <form name="form_save_rank" id="form_save_rank" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '' : '#line_'.GETPOSTINT('lineid')).'" method="POST">
476 <input type="hidden" name="token" value="' . newToken().'">
477 <input type="hidden" name="action" value="saveSkill">
478 <input type="hidden" name="mode" value="">
479 <input type="hidden" name="page_y" value="">
480 <input type="hidden" name="id" value="' . $object->id.'">
481 ';
482
483 if (!empty($conf->use_javascript_ajax) && $object->status == 0) {
484 include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
485 }
486
487 $conf->modules_parts['tpl']['hrm'] = '/hrm/core/tpl/'; // Pour utilisation du tpl hrm sur cet écran
488
489 print '<div class="div-table-responsive-no-min">';
490 if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) {
491 print '<table id="tablelines" class="noborder noshadow centpercent">';
492 }
493
494 // Lines of evaluated skills
495 // $object is Evaluation
496 $object->printObjectLines($action, $mysoc, null, GETPOSTINT('lineid'), 1);
497
498 if (empty($object->lines)) {
499 print '<tr><td colspan="4"><span class="opacitymedium">'.img_warning().' '.$langs->trans("TheJobProfileHasNoSkillsDefinedFixBefore").'</td></tr>';
500 }
501
502 // Form to add new line
503 /*
504 if ($object->status == 0 && $permissiontoadd && $action != 'selectlines') {
505 if ($action != 'editline') {
506 // Add products/services form
507
508 $parameters = array();
509 $reshook = $hookmanager->executeHooks('formAddObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
510 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
511 if (empty($reshook))
512 $object->formAddObjectLine(1, $mysoc, $soc);
513 }
514 }
515 */
516
517 if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) {
518 print '</table>';
519 }
520 print '</div>';
521
522 print "</form>\n";
523
524 print "<br>";
525 }
526
527 // Lines when evaluation is validated
528
529 if ($object->status != Evaluation::STATUS_DRAFT) {
530 // Recovery of skills related to this evaluation
531
532 $sql = 'select';
533 $sql .= ' e.ref,';
534 $sql .= ' e.date_creation,';
535 $sql .= ' e.fk_job,';
536 $sql .= ' j.label as "refjob",';
537 $sql .= ' ed.fk_skill,';
538
539 $sql .= ' sk.label as "skilllabel",';
540 $sql .= ' sk.skill_type,';
541 $sql .= ' sk.description,';
542 $sql .= ' ed.rankorder,';
543 $sql .= ' ed.required_rank,';
544 $sql .= ' ed.rankorder as "userRankForSkill",';
545 $sql .= ' skdet_user.description as "userRankForSkillDesc",';
546 $sql .= ' skdet_required.description as "required_rank_desc"';
547
548 $sql .= ' FROM ' . MAIN_DB_PREFIX . 'hrm_evaluation as e';
549 $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'hrm_evaluationdet as ed ON e.rowid = ed.fk_evaluation';
550 $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'hrm_job as j ON e.fk_job = j.rowid';
551 $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'hrm_skill as sk ON ed.fk_skill = sk.rowid';
552 $sql .= ' INNER JOIN ' . MAIN_DB_PREFIX . 'hrm_skilldet as skdet_user ON (skdet_user.fk_skill = sk.rowid AND skdet_user.rankorder = ed.rankorder)';
553 //$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')";
554 $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)';
555 $sql .= " WHERE e.rowid =" . ((int) $object->id);
556
557 // echo $sql;
558
559 $resql = $db->query($sql);
560 $Tab = array();
561
562 if ($resql) {
563 $num = 0;
564 while ($obj = $db->fetch_object($resql)) {
565 $Tab[$num] = new stdClass();
566 $class = '';
567 $Tab[$num]->skill_type = $obj->skill_type;
568 $Tab[$num]->skill_id = $obj->fk_skill;
569 $Tab[$num]->skilllabel = $obj->skilllabel;
570 $Tab[$num]->description = $obj->description;
571 $Tab[$num]->userRankForSkill = '<span title="'.$obj->userRankForSkillDesc.'" class="radio_js_bloc_number TNote_1">' . $obj->userRankForSkill . '</span>';
572
573 $required_rank = $obj->required_rank;
574 $required_rank_desc = $obj->required_rank_desc;
575 if ($required_rank == "-1") {
576 $required_rank = $langs->trans("NA");
577 $required_rank_desc = $langs->trans("NA");
578 } elseif ($required_rank == "0") {
579 $required_rank_desc = $langs->trans('SkillNotRequired');
580 }
581
582 $Tab[$num]->required_rank = '<span title="'.$required_rank_desc.'" class="radio_js_bloc_number TNote_1">' . $required_rank . '</span>';
583
584 if ($obj->userRankForSkill < 0 || $obj->required_rank < 0) {
585 $title = $langs->trans('NA');
586 $class .= 'na';
587 } elseif ($obj->userRankForSkill > $obj->required_rank) {
588 $title = $langs->trans('MaxlevelGreaterThanShort');
589 $class .= 'veryhappy';
590 } elseif ($obj->userRankForSkill == $obj->required_rank) {
591 $title = $langs->trans('MaxLevelEqualToShort');
592 $class .= 'happy';
593 } elseif ($obj->userRankForSkill < $obj->required_rank) {
594 $title = $langs->trans('MaxLevelLowerThanShort');
595 $class .= 'sad';
596 }
597
598 $Tab[$num]->result = '<span title="'.$title.'" class="classfortooltip ' . $class . ' note">&nbsp;</span>';
599
600 $num++;
601 }
602
603 print '<br>';
604
605 print '<div class="div-table-responsive-no-min">';
606 print '<table id="tablelines" class="noborder noshadow centpercent">';
607
608 print '<tr class="liste_titre">';
609 print '<th style="width:auto;text-align:auto" class="liste_titre">' . $langs->trans("TypeSkill") . ' </th>';
610 print '<th style="width:auto;text-align:auto" class="liste_titre">' . $langs->trans("Label") . '</th>';
611 print '<th style="width:auto;text-align:auto" class="liste_titre">' . $langs->trans("Description") . '</th>';
612 print '<th style="width:auto;text-align:center" class="liste_titre">' . $langs->trans("EmployeeRank") . '</th>';
613 print '<th style="width:auto;text-align:center" class="liste_titre">' . $langs->trans("RequiredRank") . '</th>';
614 print '<th style="width:auto;text-align:auto" class="liste_titre">' . $langs->trans("Result") . ' ' .$form->textwithpicto('', GetLegendSkills(), 1) .'</th>';
615 print '</tr>';
616
617 $sk = new Skill($db);
618 foreach ($Tab as $t) {
619 $sk->fetch($t->skill_id);
620
621 print '<tr>';
622 print ' <td>' . dolPrintHTML(Skill::typeCodeToLabel($t->skill_type)) . '</td>';
623 print ' <td class="tdoverflowmax200">' . $sk->getNomUrl(1) . '</td>';
624 print ' <td class="tdoverflowmax200" title="'.dolPrintHTMLForAttribute($t->description).'">' . dolPrintHTML($t->description) . '</td>';
625 print ' <td class="center">' . $t->userRankForSkill . '</td>';
626 print ' <td class="center">' . $t->required_rank . '</td>';
627 print ' <td>' . $t->result . '</td>';
628 print '</tr>';
629 }
630
631 print '</table>';
632 print '</div>'; ?>
633
634 <script>
635
636 $(document).ready(function() {
637 $(".radio_js_bloc_number").tooltip();
638 });
639
640 </script>
641
642 <?php
643 }
644 }
645
646 // Buttons for actions
647 if ($action != 'presend' && $action != 'editline') {
648 print '<div class="tabsAction">'."\n";
649 $parameters = array();
650 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
651 if ($reshook < 0) {
652 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
653 }
654
655 if (empty($reshook)) {
656 // Send
657 if (empty($user->socid)) {
658 print dolGetButtonAction('', $langs->trans('SendMail'), 'email', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&mode=init&token='.newToken().'#formmailbeforetitle');
659 }
660
661 // Back to draft
662 if ($object->status == $object::STATUS_VALIDATED) {
663 print dolGetButtonAction('', $langs->trans('SetToDraft'), 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=confirm_setdraft&confirm=yes&token='.newToken(), '', $permissiontoadd);
664 print dolGetButtonAction('', $langs->trans('Close'), 'close', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=close&token='.newToken(), '', $permissiontodelete || ($object->status == $object::STATUS_CLOSED && $permissiontoclose));
665 } elseif ($object->status != $object::STATUS_CLOSED) {
666 print dolGetButtonAction('', $langs->trans('Modify'), 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&token='.newToken(), '', $permissiontoadd);
667 }
668
669 if ($object->status == $object::STATUS_CLOSED) {
670 print dolGetButtonAction($langs->trans('ReOpen'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken(), '', $permissiontoadd);
671 }
672
673
674 // Validate
675 if ($object->status == $object::STATUS_DRAFT) {
676 if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) {
677 print dolGetButtonAction($langs->trans('Save').'&nbsp;'.$langs->trans('and').'&nbsp;'.$langs->trans('Valid'), '', 'default', '#', 'btn_valid', $permissiontovalidate);
678 } else {
679 $langs->load("errors");
680 print dolGetButtonAction($langs->trans("ErrorAddAtLeastOneLineFirst"), $langs->trans("Validate"), 'default', '#', '', 0);
681 }
682 }
683
684
685 // Delete (need delete permission, or if draft, just need create/modify permission)
686 print dolGetButtonAction($langs->trans('Delete'), '', 'delete', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=delete&token='.newToken(), '', $permissiontodelete);
687 }
688
689
690 print '</div>'."\n";
691 }
692
693 // Select mail models is same action as presend
694 if (GETPOST('modelselected')) {
695 $action = 'presend';
696 }
697
698 if ($action != 'presend') {
699 print '<div class="fichecenter"><div class="fichehalfleft">';
700 print '<a name="builddoc"></a>'; // ancre
701
702 $includedocgeneration = 1;
703
704 // Documents
705 if ($user->hasRight('hrm', 'evaluation', 'read')) {
706 $objref = dol_sanitizeFileName($object->ref);
707 $relativepath = $objref.'/'.$objref.'.pdf';
708 $filedir = $conf->hrm->dir_output.'/'.$object->element.'/'.$objref;
709 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
710 $genallowed = $user->hasRight('hrm', 'evaluation', 'read'); // If you can read, you can build the PDF to read content
711 $delallowed = $user->hasRight('hrm', 'evaluation', 'write'); // If you can create/edit, you can remove a file on card
712 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');
713 }
714
715 // Show links to link elements
716 $tmparray = $form->showLinkToObjectBlock($object, array(), array('evaluation'), 1);
717 $linktoelem = $tmparray['linktoelem'];
718 $htmltoenteralink = $tmparray['htmltoenteralink'];
719 print $htmltoenteralink;
720
721 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
722
723
724 print '</div><div class="fichehalfright">';
725
726 $MAXEVENT = 10;
727
728 $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/hrm/evaluation_agenda.php?id='.$object->id);
729
730 // List of actions on element
731 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
732 $formactions = new FormActions($db);
733 $somethingshown = $formactions->showactions($object, $object->element.'@'.$object->module, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlcenter);
734
735 print '</div></div>';
736 }
737
738 //Select mail models is same action as presend
739 /*if (GETPOST('modelselected')) {
740 // $action = 'presend';
741 }*/ // To delete.
742
743 // Presend form
744 $modelmail = 'evaluation';
745 $defaulttopic = 'InformationMessage';
746 $diroutput = $conf->hrm->dir_output;
747 $trackid = 'evaluation'.$object->id;
748
749 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
750}
751
752// End of page
753llxFooter();
754$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
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.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
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.
dolPrintHTML($s, $allowiframe=0)
Return a string (that can be on several lines) ready to be output on a HTML page.
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.
setEventMessage($mesgs, $style='mesgs', $noduplicate=0, $attop=0)
Set event message in dol_events session object.
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'.
dolGetButtonAction($label, $text='', $actionType='default', $url='', $id='', $userRight=1, $params=array())
Function dolGetButtonAction.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
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()
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.