skill_tab.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  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. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. */
  21. /**
  22. * \file skill_tab.php
  23. * \ingroup hrm
  24. * \brief Page to add/delete/view skill to jobs/users
  25. */
  26. // Load Dolibarr environment
  27. require '../main.inc.php';
  28. require_once DOL_DOCUMENT_ROOT . '/core/class/html.formcompany.class.php';
  29. require_once DOL_DOCUMENT_ROOT . '/core/class/html.formfile.class.php';
  30. require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php';
  31. require_once DOL_DOCUMENT_ROOT . '/user/class/user.class.php';
  32. require_once DOL_DOCUMENT_ROOT . '/hrm/class/skill.class.php';
  33. require_once DOL_DOCUMENT_ROOT . '/hrm/class/skillrank.class.php';
  34. require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_skill.lib.php';
  35. // Load translation files required by the page
  36. $langs->loadLangs(array("hrm", "other"));
  37. $id = GETPOST('id', 'int');
  38. $TSkillsToAdd = GETPOST('fk_skill', 'array');
  39. $objecttype = GETPOST('objecttype', 'alpha');
  40. $TNote = GETPOST('TNote', 'array');
  41. $lineid = GETPOST('lineid', 'int');
  42. $action = GETPOST('action', 'aZ09');
  43. $confirm = GETPOST('confirm', 'alpha');
  44. $cancel = GETPOST('cancel', 'aZ09');
  45. $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'skillcard'; // To manage different context of search
  46. $backtopage = GETPOST('backtopage', 'alpha');
  47. $backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
  48. $TAuthorizedObjects = array('job', 'user');
  49. $skill = new SkillRank($db);
  50. // Initialize technical objects
  51. if (in_array($objecttype, $TAuthorizedObjects)) {
  52. if ($objecttype == 'job') {
  53. require_once DOL_DOCUMENT_ROOT . '/hrm/class/job.class.php';
  54. $object = new Job($db);
  55. } elseif ($objecttype == "user") {
  56. $object = new User($db);
  57. }
  58. } else {
  59. accessforbidden('ErrorBadObjectType');
  60. }
  61. $hookmanager->initHooks(array('skilltab', 'globalcard')); // Note that conf->hooks_modules contains array
  62. // Load object
  63. include DOL_DOCUMENT_ROOT . '/core/actions_fetchobject.inc.php'; // Must be include, not include_once.
  64. $permissiontoread = $user->rights->hrm->all->read;
  65. $permissiontoadd = $user->rights->hrm->all->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
  66. // Security check (enable the most restrictive one)
  67. if ($user->socid > 0) accessforbidden();
  68. if (empty($conf->hrm->enabled)) accessforbidden();
  69. if (!$permissiontoread) accessforbidden();
  70. /*
  71. * Actions
  72. */
  73. $parameters = array();
  74. $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
  75. if ($reshook < 0) {
  76. setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
  77. }
  78. if (empty($reshook)) {
  79. $error = 0;
  80. $backurlforlist = DOL_URL_ROOT.'/hrm/skill_list.php';
  81. if (empty($backtopage) || ($cancel && empty($id))) {
  82. if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
  83. if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
  84. $backtopage = $backurlforlist;
  85. } else {
  86. $backtopage = DOL_URL_ROOT.'/hrm/skill_list.php?id=' . ($id > 0 ? $id : '__ID__');
  87. }
  88. }
  89. }
  90. if ($action == 'addSkill') {
  91. $error = 0;
  92. if (empty($TSkillsToAdd)) {
  93. setEventMessage('ErrNoSkillSelected', 'errors');
  94. $error++;
  95. }
  96. if (!$error) {
  97. foreach ($TSkillsToAdd as $k=>$v) {
  98. $skillAdded = new SkillRank($db);
  99. $skillAdded->fk_skill = $v;
  100. $skillAdded->fk_object = $id;
  101. $skillAdded->objecttype = $objecttype;
  102. $ret = $skillAdded->create($user);
  103. if ($ret < 0) setEventMessages($skillAdded->error, null, 'errors');
  104. //else unset($TSkillsToAdd);
  105. }
  106. if ($ret > 0) setEventMessages($langs->trans("SaveAddSkill"), null);
  107. }
  108. } elseif ($action == 'saveSkill') {
  109. if (!empty($TNote)) {
  110. foreach ($TNote as $skillId => $rank) {
  111. $TSkills = $skill->fetchAll('ASC', 't.rowid', 0, 0, array('customsql' => 'fk_object=' . ((int) $id) . " AND objecttype='" . $db->escape($objecttype) . "' AND fk_skill = " . ((int) $skillId)));
  112. if (is_array($TSkills) && !empty($TSkills)) {
  113. foreach ($TSkills as $tmpObj) {
  114. $tmpObj->rankorder = $rank;
  115. $tmpObj->update($user);
  116. }
  117. }
  118. }
  119. setEventMessages($langs->trans("SaveLevelSkill"), null);
  120. header("Location: " . DOL_URL_ROOT.'/hrm/skill_tab.php?id=' . $id. '&objecttype=job');
  121. exit;
  122. }
  123. } elseif ($action == 'confirm_deleteskill' && $confirm == 'yes') {
  124. $skillToDelete = new SkillRank($db);
  125. $ret = $skillToDelete->fetch($lineid);
  126. setEventMessages($langs->trans("DeleteSkill"), null);
  127. if ($ret > 0) {
  128. $skillToDelete->delete($user);
  129. }
  130. }
  131. }
  132. /*
  133. * View
  134. */
  135. $form = new Form($db);
  136. $formfile = new FormFile($db);
  137. $formproject = new FormProjets($db);
  138. $title = $langs->trans("RequiredSkills");
  139. $help_url = '';
  140. llxHeader('', $title, $help_url);
  141. // Part to show record
  142. if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
  143. $res = $object->fetch_optionals();
  144. // view configuration
  145. if ($objecttype == 'job') {
  146. require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_job.lib.php';
  147. $head = jobPrepareHead($object);
  148. $listLink = dol_buildpath('/hrm/job_list.php', 1);
  149. } elseif ($objecttype == "user") {
  150. require_once DOL_DOCUMENT_ROOT . "/core/lib/usergroups.lib.php";
  151. $object->getRights();
  152. $head = user_prepare_head($object);
  153. $listLink = dol_buildpath('/user/list.php', 1);
  154. }
  155. print dol_get_fiche_head($head, 'skill_tab', $langs->trans("Workstation"), -1, $object->picto);
  156. $formconfirm = '';
  157. // Confirmation to delete
  158. /*if ($action == 'delete') {
  159. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteSkill'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1);
  160. }*/
  161. // Confirmation to delete line
  162. if ($action == 'ask_deleteskill') {
  163. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id . '&objecttype=' . $objecttype . '&lineid=' . $lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteskill', '', 0, 1);
  164. }
  165. // Clone confirmation
  166. /*if ($action == 'clone') {
  167. // Create an array for form
  168. $formquestion = array();
  169. $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
  170. }*/
  171. // Call Hook formConfirm
  172. $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
  173. $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
  174. if (empty($reshook)) {
  175. $formconfirm .= $hookmanager->resPrint;
  176. } elseif ($reshook > 0) {
  177. $formconfirm = $hookmanager->resPrint;
  178. }
  179. // Print form confirm
  180. print $formconfirm;
  181. // Object card
  182. // ------------------------------------------------------------
  183. $linkback = '<a href="' . $listLink . '?restore_lastsearch_values=1' . (!empty($socid) ? '&socid=' . $socid : '') . '">' . $langs->trans("BackToList") . '</a>';
  184. $morehtmlref = '<a href="'.DOL_URL_ROOT.'/user/vcard.php?id='.$object->id.'" class="refid">';
  185. $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"');
  186. $morehtmlref .= '</a>';
  187. dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'rowid', $morehtmlref, '&objecttype='.$objecttype);
  188. // Get all available skills
  189. $static_skill = new Skill($db);
  190. $TAllSkills = $static_skill->fetchAll();
  191. // Array format for multiselectarray function
  192. $TAllSkillsFormatted=array();
  193. if (!empty($TAllSkills)) {
  194. foreach ($TAllSkills as $k=>$v) {
  195. $TAllSkillsFormatted[$k] = $v->label;
  196. }
  197. }
  198. // table of skillRank linked to current object
  199. $TSkillsJob = $skill->fetchAll('ASC', 't.rowid', 0, 0, array('customsql' => 'fk_object=' . ((int) $id) . " AND objecttype='" . $db->escape($objecttype) . "'"));
  200. $TAlreadyUsedSkill = array();
  201. if (is_array($TSkillsJob) && !empty($TSkillsJob)) {
  202. foreach ($TSkillsJob as $skillElement) {
  203. $TAlreadyUsedSkill[$skillElement->fk_skill] = $skillElement->fk_skill;
  204. }
  205. }
  206. print '<div class="fichecenter">';
  207. print '<div class="fichehalfleft">';
  208. print '<div class="underbanner clearboth"></div>';
  209. print '<table class="border centpercent tableforfield">';
  210. // Login
  211. print '<tr><td class="titlefield">'.$langs->trans("Login").'</td>';
  212. if (!empty($object->ldap_sid) && $object->statut == 0) {
  213. print '<td class="error">';
  214. print $langs->trans("LoginAccountDisableInDolibarr");
  215. print '</td>';
  216. } else {
  217. print '<td>';
  218. $addadmin = '';
  219. if (property_exists($object, 'admin')) {
  220. if (isModEnabled('multicompany') && !empty($object->admin) && empty($object->entity)) {
  221. $addadmin .= img_picto($langs->trans("SuperAdministratorDesc"), "redstar", 'class="paddingleft"');
  222. } elseif (!empty($object->admin)) {
  223. $addadmin .= img_picto($langs->trans("AdministratorDesc"), "star", 'class="paddingleft"');
  224. }
  225. }
  226. print showValueWithClipboardCPButton($object->login).$addadmin;
  227. print '</td>';
  228. }
  229. print '</tr>'."\n";
  230. $object->fields['label']['visible']=0; // Already in banner
  231. $object->fields['firstname']['visible']=0; // Already in banner
  232. $object->fields['lastname']['visible']=0; // Already in banner
  233. //include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_view.tpl.php';
  234. // Ref employee
  235. print '<tr><td class="titlefield">'.$langs->trans("RefEmployee").'</td>';
  236. print '<td class="error">';
  237. print showValueWithClipboardCPButton($object->ref_employee);
  238. print '</td>';
  239. print '</tr>'."\n";
  240. // National Registration Number
  241. print '<tr><td class="titlefield">'.$langs->trans("NationalRegistrationNumber").'</td>';
  242. print '<td class="error">';
  243. print showValueWithClipboardCPButton($object->national_registration_number);
  244. print '</td>';
  245. print '</tr>'."\n";
  246. /*print '<tr><td class="titlefield">'.$langs->trans("NbOfActiveNotifications").'</td>'; // Notification for this thirdparty
  247. print '<td colspan="3">';
  248. $nbofrecipientemails=0;
  249. $notify=new Notify($db);
  250. $tmparray = $notify->getNotificationsArray('', 0, null, $object->id, array('user'));
  251. foreach($tmparray as $tmpkey => $tmpval)
  252. {
  253. $nbofrecipientemails++;
  254. }
  255. print $nbofrecipientemails;
  256. print '</td></tr>';*/
  257. print '</table>';
  258. print '</div>';
  259. print '</div>';
  260. print '<div class="clearboth"></div><br>';
  261. if ($objecttype != 'user' && $permissiontoadd) {
  262. // form pour ajouter des compétences
  263. print '<form name="addSkill" method="post" action="' . $_SERVER['PHP_SELF'] . '">';
  264. print '<input type="hidden" name="objecttype" value="' . $objecttype . '">';
  265. print '<input type="hidden" name="id" value="' . $id . '">';
  266. print '<input type="hidden" name="action" value="addSkill">';
  267. print '<input type="hidden" name="token" value="'.newToken().'">';
  268. print '<div class="div-table-responsive-no-min">';
  269. print '<table id="tablelines" class="noborder noshadow" width="100%">';
  270. print '<tr><td style="width:90%">' . $langs->trans('AddSkill') . '</td><td style="width:10%"></td></tr>';
  271. print '<tr>';
  272. print '<td>' . $form->multiselectarray('fk_skill', array_diff_key($TAllSkillsFormatted, $TAlreadyUsedSkill), array(), 0, 0, '', 0, '100%') . '</td>';
  273. print '<td><input class="button reposition" type="submit" value="' . $langs->trans('Add') . '"></td>';
  274. print '</tr>';
  275. print '</table>';
  276. print '</div>';
  277. print '</form>';
  278. }
  279. print '<br>';
  280. print '<div class="clearboth"></div>';
  281. if ($objecttype != 'user' && $permissiontoadd) {
  282. print '<form name="saveSkill" method="post" action="' . $_SERVER['PHP_SELF'] . '">';
  283. print '<input type="hidden" name="objecttype" value="' . $objecttype . '">';
  284. print '<input type="hidden" name="id" value="' . $id . '">';
  285. print '<input type="hidden" name="token" value="'.newToken().'">';
  286. print '<input type="hidden" name="action" value="saveSkill">';
  287. }
  288. print '<div class="div-table-responsive-no-min">';
  289. print '<table id="tablelines" class="noborder centpercent" width="100%">';
  290. print '<tr class="liste_titre">';
  291. print '<th>'.$langs->trans('SkillType').'</th>';
  292. print '<th>'.$langs->trans('Label').'</th>';
  293. print '<th>'.$langs->trans('Description').'</th>';
  294. print '<th>'.$langs->trans($objecttype === 'job' ? 'RequiredRank' : 'EmployeeRank').'</th>';
  295. if ($objecttype === 'job') {
  296. print '<th class="linecoledit"></th>';
  297. print '<th class="linecoldelete"></th>';
  298. }
  299. print '</tr>';
  300. if (!is_array($TSkillsJob) || empty($TSkillsJob)) {
  301. print '<tr><td><span class="opacitymedium">' . $langs->trans("NoRecordFound") . '</span></td></tr>';
  302. } else {
  303. $sk = new Skill($db);
  304. foreach ($TSkillsJob as $skillElement) {
  305. $sk->fetch($skillElement->fk_skill);
  306. print '<tr>';
  307. print '<td>';
  308. print Skill::typeCodeToLabel($sk->skill_type);
  309. print '</td><td class="linecolfk_skill">';
  310. print $sk->getNomUrl(1);
  311. print '</td>';
  312. print '<td>';
  313. print $sk->description;
  314. print '</td><td class="linecolrank">';
  315. print displayRankInfos($skillElement->rankorder, $skillElement->fk_skill, 'TNote', $objecttype == 'job' && $permissiontoadd ? 'edit' : 'view');
  316. print '</td>';
  317. if ($objecttype != 'user' && $permissiontoadd) {
  318. print '<td class="linecoledit"></td>';
  319. print '<td class="linecoldelete">';
  320. print '<a class="reposition" href="' . $_SERVER["PHP_SELF"] . '?id=' . $skillElement->fk_object . '&amp;objecttype=' . $objecttype . '&amp;action=ask_deleteskill&amp;lineid=' . $skillElement->id . '">';
  321. print img_delete();
  322. print '</a>';
  323. }
  324. print '</td>';
  325. print '</tr>';
  326. }
  327. }
  328. print '</table>';
  329. if ($objecttype != 'user' && $permissiontoadd) print '<td><input class="button pull-right" type="submit" value="' . $langs->trans('SaveRank') . '"></td>';
  330. print '</div>';
  331. if ($objecttype != 'user' && $permissiontoadd) print '</form>';
  332. // liste des compétences liées
  333. print dol_get_fiche_end();
  334. llxFooter();
  335. }