skill_tab.php 14 KB

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