dolibarr 24.0.0-beta
skill_tab.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2021 Grégory Blémand <contact@atm-consulting.fr>
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-2025 Frédéric France <frederic.france@free.fr>
8 * Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
9 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <https://www.gnu.org/licenses/>.
23 */
24
32// Load Dolibarr environment
33require '../main.inc.php';
34require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
35require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
36require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
37require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
38require_once DOL_DOCUMENT_ROOT.'/hrm/class/job.class.php';
39require_once DOL_DOCUMENT_ROOT.'/hrm/class/skill.class.php';
40require_once DOL_DOCUMENT_ROOT.'/hrm/class/skillrank.class.php';
41require_once DOL_DOCUMENT_ROOT.'/hrm/lib/hrm_skill.lib.php';
42require_once DOL_DOCUMENT_ROOT.'/hrm/class/evaluation.class.php';
43require_once DOL_DOCUMENT_ROOT.'/hrm/lib/hrm_evaluation.lib.php';
44require_once DOL_DOCUMENT_ROOT.'/hrm/class/evaluationdet.class.php';
45
55// Load translation files required by the page
56$langs->loadLangs(array('hrm', 'companies', 'other'));
57
58// Get Parameters
59$action = GETPOST('action', 'aZ09');
60$confirm = GETPOST('confirm', 'alpha');
61$cancel = GETPOST('cancel');
62$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'skillcard'; // To manage different context of search
63$backtopage = GETPOST('backtopage', 'alpha');
64$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
65
66$id = GETPOSTINT('id');
67$TSkillsToAdd = GETPOST('fk_skill', 'array');
68$objecttype = GETPOST('objecttype', 'alpha');
69$TNote = GETPOST('TNote', 'array');
70$lineid = GETPOSTINT('lineid');
71
72if (empty($objecttype)) {
73 $objecttype = 'job';
74}
75
76$TAuthorizedObjects = array('job', 'user');
77$skill = new SkillRank($db);
78
79// Initialize a technical objects
80$object = null;
81if (in_array($objecttype, $TAuthorizedObjects)) {
82 if ($objecttype == 'job') {
83 $object = new Job($db);
84 } elseif ($objecttype == 'user') {
85 $object = new User($db);
86 } else {
87 accessforbidden('ErrorBadObjectType');
88 }
89} else {
90 accessforbidden('ErrorBadObjectType');
91}
92
93$hookmanager->initHooks(array('skilltab', 'globalcard')); // Note that conf->hooks_modules contains array
94
95// Load object
96include DOL_DOCUMENT_ROOT . '/core/actions_fetchobject.inc.php'; // Must be 'include', not 'include_once'.
97if (method_exists($object, 'loadPersonalConf')) {
98 $object->loadPersonalConf();
99}
100
101// Permissions
102$permissiontoread = $user->hasRight('hrm', 'all', 'read');
103$permissiontoadd = $user->hasRight('hrm', 'all', 'write'); // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
104
105// Security check (enable the most restrictive one)
106if ($user->socid > 0) {
108}
109if (!isModEnabled('hrm')) {
111}
112if (!$permissiontoread) {
114}
115
116
117/*
118 * Actions
119 */
120
121$parameters = array();
122$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
123if ($reshook < 0) {
124 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
125}
126
127if (empty($reshook)) {
128 $error = 0;
129
130 $backurlforlist = DOL_URL_ROOT.'/hrm/skill_list.php';
131
132 if (empty($backtopage) || ($cancel && empty($id))) {
133 if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
134 if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
135 $backtopage = $backurlforlist;
136 } else {
137 $backtopage = DOL_URL_ROOT.'/hrm/skill_list.php?id=' . ($id > 0 ? $id : '__ID__');
138 }
139 }
140 }
141
142 // update national_registration_number
143 if ($action == 'setnational_registration_number' && $permissiontoadd) {
144 $object->national_registration_number = (string) GETPOST('national_registration_number', 'alphanohtml');
145 $result = $object->update($user);
146 if ($result < 0) {
147 setEventMessages($object->error, $object->errors, 'errors');
148 }
149 }
150
151 if ($action == 'addSkill' && $permissiontoadd) {
152 $db->begin();
153 $error = 0;
154
155 if (empty($TSkillsToAdd)) {
156 setEventMessage('ErrNoSkillSelected', 'errors');
157 $error++;
158 }
159 if (!$error) {
160 $ret = -1;
161 foreach ($TSkillsToAdd as $k => $v) {
162 $skillAdded = new SkillRank($db);
163 $skillAdded->fk_skill = (int) $v;
164 $skillAdded->fk_object = $id;
165 $skillAdded->objecttype = $objecttype;
166 $ret = $skillAdded->create($user);
167 if ($ret < 0) {
168 $error++;
169 setEventMessages($skillAdded->error, null, 'errors');
170 break;
171 } else {
172 // Create new EvaluationLine for each Skill to add in draft evaluation
173 $sql_eval = "SELECT e.rowid FROM ".MAIN_DB_PREFIX."hrm_evaluation as e";
174 $sql_eval .= " WHERE e.status = 0 ";
175 $sql_eval .= " AND e.entity = ".(int) getEntity($object->element);
176 $sql_eval .= " AND e.fk_job = ".(int) $object->id;
177 $result = $db->query($sql_eval);
178 $numEvals = $db->num_rows($result);
179 $i = 0;
180 while ($i < $numEvals) {
181 $objEval = $db->fetch_object($result);
182 $line = new EvaluationLine($db);
183 $line->fk_evaluation = $objEval->rowid;
184 $line->fk_skill = (int) $v;
185 $line->required_rank = 0;
186 $line->fk_rank = 0;
187
188 $res = $line->create($user);
189 if ($res < 0) {
190 $error++;
191 setEventMessages($line->error, null, 'errors');
192 break;
193 }
194 $i++;
195 }
196 }
197 }
198 if (!$error) {
199 setEventMessages($langs->trans("SaveAddSkill"), null);
200 $db->commit();
201 } else {
202 $db->rollback();
203 }
204 }
205 } elseif ($action == 'saveSkill' && $permissiontoadd) {
206 if (!empty($TNote)) {
207 $db->begin();
208 $error = 0;
209 foreach ($TNote as $skillId => $rank) {
210 $rank = ($rank == "NA" ? -1 : $rank);
211 $TSkills = $skill->fetchAll('ASC', 't.rowid', 0, 0, '(fk_object:=:'.((int) $id).") AND (objecttype:=:'".$db->escape($objecttype)."') AND (fk_skill:=:".((int) $skillId).')');
212 '@phan-var-force SkillRank[] $tSkills';
213 if (is_array($TSkills) && !empty($TSkills)) {
214 foreach ($TSkills as $tmpObj) {
215 $tmpObj->rankorder = $rank;
216 $ret = $tmpObj->update($user);
217 if ($ret < 0) {
218 $error++;
219 setEventMessages($tmpObj->error, null, 'errors');
220 break;
221 }
222 if (!$error) {
223 // Update draft Evaluations using this Skill
224 $sql_eval = "SELECT e.rowid FROM ".MAIN_DB_PREFIX."hrm_evaluation as e";
225 $sql_eval .= " WHERE e.status = 0 ";
226 $sql_eval .= " AND e.entity = ".getEntity($object->element);
227 $sql_eval .= " AND e.fk_job = ".(int) $object->id;
228 $result = $db->query($sql_eval);
229 $numEvals = $db->num_rows($result);
230 $i = 0;
231 while ($i < $numEvals) {
232 $objEval = $db->fetch_object($result);
233 $line = new EvaluationLine($db);
234 $lines = $line->fetchAll('', '', 0, 0, '((fk_skill:=:'.((int) $tmpObj->fk_skill).') AND (fk_evaluation:=:'.((int) $objEval->rowid).'))');
235 if (is_array($lines)) {
236 foreach ($lines as $key => $evalline) {
237 // Verify if fetchAll gave the right object
238 if (is_object($evalline) && $evalline instanceof EvaluationLine) {
239 $evalline->required_rank = $rank;
240 $ret = $evalline->update($user);
241 if ($ret <= 0) {
242 $error++;
243 setEventMessages($evalline->error, null, 'errors');
244 break;
245 }
246 }
247 }
248 } else {
249 $error++;
250 setEventMessages($line->error, null, 'errors');
251 break;
252 }
253 $i++;
254 }
255 }
256 }
257 } else {
258 $error++;
259 setEventMessages($skill->error, null, 'errors');
260 break;
261 }
262 }
263 if (!$error) {
264 setEventMessages($langs->trans("SaveLevelSkill"), null);
265 $db->commit();
266 } else {
267 $db->rollback();
268 }
269 header("Location: " . DOL_URL_ROOT.'/hrm/skill_tab.php?id=' . $id. '&objecttype=job');
270 exit;
271 }
272 } elseif ($action == 'confirm_deleteskill' && $confirm == 'yes' && $permissiontoadd) {
273 $db->begin();
274 $error = 0;
275 $skillToDelete = new SkillRank($db);
276 $ret = $skillToDelete->fetch($lineid);
277 if ($ret > 0) {
278 // Remove EvaluationLine foreach draft Evaluations using this Skill
279 $sql_eval = "SELECT e.rowid FROM ".MAIN_DB_PREFIX."hrm_evaluation as e";
280 $sql_eval .= " WHERE e.status = 0 ";
281 $sql_eval .= " AND e.entity = ".getEntity($object->element);
282 $sql_eval .= " AND e.fk_job = ".(int) $object->id;
283 $result = $db->query($sql_eval);
284 $numEvals = $db->num_rows($result);
285 $i = 0;
286 while ($i < $numEvals) {
287 $objEval = $db->fetch_object($result);
288 $line = new EvaluationLine($db);
289 $lines = $line->fetchAll('', '', 0, 0, '((fk_skill:=:'.((int) $skillToDelete->fk_skill).') AND (fk_evaluation:=:'.((int) $objEval->rowid).'))');
290 if (is_array($lines)) {
291 foreach ($lines as $key => $evalline) {
292 // Verify if fetchAll gave the right object
293 if (is_object($evalline) && $evalline instanceof EvaluationLine) {
294 $ret = $evalline->delete($user);
295 if ($ret <= 0) {
296 $error++;
297 setEventMessages($evalline->error, null, 'errors');
298 break;
299 }
300 }
301 }
302 } else {
303 $error++;
304 setEventMessages($line->error, null, 'errors');
305 break;
306 }
307 $i++;
308 }
309 } else {
310 $error++;
311 setEventMessages($skillToDelete->error, null, 'errors');
312 }
313 if (!$error) {
314 $ret = $skillToDelete->delete($user);
315 if ($ret <= 0) {
316 $error++;
317 setEventMessages($skillToDelete->error, null, 'errors');
318 }
319 }
320 if (!$error) {
321 setEventMessages($langs->trans("DeleteSkill"), null);
322 $db->commit();
323 } else {
324 $db->rollback();
325 }
326 }
327}
328
329
330/*
331 * View
332 */
333
334$form = new Form($db);
335$formfile = new FormFile($db);
336$formproject = new FormProjets($db);
337
338$title = $langs->trans("RequiredSkills");
339$help_url = '';
340llxHeader('', $title, $help_url);
341
342$listLink = '';
343// Part to show record
344if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
345 $res = $object->fetch_optionals();
346
347 // view configuration
348 if ($objecttype == 'job') {
349 require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_job.lib.php';
350 $head = jobPrepareHead($object);
351 $listLink = dol_buildpath('/hrm/job_list.php', 1);
352 } elseif ($objecttype == "user") { // Always true - @phpstan-ignore equal.alwaysTrue
353 require_once DOL_DOCUMENT_ROOT . "/core/lib/usergroups.lib.php";
354 $object->getRights();
355 $head = user_prepare_head($object);
356 $listLink = dol_buildpath('/user/list.php', 1);
357 } else {
358 $head = [];
359 }
360
361 print dol_get_fiche_head($head, 'skill_tab', $langs->trans("Workstation"), -1, $object->picto);
362
363 $formconfirm = '';
364
365 // Confirmation to delete
366 // Confirmation to delete line
367 if ($action == 'ask_deleteskill') {
368 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id . '&objecttype=' . $objecttype . '&lineid=' . $lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteskill', '', 0, 1);
369 }
370 // Clone confirmation
371 /*if ($action == 'clone' && $permissiontoadd) {
372 // Create an array for form
373 $formquestion = array();
374 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
375 }*/
376
377 // Call Hook formConfirm
378 $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
379 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
380 if (empty($reshook)) {
381 $formconfirm .= $hookmanager->resPrint;
382 } elseif ($reshook > 0) {
383 $formconfirm = $hookmanager->resPrint;
384 }
385
386 // Print form confirm
387 print $formconfirm;
388
389
390 // Object card
391 // ------------------------------------------------------------
392 if ($objecttype == 'job') {
393 $linkback = '<a href="' . dol_buildpath('/hrm/job_list.php', 1) . '?restore_lastsearch_values=1' . (!empty($socid) ? '&socid=' . $socid : '') . '">' . $langs->trans("BackToList") . '</a>';
394
395 $morehtmlref = '<div class="refid">';
396 $morehtmlref .= $object->label;
397 $morehtmlref .= '</div>';
398
399 dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'rowid', $morehtmlref);
400 } elseif ($listLink !== null) {
401 $linkback = '<a href="' . $listLink . '?restore_lastsearch_values=1' . (!empty($socid) ? '&socid=' . $socid : '') . '">' . $langs->trans("BackToList") . '</a>';
402
403 $morehtmlref = '<a href="'.DOL_URL_ROOT.'/user/vcard.php?id='.$object->id.'&output=file&file='.urlencode(dol_sanitizeFileName($object->getFullName($langs).'.vcf')).'" class="refid" rel="noopener">';
404 $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard', 'class="valignmiddle marginleftonly paddingrightonly"');
405 $morehtmlref .= '</a>';
406
407 $urltovirtualcard = '/user/virtualcard.php?id='.((int) $object->id);
408 $morehtmlref .= dolButtonToOpenUrlInDialogPopup('publicvirtualcard', $langs->trans("PublicVirtualCardUrl").' - '.$object->getFullName($langs), img_picto($langs->trans("PublicVirtualCardUrl"), 'card', 'class="valignmiddle marginleftonly paddingrightonly"'), $urltovirtualcard, '', 'nohover');
409
410 dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'rowid', $morehtmlref, '&objecttype='.$objecttype);
411 }
412
413 // Get all available skills
414 $static_skill = new Skill($db);
415 $TAllSkills = $static_skill->fetchAll();
416
417 // Array format for multiselectarray function
418 $TAllSkillsFormatted = array();
419 if (!empty($TAllSkills)) {
420 foreach ($TAllSkills as $k => $v) {
421 $TAllSkillsFormatted[$k] = $v->label;
422 }
423 }
424
425 // table of skillRank linked to current object
426 //$TSkillsJob = $skill->fetchAll('ASC', 't.rowid', 0, 0);
427 $sql_skill = "SELECT sr.fk_object, sr.rowid, s.label,s.skill_type, sr.rankorder, sr.fk_skill";
428 $sql_skill .= " FROM ".MAIN_DB_PREFIX."hrm_skillrank AS sr";
429 $sql_skill .= " JOIN ".MAIN_DB_PREFIX."hrm_skill AS s ON sr.fk_skill = s.rowid";
430 $sql_skill .= " AND sr.fk_object = ".((int) $id);
431 $result = $db->query($sql_skill);
432 $numSkills = $db->num_rows($result);
433 $TSkillsJob = array();
434 for ($i = 0; $i < $numSkills; $i++) {
435 $objSkillRank = $db->fetch_object($result);
436 $TSkillsJob[] = $objSkillRank;
437 }
438
439 $TAlreadyUsedSkill = array();
440 if (is_array($TSkillsJob) && !empty($TSkillsJob)) {
441 foreach ($TSkillsJob as $skillElement) {
442 $TAlreadyUsedSkill[$skillElement->fk_skill] = $skillElement->fk_skill;
443 }
444 }
445
446 print '<div class="fichecenter">';
447 print '<div class="fichehalfleft">';
448
449 print '<div class="underbanner clearboth"></div>';
450 print '<table class="border centpercent tableforfield">'."\n";
451
452 if ($objecttype == 'job') {
453 // Common attributes
454 //$keyforbreak='fieldkeytoswitchonsecondcolumn'; // We change column just before this field
455 //unset($object->fields['fk_project']); // Hide field already shown in banner
456 //unset($object->fields['fk_soc']); // Hide field already shown in banner
457 $object->fields['label']['visible'] = 0; // Already in banner
458 include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_view.tpl.php';
459
460 // Other attributes. Fields from hook formObjectOptions and Extrafields.
461 include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php';
462 } else {
463 // Login
464 print '<tr><td class="titlefieldmiddle">'.$langs->trans("Login").'</td>';
465 if (!empty($object->ldap_sid) && $object->statut == 0) {
466 print '<td class="error">';
467 print $langs->trans("LoginAccountDisableInDolibarr");
468 print '</td>';
469 } else {
470 print '<td>';
471 $addadmin = '';
472 if (property_exists($object, 'admin')) {
473 if (isModEnabled('multicompany') && !empty($object->admin) && empty($object->entity)) {
474 $addadmin .= img_picto($langs->trans("SuperAdministratorDesc"), "superadmin", 'class="paddingleft valignmiddle"');
475 } elseif (!empty($object->admin)) {
476 $addadmin .= img_picto($langs->trans("AdministratorDesc"), "admin", 'class="paddingleft valignmiddle"');
477 }
478 }
479 print showValueWithClipboardCPButton(!empty($object->login) ? $object->login : '').$addadmin;
480 print '</td>';
481 }
482 print '</tr>'."\n";
483
484 $object->fields['label']['visible'] = 0; // Already in banner
485 $object->fields['firstname']['visible'] = 0; // Already in banner
486 $object->fields['lastname']['visible'] = 0; // Already in banner
487 //include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_view.tpl.php';
488
489 // Ref employee
490 print '<tr><td class="titlefield">'.$langs->trans("RefEmployee").'</td>';
491 print '<td class="error">';
492 print showValueWithClipboardCPButton(!empty($object->ref_employee) ? $object->ref_employee : '');
493 print '</td>';
494 print '</tr>'."\n";
495
496 // National Registration Number
497 print '<tr><td class="titlefield">'.$langs->trans("NationalRegistrationNumber").' <a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&objecttype=user&action=editnational_registration_number&token='.newToken().'">'.img_picto($langs->trans("Edit"), 'edit').'</a></td>';
498 print '<td>';
499 if ($action == 'editnational_registration_number') {
500 $ret = '<form method="post" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&objecttype=user">';
501 $ret .= '<input type="hidden" name="action" value="setnational_registration_number">';
502 $ret .= '<input type="hidden" name="token" value="'.newToken().'">';
503 $ret .= '<input type="hidden" name="id" value="'.$object->id.'">';
504 $ret .= '<input type="text" name="national_registration_number" value="'.$object->national_registration_number.'">';
505 $ret .= '<input type="submit" class="button smallpaddingimp" name="modify" value="'.$langs->trans("Modify").'"> ';
506 $ret .= '<input type="submit" class="button smallpaddingimp button-cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
507 $ret .= '</form>';
508 print $ret;
509 } else {
510 print showValueWithClipboardCPButton(!empty($object->national_registration_number) ? $object->national_registration_number : '');
511 }
512 print '</td>';
513 print '</tr>'."\n";
514 }
515
516 print '</table>';
517
518 print '</div>';
519 print '</div>';
520
521
522 print '<div class="clearboth"></div><br>';
523
524 if ($objecttype != 'user' && $permissiontoadd) {
525 // form to add new skills
526 print '<br>';
527 print '<form name="addSkill" method="post" action="' . $_SERVER['PHP_SELF'] . '">';
528 print '<input type="hidden" name="objecttype" value="' . $objecttype . '">';
529 print '<input type="hidden" name="id" value="' . $id . '">';
530 print '<input type="hidden" name="action" value="addSkill">';
531 print '<input type="hidden" name="token" value="'.newToken().'">';
532 print '<div class="div-table-responsive-no-min">';
533 print '<table id="tablelines" class="noborder noshadow" width="100%">';
534 print '<tr><td style="width:90%">' . $langs->trans('AddSkill') . '</td><td style="width:10%"></td></tr>';
535 print '<tr>';
536 print '<td>';
537 print img_picto('', 'shapes', 'class="pictofixedwidth"');
538 print $form->multiselectarray('fk_skill', array_diff_key($TAllSkillsFormatted, $TAlreadyUsedSkill), array(), 0, 0, 'widthcentpercentminusx') . '</td>';
539 print '<td><input class="button reposition" type="submit" value="' . $langs->trans('Add') . '"></td>';
540 print '</tr>';
541 print '</table>';
542 print '</div>';
543 print '</form>';
544 }
545 print '<br>';
546
547 print '<div class="clearboth"></div>';
548
549 if ($objecttype != 'user' && $permissiontoadd) {
550 print '<form name="saveSkill" method="post" action="' . $_SERVER['PHP_SELF'] . '">';
551 print '<input type="hidden" name="objecttype" value="' . $objecttype . '">';
552 print '<input type="hidden" name="id" value="' . $id . '">';
553 print '<input type="hidden" name="token" value="'.newToken().'">';
554 print '<input type="hidden" name="action" value="saveSkill">';
555 }
556 if ($objecttype != 'user') {
557 print '<div class="div-table-responsive-no-min">';
558 print '<table id="tablelines" class="noborder centpercent" width="100%">';
559 print '<tr class="liste_titre">';
560 print '<th>'.$langs->trans('SkillType').'</th>';
561 print '<th>'.$langs->trans('Label').'</th>';
562 print '<th>'.$langs->trans('Description').'</th>';
563 print '<th>'.$langs->trans($objecttype === 'job' ? 'RequiredRank' : 'EmployeeRank').'</th>'; // Always true - @phpstan-ignore identical.alwaysTrue
564 if ($objecttype === 'job') { // Always true - @phpstan-ignore identical.alwaysTrue
565 print '<th class="linecoledit"></th>';
566 print '<th class="linecoldelete"></th>';
567 }
568 print '</tr>';
569 if (!is_array($TSkillsJob) || empty($TSkillsJob)) {
570 print '<tr><td><span class="opacitymedium">' . $langs->trans("NoRecordFound") . '</span></td></tr>';
571 } else {
572 $sk = new Skill($db);
573 foreach ($TSkillsJob as $skillElement) {
574 $sk->fetch((int) $skillElement->fk_skill);
575 print '<tr>';
576 print '<td>';
577 print Skill::typeCodeToLabel($sk->skill_type);
578 print '</td><td class="linecolfk_skill">';
579 print $sk->getNomUrl(1);
580 print '</td>';
581 print '<td>';
582 print $sk->description;
583 print '</td><td class="linecolrank">';
584 print displayRankInfos($skillElement->rankorder, $skillElement->fk_skill, 'TNote', $objecttype == 'job' && $permissiontoadd ? 'edit' : 'view'); // Always true - @phpstan-ignore equal.alwaysTrue
585 print '</td>';
586 if ($objecttype != 'user' && $permissiontoadd) { // Always true - @phpstan-ignore notEqual.alwaysTrue
587 print '<td class="linecoledit"></td>';
588 print '<td class="linecoldelete">';
589 print '<a class="reposition" href="' . $_SERVER["PHP_SELF"] . '?id=' . $skillElement->fk_object . '&amp;objecttype=' . $objecttype . '&amp;action=ask_deleteskill&amp;lineid=' . $skillElement->rowid . '&amp;token='.newToken().'">';
590 print img_delete();
591 print '</a>';
592 }
593 print '</td>';
594 print '</tr>';
595 }
596 }
597
598 print '</table>';
599 if ($objecttype != 'user' && $permissiontoadd) { // Left always true - @phpstan-ignore notEqual.alwaysTrue
600 print '<td><input class="button pull-right" type="submit" value="' . $langs->trans('SaveRank') . '"></td>';
601 }
602 print '</div>';
603 if ($objecttype != 'user' && $permissiontoadd) { // Left always true - @phpstan-ignore notEqual.alwaysTrue
604 print '</form>';
605 }
606 }
607
608
609 // liste des evaluation liées
610 if ($objecttype == 'user' && $permissiontoadd) {
611 $evaltmp = new Evaluation($db);
612 $job = new Job($db);
613 $sql = "select e.rowid,e.ref,e.fk_user,e.fk_job,e.date_eval,ed.rankorder,ed.required_rank,ed.fk_skill,s.label";
614 $sql .= " FROM ".MAIN_DB_PREFIX."hrm_evaluation as e";
615 $sql .= ", ".MAIN_DB_PREFIX."hrm_evaluationdet as ed";
616 $sql .= ", ".MAIN_DB_PREFIX."hrm_skill as s";
617 $sql .= " WHERE e.rowid = ed.fk_evaluation";
618 $sql .= " AND s.rowid = ed.fk_skill";
619 $sql .= " AND e.fk_user = ".((int) $id);
620
621 $resql = $db->query($sql);
622 $num = $db->num_rows($resql);
623
624 //num of evaluations for each user
625 $sqlEval = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."hrm_evaluation as e";
626 $sqlEval .= " WHERE e.fk_user = ".((int) $id);
627 $rslt = $db->query($sqlEval);
628 $tmpobj = $db->fetch_object($rslt);
629 $numEval = 0;
630 if ($tmpobj) {
631 $numEval = $tmpobj->nb;
632 }
633
634 $page = 0;
635 print_barre_liste($langs->trans("Evaluations"), $page, $_SERVER["PHP_SELF"], '', '', '', '', $numEval, $numEval, $evaltmp->picto, 0);
636
637 print '<div class="div-table-responsive-no-min">';
638 print '<table id="tablelines" class="noborder centpercent">';
639 print '<tr class="liste_titre">';
640 print '<th>'.$langs->trans('Label').'</th>';
641 print '<th>'.$langs->trans('Description').'</th>';
642 print '<th>'.$langs->trans('DateEval').'</th>';
643 print '<th>'.$langs->trans('Status').'</th>';
644 print '<th>'.$langs->trans("Result").' ' .$form->textwithpicto('', GetLegendSkills(), 1) .'</th>';
645 print '</tr>';
646 if (!$resql) {
647 print '<tr><td><span class="opacitymedium">' . $langs->trans("NoRecordFound") . '</span></td></tr>';
648 } else {
649 $i = 0;
650 $sameRef = array();
652 $objects = array();
653 while ($i < $num) {
654 $obj = $db->fetch_object($resql);
655 $obj->result = getRankOrderResults($obj);
656 $objects[$i] = $obj;
657 $i++;
658 }
659
660 //grouped skills by evaluation
661 $resultArray = getGroupedEval($objects);
662 foreach ($resultArray as $object) {
663 if (is_array($object)) {
664 $evaltmp->fetch($object[0]->rowid);
665 $evaltmp->id = $object[0]->rowid;
666 $evaltmp->ref = $object[0]->ref;
667 $job->fetch($object[0]->fk_job);
668 } else {
669 $evaltmp->ref = $object->ref;
670 $evaltmp->fetch($object->rowid);
671 $evaltmp->id = $object->rowid;
672 $job->fetch($object->fk_job);
673 }
674
675 print '<tr>';
676 print '<td class="nowraponall">';
677 print $evaltmp->getNomUrl(1);
678 print '</td><td class="linecolfk_skill">';
679 print $job->getNomUrl(1);
680 print '</td>';
681 print '<td>';
682 print dol_print_date((!is_array($object) ? $object->date_eval : $object[0]->date_eval), 'day', 'tzserver');
683 print '</td><td>';
684 print $evaltmp->getLibStatut(2);
685 print '</td>';
686 print '<td class="linecolrank tdoverflowmax300">';
687 if ($job->status == $job::STATUS_VALIDATED) {
688 if (!is_array($object)) {
689 print $object->result;
690 } else {
691 foreach ($object as $skill) {
692 print $skill->result;
693 }
694 }
695 }
696 print '</td>';
697 print '</tr>';
698 }
699 }
700 print '</table>';
701 }
702
703 print dol_get_fiche_end();
704}
705
706llxFooter();
707$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 for EvaluationLine.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class to manage building of HTML components.
Class for Job.
Definition job.class.php:38
Class for Skill.
static typeCodeToLabel($code)
Class for SkillRank.
Class to manage Dolibarr users.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $selectlimitsuffix=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
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.
dolButtonToOpenUrlInDialogPopup($name, $label, $buttonstring, $url, $disabled='', $morecss='classlink button bordertransp', $jsonopen='', $jsonclose='', $accesskey='')
Return HTML code to output a button to open a dialog popup box.
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.
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_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
isModEnabled($module)
Is Dolibarr module enabled.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
GetLegendSkills()
getRankOrderResults($obj)
getGroupedEval($objects)
Grouped rows with same ref in array.
jobPrepareHead($object)
Prepare array of tabs for Job.
displayRankInfos($selected_rank, $fk_skill, $inputname='TNote', $mode='view')
Used to print ranks of a skill into several case, view or edit pour js necessary to select a rank.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.
user_prepare_head(User $object)
Prepare array with list of tabs.