dolibarr  18.0.6
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  *
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 
29 // Load Dolibarr environment
30 require '../main.inc.php';
31 
32 require_once DOL_DOCUMENT_ROOT . '/core/class/html.formcompany.class.php';
33 require_once DOL_DOCUMENT_ROOT . '/core/class/html.formfile.class.php';
34 require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php';
35 require_once DOL_DOCUMENT_ROOT . '/user/class/user.class.php';
36 require_once DOL_DOCUMENT_ROOT . '/hrm/class/job.class.php';
37 require_once DOL_DOCUMENT_ROOT . '/hrm/class/skill.class.php';
38 require_once DOL_DOCUMENT_ROOT . '/hrm/class/skillrank.class.php';
39 require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_skill.lib.php';
40 
41 // Load translation files required by the page
42 $langs->loadLangs(array('hrm', 'other'));
43 
44 // Get Parameters
45 $action = GETPOST('action', 'aZ09');
46 $confirm = GETPOST('confirm', 'alpha');
47 $cancel = GETPOST('cancel', 'aZ09');
48 $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'skillcard'; // To manage different context of search
49 $backtopage = GETPOST('backtopage', 'alpha');
50 $backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
51 
52 $id = GETPOST('id', 'int');
53 $TSkillsToAdd = GETPOST('fk_skill', 'array');
54 $objecttype = GETPOST('objecttype', 'alpha');
55 $TNote = GETPOST('TNote', 'array');
56 $lineid = GETPOST('lineid', 'int');
57 
58 if (empty($objecttype)) {
59  $objecttype = 'job';
60 }
61 
62 $TAuthorizedObjects = array('job', 'user');
63 $skill = new SkillRank($db);
64 
65 // Initialize technical objects
66 if (in_array($objecttype, $TAuthorizedObjects)) {
67  if ($objecttype == 'job') {
68  $object = new Job($db);
69  } elseif ($objecttype == "user") {
70  $object = new User($db);
71  }
72 } else {
73  accessforbidden('ErrorBadObjectType');
74 }
75 
76 $hookmanager->initHooks(array('skilltab', 'globalcard')); // Note that conf->hooks_modules contains array
77 
78 // Load object
79 include DOL_DOCUMENT_ROOT . '/core/actions_fetchobject.inc.php'; // Must be include, not include_once.
80 
81 // Permissions
82 $permissiontoread = $user->hasRight('hrm', 'all', 'read');
83 $permissiontoadd = $user->hasRight('hrm', 'all', 'write'); // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
84 
85 // Security check (enable the most restrictive one)
86 if ($user->socid > 0) accessforbidden();
87 if (empty($conf->hrm->enabled)) accessforbidden();
88 if (!$permissiontoread) accessforbidden();
89 
90 
91 /*
92  * Actions
93  */
94 
95 $parameters = array();
96 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
97 if ($reshook < 0) {
98  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
99 }
100 
101 if (empty($reshook)) {
102  $error = 0;
103 
104  $backurlforlist = DOL_URL_ROOT.'/hrm/skill_list.php';
105 
106  if (empty($backtopage) || ($cancel && empty($id))) {
107  if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
108  if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
109  $backtopage = $backurlforlist;
110  } else {
111  $backtopage = DOL_URL_ROOT.'/hrm/skill_list.php?id=' . ($id > 0 ? $id : '__ID__');
112  }
113  }
114  }
115 
116  if ($action == 'addSkill') {
117  $error = 0;
118 
119  if (empty($TSkillsToAdd)) {
120  setEventMessage('ErrNoSkillSelected', 'errors');
121  $error++;
122  }
123 
124  if (!$error) {
125  foreach ($TSkillsToAdd as $k=>$v) {
126  $skillAdded = new SkillRank($db);
127  $skillAdded->fk_skill = $v;
128  $skillAdded->fk_object = $id;
129  $skillAdded->objecttype = $objecttype;
130  $ret = $skillAdded->create($user);
131  if ($ret < 0) setEventMessages($skillAdded->error, null, 'errors');
132  //else unset($TSkillsToAdd);
133  }
134  if ($ret > 0) setEventMessages($langs->trans("SaveAddSkill"), null);
135  }
136  } elseif ($action == 'saveSkill') {
137  if (!empty($TNote)) {
138  foreach ($TNote as $skillId => $rank) {
139  $TSkills = $skill->fetchAll('ASC', 't.rowid', 0, 0, array('customsql' => 'fk_object=' . ((int) $id) . " AND objecttype='" . $db->escape($objecttype) . "' AND fk_skill = " . ((int) $skillId)));
140  if (is_array($TSkills) && !empty($TSkills)) {
141  foreach ($TSkills as $tmpObj) {
142  $tmpObj->rankorder = $rank;
143  $tmpObj->update($user);
144  }
145  }
146  }
147  setEventMessages($langs->trans("SaveLevelSkill"), null);
148  header("Location: " . DOL_URL_ROOT.'/hrm/skill_tab.php?id=' . $id. '&objecttype=job');
149  exit;
150  }
151  } elseif ($action == 'confirm_deleteskill' && $confirm == 'yes') {
152  $skillToDelete = new SkillRank($db);
153  $ret = $skillToDelete->fetch($lineid);
154  setEventMessages($langs->trans("DeleteSkill"), null);
155  if ($ret > 0) {
156  $skillToDelete->delete($user);
157  }
158  }
159 }
160 
161 /*
162  * View
163  */
164 
165 $form = new Form($db);
166 $formfile = new FormFile($db);
167 $formproject = new FormProjets($db);
168 
169 $title = $langs->trans("RequiredSkills");
170 $help_url = '';
171 llxHeader('', $title, $help_url);
172 
173 // Part to show record
174 if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
175  $res = $object->fetch_optionals();
176 
177  // view configuration
178  if ($objecttype == 'job') {
179  require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_job.lib.php';
180  $head = jobPrepareHead($object);
181  $listLink = dol_buildpath('/hrm/job_list.php', 1);
182  } elseif ($objecttype == "user") {
183  require_once DOL_DOCUMENT_ROOT . "/core/lib/usergroups.lib.php";
184  $object->getRights();
185  $head = user_prepare_head($object);
186  $listLink = dol_buildpath('/user/list.php', 1);
187  }
188 
189  print dol_get_fiche_head($head, 'skill_tab', $langs->trans("Workstation"), -1, $object->picto);
190 
191  $formconfirm = '';
192 
193  // Confirmation to delete
194  /*if ($action == 'delete') {
195  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteSkill'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1);
196  }*/
197  // Confirmation to delete line
198  if ($action == 'ask_deleteskill') {
199  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id . '&objecttype=' . $objecttype . '&lineid=' . $lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteskill', '', 0, 1);
200  }
201  // Clone confirmation
202  /*if ($action == 'clone') {
203  // Create an array for form
204  $formquestion = array();
205  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
206  }*/
207 
208  // Call Hook formConfirm
209  $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
210  $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
211  if (empty($reshook)) {
212  $formconfirm .= $hookmanager->resPrint;
213  } elseif ($reshook > 0) {
214  $formconfirm = $hookmanager->resPrint;
215  }
216 
217  // Print form confirm
218  print $formconfirm;
219 
220 
221  // Object card
222  // ------------------------------------------------------------
223  if ($objecttype == 'job') {
224  $linkback = '<a href="' . dol_buildpath('/hrm/job_list.php', 1) . '?restore_lastsearch_values=1' . (!empty($socid) ? '&socid=' . $socid : '') . '">' . $langs->trans("BackToList") . '</a>';
225 
226  $morehtmlref = '<div class="refid">';
227  $morehtmlref.= $object->label;
228  $morehtmlref .= '</div>';
229 
230  dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'rowid', $morehtmlref);
231  } else {
232  $linkback = '<a href="' . $listLink . '?restore_lastsearch_values=1' . (!empty($socid) ? '&socid=' . $socid : '') . '">' . $langs->trans("BackToList") . '</a>';
233 
234  $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">';
235  $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"');
236  $morehtmlref .= '</a>';
237 
238  $urltovirtualcard = '/user/virtualcard.php?id='.((int) $object->id);
239  $morehtmlref .= dolButtonToOpenUrlInDialogPopup('publicvirtualcard', $langs->trans("PublicVirtualCardUrl").' - '.$object->getFullName($langs), img_picto($langs->trans("PublicVirtualCardUrl"), 'card', 'class="valignmiddle marginleftonly paddingrightonly"'), $urltovirtualcard, '', 'nohover');
240 
241  dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'rowid', $morehtmlref, '&objecttype='.$objecttype);
242  }
243 
244  // Get all available skills
245  $static_skill = new Skill($db);
246  $TAllSkills = $static_skill->fetchAll();
247 
248  // Array format for multiselectarray function
249  $TAllSkillsFormatted=array();
250  if (!empty($TAllSkills)) {
251  foreach ($TAllSkills as $k=>$v) {
252  $TAllSkillsFormatted[$k] = $v->label;
253  }
254  }
255 
256  // table of skillRank linked to current object
257  $TSkillsJob = $skill->fetchAll('ASC', 't.rowid', 0, 0, array('customsql' => 'fk_object=' . ((int) $id) . " AND objecttype='" . $db->escape($objecttype) . "'"));
258 
259  $TAlreadyUsedSkill = array();
260  if (is_array($TSkillsJob) && !empty($TSkillsJob)) {
261  foreach ($TSkillsJob as $skillElement) {
262  $TAlreadyUsedSkill[$skillElement->fk_skill] = $skillElement->fk_skill;
263  }
264  }
265 
266  print '<div class="fichecenter">';
267  print '<div class="fichehalfleft">';
268 
269  print '<div class="underbanner clearboth"></div>';
270  print '<table class="border centpercent tableforfield">'."\n";
271 
272  if ($objecttype == 'job') {
273  // Common attributes
274  //$keyforbreak='fieldkeytoswitchonsecondcolumn'; // We change column just before this field
275  //unset($object->fields['fk_project']); // Hide field already shown in banner
276  //unset($object->fields['fk_soc']); // Hide field already shown in banner
277  $object->fields['label']['visible']=0; // Already in banner
278  include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_view.tpl.php';
279 
280  // Other attributes. Fields from hook formObjectOptions and Extrafields.
281  include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php';
282  } else {
283  // Login
284  print '<tr><td class="titlefield">'.$langs->trans("Login").'</td>';
285  if (!empty($object->ldap_sid) && $object->statut == 0) {
286  print '<td class="error">';
287  print $langs->trans("LoginAccountDisableInDolibarr");
288  print '</td>';
289  } else {
290  print '<td>';
291  $addadmin = '';
292  if (property_exists($object, 'admin')) {
293  if (isModEnabled('multicompany') && !empty($object->admin) && empty($object->entity)) {
294  $addadmin .= img_picto($langs->trans("SuperAdministratorDesc"), "redstar", 'class="paddingleft"');
295  } elseif (!empty($object->admin)) {
296  $addadmin .= img_picto($langs->trans("AdministratorDesc"), "star", 'class="paddingleft"');
297  }
298  }
299  print showValueWithClipboardCPButton(!empty($object->login) ? $object->login : '').$addadmin;
300  print '</td>';
301  }
302  print '</tr>'."\n";
303 
304  $object->fields['label']['visible']=0; // Already in banner
305  $object->fields['firstname']['visible']=0; // Already in banner
306  $object->fields['lastname']['visible']=0; // Already in banner
307  //include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_view.tpl.php';
308 
309  // Ref employee
310  print '<tr><td class="titlefield">'.$langs->trans("RefEmployee").'</td>';
311  print '<td class="error">';
312  print showValueWithClipboardCPButton(!empty($object->ref_employee) ? $object->ref_employee : '');
313  print '</td>';
314  print '</tr>'."\n";
315 
316  // National Registration Number
317  print '<tr><td class="titlefield">'.$langs->trans("NationalRegistrationNumber").'</td>';
318  print '<td class="error">';
319  print showValueWithClipboardCPButton(!empty($object->national_registration_number) ? $object->national_registration_number : '');
320  print '</td>';
321  print '</tr>'."\n";
322  }
323 
324  print '</table>';
325 
326  print '</div>';
327  print '</div>';
328 
329 
330  print '<div class="clearboth"></div><br>';
331 
332  if ($objecttype != 'user' && $permissiontoadd) {
333  // form pour ajouter des compétences
334  print '<form name="addSkill" method="post" action="' . $_SERVER['PHP_SELF'] . '">';
335  print '<input type="hidden" name="objecttype" value="' . $objecttype . '">';
336  print '<input type="hidden" name="id" value="' . $id . '">';
337  print '<input type="hidden" name="action" value="addSkill">';
338  print '<input type="hidden" name="token" value="'.newToken().'">';
339  print '<div class="div-table-responsive-no-min">';
340  print '<table id="tablelines" class="noborder noshadow" width="100%">';
341  print '<tr><td style="width:90%">' . $langs->trans('AddSkill') . '</td><td style="width:10%"></td></tr>';
342  print '<tr>';
343  print '<td>';
344  print img_picto('', 'shapes', 'class="pictofixedwidth"');
345  print $form->multiselectarray('fk_skill', array_diff_key($TAllSkillsFormatted, $TAlreadyUsedSkill), array(), 0, 0, 'widthcentpercentminusx') . '</td>';
346  print '<td><input class="button reposition" type="submit" value="' . $langs->trans('Add') . '"></td>';
347  print '</tr>';
348  print '</table>';
349  print '</div>';
350  print '</form>';
351  }
352  print '<br>';
353 
354  print '<div class="clearboth"></div>';
355 
356  if ($objecttype != 'user' && $permissiontoadd) {
357  print '<form name="saveSkill" method="post" action="' . $_SERVER['PHP_SELF'] . '">';
358  print '<input type="hidden" name="objecttype" value="' . $objecttype . '">';
359  print '<input type="hidden" name="id" value="' . $id . '">';
360  print '<input type="hidden" name="token" value="'.newToken().'">';
361  print '<input type="hidden" name="action" value="saveSkill">';
362  }
363  print '<div class="div-table-responsive-no-min">';
364  print '<table id="tablelines" class="noborder centpercent" width="100%">';
365  print '<tr class="liste_titre">';
366  print '<th>'.$langs->trans('SkillType').'</th>';
367  print '<th>'.$langs->trans('Label').'</th>';
368  print '<th>'.$langs->trans('Description').'</th>';
369  print '<th>'.$langs->trans($objecttype === 'job' ? 'RequiredRank' : 'EmployeeRank').'</th>';
370  if ($objecttype === 'job') {
371  print '<th class="linecoledit"></th>';
372  print '<th class="linecoldelete"></th>';
373  }
374  print '</tr>';
375  if (!is_array($TSkillsJob) || empty($TSkillsJob)) {
376  print '<tr><td><span class="opacitymedium">' . $langs->trans("NoRecordFound") . '</span></td></tr>';
377  } else {
378  $sk = new Skill($db);
379  foreach ($TSkillsJob as $skillElement) {
380  $sk->fetch($skillElement->fk_skill);
381  print '<tr>';
382  print '<td>';
383  print Skill::typeCodeToLabel($sk->skill_type);
384  print '</td><td class="linecolfk_skill">';
385  print $sk->getNomUrl(1);
386  print '</td>';
387  print '<td>';
388  print $sk->description;
389  print '</td><td class="linecolrank">';
390  print displayRankInfos($skillElement->rankorder, $skillElement->fk_skill, 'TNote', $objecttype == 'job' && $permissiontoadd ? 'edit' : 'view');
391  print '</td>';
392  if ($objecttype != 'user' && $permissiontoadd) {
393  print '<td class="linecoledit"></td>';
394  print '<td class="linecoldelete">';
395  print '<a class="reposition" href="' . $_SERVER["PHP_SELF"] . '?id=' . $skillElement->fk_object . '&amp;objecttype=' . $objecttype . '&amp;action=ask_deleteskill&amp;lineid=' . $skillElement->id . '">';
396  print img_delete();
397  print '</a>';
398  }
399  print '</td>';
400  print '</tr>';
401  }
402  }
403 
404  print '</table>';
405  if ($objecttype != 'user' && $permissiontoadd) print '<td><input class="button pull-right" type="submit" value="' . $langs->trans('SaveRank') . '"></td>';
406  print '</div>';
407  if ($objecttype != 'user' && $permissiontoadd) print '</form>';
408 
409 
410  // liste des compétences liées
411 
412  print dol_get_fiche_end();
413 
414  llxFooter();
415 }
if(GETPOST('button_removefilter_x', 'alpha')||GETPOST('button_removefilter.x', 'alpha')||GETPOST('button_removefilter', 'alpha')) if(GETPOST('button_search_x', 'alpha')||GETPOST('button_search.x', 'alpha')||GETPOST('button_search', 'alpha')) if($action=="save" &&empty($cancel)) $help_url
View.
Definition: agenda.php:118
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:56
llxFooter()
Empty footer.
Definition: wrapper.php:70
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:37
Class for Skill.
Definition: skill.class.php:37
static typeCodeToLabel($code)
Class for SkillRank.
Class to manage Dolibarr users.
Definition: user.class.php:48
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='rowid', $fieldref='ref', $morehtmlref='', $moreparam='', $nodbprefix=0, $morehtmlleft='', $morehtmlstatus='', $onlybanner=0, $morehtmlright='')
Show tab footer of a card.
showValueWithClipboardCPButton($valuetocopy, $showonlyonhover=1, $texttoshow='')
Create a button to copy $valuetocopy in the clipboard (for copy and paste feature).
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
dolButtonToOpenUrlInDialogPopup($name, $label, $buttonstring, $url, $disabled='', $morecss='classlink button bordertransp', $jsonopen='', $backtopagejsfields='', $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)
Set event message in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
isModEnabled($module)
Is Dolibarr module enabled.
jobPrepareHead($object)
Prepare array of tabs for Job.
Definition: hrm_job.lib.php:33
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.
$formconfirm
if ($action == 'delbookkeepingyear') {
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.