38require_once
'../main.inc.php';
39require_once DOL_DOCUMENT_ROOT .
'/core/lib/functions.lib.php';
40require_once DOL_DOCUMENT_ROOT .
'/core/lib/functions2.lib.php';
41require_once DOL_DOCUMENT_ROOT .
'/hrm/class/skill.class.php';
42require_once DOL_DOCUMENT_ROOT .
'/hrm/class/job.class.php';
43require_once DOL_DOCUMENT_ROOT .
'/hrm/class/evaluation.class.php';
44require_once DOL_DOCUMENT_ROOT .
'/hrm/class/position.class.php';
45require_once DOL_DOCUMENT_ROOT .
'/hrm/lib/hrm.lib.php';
63$permissiontoread = $user->hasRight(
'hrm',
'evaluation',
'read') || $user->hasRight(
'hrm',
'compare_advance',
'read');
66if (empty(
$conf->hrm->enabled)) {
69if (!$permissiontoread || ($action ===
'create' && !$permissiontoadd)) {
78$css = array(
'/hrm/css/style.css');
80llxHeader(
'', $langs->trans(
'SkillComparison'),
'',
'', 0, 0,
'', $css);
85$head[$h][0] = $_SERVER[
"PHP_SELF"];
86$head[$h][1] = $langs->trans(
"SkillComparison");
87$head[$h][2] =
'compare';
92 <script
type=
"text/javascript">
94 $(document).ready(
function () {
96 $(
"li[fk_user]").click(
function () {
98 if ($(
this).hasClass(
'disabled')) {
99 $(
this).removeClass(
'disabled');
101 $(
this).addClass(
'disabled');
105 var $userl = $(
this).closest(
'ul');
106 var listname = $userl.attr(
'name');
110 $userl.find(
'li').each(
function (i, item) {
112 if ($(item).hasClass(
'disabled')) {
113 TId.push($(item).attr(
'fk_user'));
118 $(
'#' + listname +
'_excluded_id').val(TId.join(
','));
131$fk_job = (int)
GETPOST(
'fk_job');
141 <div
class=
"fichecenter">
142 <form action=
"<?php echo $_SERVER['PHP_SELF'] ?>">
144 <div
class=
"tabBar tabBarWithBottom">
145 <div
class=
"fichehalfleft">
146 <
table class=
"border tableforfield" width=
"100%">
149 print $langs->trans(
'group1ToCompare').
'</td><td>';
150 print
img_picto(
'',
'group',
'class="pictofixedwidth"');
151 print $form->select_dolgroups($fk_usergroup1,
'fk_usergroup1', 1);
154 <tr><td> </td></tr>
157 print $langs->trans(
'group2ToCompare').
'</td><td>';
158 print
img_picto(
'',
'group',
'class="pictofixedwidth"');
159 print $form->select_dolgroups($fk_usergroup2,
'fk_usergroup2', 1);
163 <td><STRONG><?php print $langs->trans(
'or'); ?></STRONG></td>
167 echo $langs->trans(
'OrJobToCompare') .
'</td><td>';
169 $jobs = $j->fetchAll();
172 foreach ($jobs as &$j) {
173 $TJobs[$j->id] = $j->label;
176 print
img_picto(
'',
'jobprofile',
'class="pictofixedwidth"').$form->selectarray(
'fk_job', $TJobs, $fk_job, 1);
182 <div style=
"background:#eee;border-radius:5px 0;margin:0px 0 10px;font-style:italic;padding:5px;" class=
"fichehalfright">
183 <!--<h4><?php echo $langs->trans(
'legend'); ?></h4>-->
184 <
table class=
"border" width=
"100%">
186 <td><span style=
"vertical-align:middle" class=
"toohappy diffnote little"></span>
187 <?php echo $langs->trans(
'CompetenceAcquiredByOneOrMore'); ?></td>
190 <td><span style=
"vertical-align:middle" class=
"veryhappy diffnote little"></span>
191 <?php echo $langs->trans(
'MaxlevelGreaterThan'); ?></td>
194 <td><span style=
"vertical-align:middle" class=
"happy diffnote little"></span>
195 <?php echo $langs->trans(
'MaxLevelEqualTo'); ?></td>
198 <td><span style=
"vertical-align:middle" class=
"sad diffnote little"></span>
199 <?php echo $langs->trans(
'MaxLevelLowerThan'); ?></td>
202 <td><span style=
"vertical-align:middle" class=
"toosad diffnote little"></span>
203 <?php echo $langs->trans(
'SkillNotAcquired'); ?></td>
209 <div
class=
"clearboth"></div>
215 <input
class=
"button" type=
"SUBMIT" name=
"bt1" VALUE=
"<?php print $langs->trans('Refresh'); ?>">
219 <div
id=
"compare" class=
"centpercent" style=
"position:relative;">
221 <?php
if ($fk_usergroup1 > 0 || $fk_usergroup2 > 0 || $fk_job > 0) {
222 $TUser1 = $TUser2 = array();
224 $userlist1 = displayUsersListWithPicto($TUser1, $fk_usergroup1,
'list1');
226 $TSkill1 = getSkillForUsers($TUser1);
229 $TSkill2 = getSkillForJob($fk_job);
232 $job->fetch($fk_job);
235 <h3>' . $job->label .
'</h3>
236 <p>' . $job->description .
'</p>
240 $userlist2 = displayUsersListWithPicto($TUser2, $fk_usergroup2,
'list2');
241 $TSkill2 = getSkillForUsers($TUser2);
244 $TMergedSkills = mergeSkills($TSkill1, $TSkill2);
246 <
table class=
"centpercent">
248 <th
class=
"left"><?php print $langs->trans(
'Employees'); ?></th>
249 <th
class=
"left" style=
"padding-left: 10px;"><?php print $langs->trans(
'Skill'); ?></th>
250 <th><?php print $langs->trans(
'HighestRank'); ?></th>
251 <th><?php print $langs->trans(
'difference'); ?></th>
252 <th><?php print $langs->trans($fk_job > 0 ?
'ExpectedRank' :
'HighestRank'); ?></th>
259 echo
'<td id="list-user-left" style="width:25%; padding-right: 10px; border-right: 1px solid #ccc" class="valigntop">';
263 echo
'<td id="" style="width:20%; padding-left: 10px;" valign="top">' . skillList($TMergedSkills) .
'</td>';
265 echo
'<td id="" style="width:10%" valign="top">' . rate($TMergedSkills,
'rate1') .
'</td>';
267 echo
'<td id="" style="width:10%" valign="top">' . diff($TMergedSkills) .
'</td>';
269 echo
'<td id="" style="width:10%; padding-right: 10px;" valign="top">' . rate($TMergedSkills,
'rate2') .
'</td>';
271 echo
'<td id="list-user-right" style="width:25%; padding-left: 10px; border-left: 1px solid #ccc;" class="valigntop">';
304function diff(&$TMergedSkills)
306 $out =
'<ul class="diff">';
308 foreach ($TMergedSkills as
$id => &$sk) {
311 if (empty($sk->rate2)) {
312 $class .=
' toohappy';
313 } elseif (empty($sk->rate1)) {
315 } elseif ($sk->rate1 == $sk->rate2) {
317 } elseif ($sk->rate2 < $sk->rate1) {
318 $class .=
' veryhappy';
319 } elseif ($sk->rate2 > $sk->rate1) {
323 $out .=
'<li fk_skill="' .
$id .
'" class="' . $class .
'" style="text-align:center;">
324 <span class="' . $class .
'"> </span>
340function rate(&$TMergedSkills, $field)
342 global $langs, $fk_job;
344 $out =
'<ul class="competence">';
346 foreach ($TMergedSkills as
$id => &$sk) {
349 if (empty($sk->$field)) {
353 $note = $sk->$field < 0 ? $langs->trans(
"NA") : $sk->$field;
354 $how_many = ($field ===
'rate1') ? $sk->how_many_max1 : $sk->how_many_max2;
357 if ($field ===
'rate2' && $fk_job > 0) {
358 $trad = $langs->trans(
'RequiredRank');
360 $trad = $langs->trans(
'HighestRank');
363 $out .=
'<li fk_skill="' .
$id .
'" class="center">
364 <p class="nowraponall"><span class="' . $class .
' classfortooltip" title="' . $trad .
'">' . $note .
'</span>' . ($how_many > 0 ?
'<span class="bubble classfortooltip" title="' . $langs->trans(
'HowManyUserWithThisMaxNote') .
'">' . $how_many .
'</span>' :
'') .
'</p>
379function skillList(&$TMergedSkills)
381 $out =
'<ul class="competence">';
383 foreach ($TMergedSkills as
$id => &$sk) {
384 $out .=
'<li fk_skill="' .
$id .
'">
385 <h3>' . $sk->label .
'</h3>
386 <p>' . $sk->description .
'</p>
402function mergeSkills($TSkill1, $TSkill2)
406 foreach ($TSkill1 as &$sk) {
407 if (empty($Tab[$sk->fk_skill])) {
408 $Tab[$sk->fk_skill] =
new stdClass();
411 $Tab[$sk->fk_skill]->rate1 = $sk->rankorder;
412 $Tab[$sk->fk_skill]->how_many_max1 = $sk->how_many_max;
414 $Tab[$sk->fk_skill]->label = $sk->label;
415 $Tab[$sk->fk_skill]->description = $sk->description;
418 foreach ($TSkill2 as &$sk) {
419 if (empty($Tab[$sk->fk_skill])) {
420 $Tab[$sk->fk_skill] =
new stdClass();
422 $Tab[$sk->fk_skill]->rate2 = $sk->rankorder;
423 $Tab[$sk->fk_skill]->how_many_max2 = $sk->how_many_max;
425 $Tab[$sk->fk_skill]->label = $sk->label;
426 $Tab[$sk->fk_skill]->description = $sk->description;
440function displayUsersListWithPicto(&$TUser, $fk_usergroup = 0, $namelist =
'list-user')
442 global $db, $langs,
$conf, $form;
445 if ($fk_usergroup > 0) {
446 $list = $namelist .
'_excluded_id';
448 $excludedIdsList =
GETPOST($list);
450 $sql =
"SELECT u.rowid FROM " . MAIN_DB_PREFIX .
"user u
451 LEFT JOIN " . MAIN_DB_PREFIX .
"usergroup_user as ugu ON (u.rowid = ugu.fk_user)
452 WHERE u.statut > 0 AND ugu.entity = ".((int)
$conf->entity);
453 $sql .=
" AND ugu.fk_usergroup=" . ((int) $fk_usergroup);
455 $res = $db->query($sql);
456 $out .=
'<ul name="' . $namelist .
'">';
458 $TExcludedId = explode(
',', $excludedIdsList);
460 $out .=
'<input id="'.$list.
'" type="hidden" name="'.$list.
'" value="'.$excludedIdsList.
'"> ';
464 while ($obj = $db->fetch_object($res)) {
467 $user =
new User($db);
468 $user->fetch($obj->rowid);
470 $name = $user->getFullName($langs);
472 $name = $user->login;
475 if (in_array($user->id, $TExcludedId)) {
476 $class .=
' disabled';
478 if (!in_array($user->id, $TUser)) {
479 $TUser[] = $user->id;
485 $jobstring = $job->getLastJobForUser($user->id);
489 $evaluation = $static_eval->getLastEvaluationForUser($user->id);
491 if (!empty($evaluation) && !empty($evaluation->date_eval)) {
492 $desc .= $langs->trans(
'DateLastEval') .
' : ' .
dol_print_date($evaluation->date_eval);
494 $desc .= $langs->trans(
'NoEval');
497 if (!empty($user->array_options[
'options_DDA'])) {
498 $desc .=
'<br>' . $langs->trans(
'Seniority') .
' : ' .
dol_print_date(strtotime($user->array_options[
'options_DDA']));
501 $out .=
'<li fk_user="' . $user->id .
'" class="' . $class .
'">
502 ' . $form->showphoto(
'userphoto', $user, 0, 0, 0,
'photoref',
'small', 1, 0,
'', 1) .
'
503 <h3>' . $name .
'</h3>
521function getSkillForUsers($TUser)
530 $sql =
'SELECT sk.rowid, sk.label, sk.description, sk.skill_type,';
531 $sql .=
' MAX(sr.rankorder) as rankorder';
532 $sql .=
' FROM '.MAIN_DB_PREFIX.
'hrm_skill sk';
533 $sql .=
' INNER JOIN '.MAIN_DB_PREFIX.
'hrm_skillrank sr';
534 $sql .=
" WHERE sk.rowid = sr.fk_skill AND sr.objecttype = '".$db->escape(SkillRank::SKILLRANK_TYPE_USER).
"'";
535 $sql .=
' AND sr.fk_object IN ('.$db->sanitize(implode(
',', $TUser)).
')';
536 $sql .=
' AND rankorder >= 0';
537 $sql .=
" GROUP BY sk.rowid, sk.label, sk.description, sk.skill_type";
538 $sql .=
" ORDER BY sk.rowid ASC";
540 $resql = $db->query($sql);
546 while ($obj = $db->fetch_object($resql)) {
549 $Tab[$num]->fk_skill = $obj->rowid;
550 $Tab[$num]->label = $obj->label;
551 $Tab[$num]->description = $obj->description;
552 $Tab[$num]->skill_type = $obj->skill_type;
554 $Tab[$num]->objectType = SkillRank::SKILLRANK_TYPE_USER;
556 $Tab[$num]->rankorder = $obj->rankorder;
559 $sql1 =
"SELECT COUNT(rowid) as how_many_max FROM ".MAIN_DB_PREFIX.
"hrm_skillrank as sr";
560 $sql1 .=
" WHERE sr.rankorder = ".((int) $obj->rankorder);
561 $sql1 .=
" AND sr.objecttype = '".$db->escape(SkillRank::SKILLRANK_TYPE_USER).
"'";
562 $sql1 .=
" AND sr.fk_skill = ".((int) $obj->rowid);
563 $sql1 .=
" AND sr.fk_object IN (".$db->sanitize(implode(
',', $TUser)).
")";
564 $resql1 = $db->query($sql1);
566 $objMax = $db->fetch_object($resql1);
568 $Tab[$num]->how_many_max = $objMax->how_many_max;
587function getSkillForJob($fk_job)
591 if (empty($fk_job)) {
595 $sql =
'SELECT sk.rowid, sk.label, sk.description, sk.skill_type, sr.fk_object, sr.objecttype, sr.fk_skill,';
596 $sql .=
" MAX(sr.rankorder) as rankorder";
597 $sql .=
' FROM '.MAIN_DB_PREFIX.
'hrm_skill as sk';
598 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'hrm_skillrank as sr ON (sk.rowid = sr.fk_skill)';
599 $sql .=
" WHERE sr.objecttype = '".SkillRank::SKILLRANK_TYPE_JOB.
"'";
600 $sql .=
' AND sr.fk_object = '.((int) $fk_job);
601 $sql .=
' GROUP BY sk.rowid, sk.label, sk.description, sk.skill_type, sr.fk_object, sr.objecttype, sr.fk_skill';
603 $resql = $db->query($sql);
608 while ($obj = $db->fetch_object($resql)) {
610 $Tab[$num]->fk_skill = $obj->fk_skill;
611 $Tab[$num]->label = $obj->label;
612 $Tab[$num]->description = $obj->description;
613 $Tab[$num]->skill_type = $obj->skill_type;
616 $Tab[$num]->fk_object = $obj->fk_object;
617 $Tab[$num]->objectType = SkillRank::SKILLRANK_TYPE_JOB;
618 $Tab[$num]->rankorder = $obj->rankorder;
619 $Tab[$num]->how_many_max = $obj->how_many_max;
$id
Support class for third parties, contacts, members, users or resources.
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
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.
Class to manage Dolibarr users.
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)
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.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
treeview li table
No Email.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
$conf db name
Only used if Module[ID]Name translation string is not found.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.