dolibarr 21.0.0-beta
job.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
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 Frédéric France <frederic.france@free.fr>
8 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
30// Put here all includes required by your class file
31require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
32
33
37class Job extends CommonObject
38{
42 public $module = 'hrm';
43
47 public $element = 'job';
48
52 public $table_element = 'hrm_job';
53
57 public $picto = 'technic';
58
59
60 const STATUS_DRAFT = 0;
61 const STATUS_VALIDATED = 1;
62 const STATUS_CANCELED = 9;
63
64
91 // BEGIN MODULEBUILDER PROPERTIES
95 public $fields = array(
96 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'css' => 'left', 'comment' => "Id"),
97 'label' => array('type' => 'varchar(128)', 'label' => 'Label', 'enabled' => 1, 'position' => 20, 'notnull' => 1, 'visible' => 1, 'index' => 1, 'searchall' => 1, 'showoncombobox' => 1, 'comment' => "Label of object"),
98 'description' => array('type' => 'text', 'label' => 'Description', 'enabled' => 1, 'position' => 21, 'notnull' => 0, 'visible' => 1,),
99 'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'position' => 500, 'notnull' => 1, 'visible' => 2,),
100 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'position' => 501, 'notnull' => 0, 'visible' => 2,),
101 'deplacement' => array('type' => 'select', 'required' => 1,'label' => 'NeedBusinessTravels', 'enabled' => 1, 'position' => 90, 'notnull' => 1, 'visible' => 1, 'arrayofkeyval' => array(0 => "No", 1 => "Yes"), 'default' => '0'),
102 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'position' => 70, 'notnull' => 0, 'visible' => 0,),
103 'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'position' => 71, 'notnull' => 0, 'visible' => 0,),
104 'fk_user_creat' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'enabled' => 1, 'position' => 510, 'notnull' => 1, 'visible' => -2, 'foreignkey' => 'user.rowid',),
105 'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'position' => 511, 'notnull' => -1, 'visible' => -2,),
106 );
110 public $rowid;
114 public $ref;
118 public $label;
122 public $description;
126 public $deplacement;
130 public $fk_user_creat;
134 public $fk_user_modif;
135 // END MODULEBUILDER PROPERTIES
136
137
138 // If this object has a subtable with lines
139
140 // /**
141 // * @var string Name of subtable line
142 // */
143 // public $table_element_line = 'hrm_jobline';
144
148 public $fk_element = 'fk_job';
149
150 // /**
151 // * @var string Name of subtable class that manage subtable lines
152 // */
153 // public $class_element_line = 'Jobline';
154
158 protected $childtables = array(
159 'hrm_evaluation' => ['name' => 'Evaluation'],
160 'hrm_job_user' => ['name' => 'Job'],
161 );
162
168 protected $childtablesoncascade = array("@SkillRank:hrm/class/skillrank.class.php:fk_object:(objecttype:=:'job')");
169
170 // /**
171 // * @var JobLine[] Array of subtable lines
172 // */
173 // public $lines = array();
174
175
176
182 public function __construct(DoliDB $db)
183 {
184 global $conf, $langs;
185
186 $this->db = $db;
187
188 $this->ismultientitymanaged = 0;
189 $this->isextrafieldmanaged = 1;
190
191 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
192 $this->fields['rowid']['visible'] = 0;
193 }
194 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
195 $this->fields['entity']['enabled'] = 0;
196 }
197
198 // Example to show how to set values of fields definition dynamically
199 /*if ($user->rights->hrm->job->read) {
200 $this->fields['myfield']['visible'] = 1;
201 $this->fields['myfield']['noteditable'] = 0;
202 }*/
203
204 // Unset fields that are disabled
205 foreach ($this->fields as $key => $val) {
206 if (isset($val['enabled']) && empty($val['enabled'])) {
207 unset($this->fields[$key]);
208 }
209 }
210
211 // Translate some data of arrayofkeyval
212 if (is_object($langs)) {
213 foreach ($this->fields as $key => $val) {
214 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
215 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
216 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
217 }
218 }
219 }
220 }
221 }
222
230 public function create(User $user, $notrigger = 0)
231 {
232 $resultcreate = $this->createCommon($user, $notrigger);
233
234 //$resultvalidate = $this->validate($user, $notrigger);
235
236 return $resultcreate;
237 }
238
246 public function createFromClone(User $user, $fromid)
247 {
248 global $langs, $extrafields;
249 $error = 0;
250
251 dol_syslog(__METHOD__, LOG_DEBUG);
252
253 $object = new self($this->db);
254
255 $this->db->begin();
256
257 // Load source object
258 $result = $object->fetchCommon($fromid);
259 if ($result > 0 && !empty($object->table_element_line)) {
260 $object->fetchLines();
261 }
262
263 // get lines so they will be clone
264 //foreach($this->lines as $line)
265 // $line->fetch_optionals();
266
267 // Reset some properties
268 unset($object->id);
269 unset($object->fk_user_creat);
270 unset($object->import_key);
271
272 // Clear fields
273 if (property_exists($object, 'ref')) {
274 $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
275 }
276 if (property_exists($object, 'label')) {
277 // @phan-suppress-next-line PhanTypeInvalidDimOffset
278 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
279 }
280 if (property_exists($object, 'status')) {
281 $object->status = self::STATUS_DRAFT;
282 }
283 if (property_exists($object, 'date_creation')) {
284 $object->date_creation = dol_now();
285 }
286 if (property_exists($object, 'date_modification')) {
287 $object->date_modification = null;
288 }
289 // ...
290 // Clear extrafields that are unique
291 if (is_array($object->array_options) && count($object->array_options) > 0) {
292 $extrafields->fetch_name_optionals_label($this->table_element);
293 foreach ($object->array_options as $key => $option) {
294 $shortkey = preg_replace('/options_/', '', $key);
295 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
296 //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
297 unset($object->array_options[$key]);
298 }
299 }
300 }
301
302 // Create clone
303 $object->context['createfromclone'] = 'createfromclone';
304 $result = $object->createCommon($user);
305 if ($result < 0) {
306 $error++;
308 }
309
310 if (!$error) {
311 // copy internal contacts
312 if ($this->copy_linked_contact($object, 'internal') < 0) {
313 $error++;
314 }
315 }
316
317 if (!$error) {
318 // copy external contacts if same company
319 if (property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
320 if ($this->copy_linked_contact($object, 'external') < 0) {
321 $error++;
322 }
323 }
324 }
325
326 unset($object->context['createfromclone']);
327
328 // End
329 if (!$error) {
330 $this->db->commit();
331 return $object;
332 } else {
333 $this->db->rollback();
334 return -1;
335 }
336 }
337
345 public function fetch($id, $ref = null)
346 {
347 $result = $this->fetchCommon($id, $ref);
348 if ($result > 0 && !empty($this->table_element_line)) {
349 $this->fetchLines();
350 }
351 return $result;
352 }
353
359 public function fetchLines()
360 {
361 $this->lines = array();
362
363 $result = $this->fetchLinesCommon();
364 return $result;
365 }
366
367
380 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
381 {
382 dol_syslog(__METHOD__, LOG_DEBUG);
383
384 $records = array();
385
386 $sql = 'SELECT ';
387 $sql .= $this->getFieldList('t');
388 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
389 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
390 $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
391 } else {
392 $sql .= ' WHERE 1 = 1';
393 }
394
395 // Manage filter
396 $errormessage = '';
397 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
398 if ($errormessage) {
399 $this->errors[] = $errormessage;
400 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
401 return -1;
402 }
403
404 if (!empty($sortfield)) {
405 $sql .= $this->db->order($sortfield, $sortorder);
406 }
407 if (!empty($limit)) {
408 $sql .= ' '.$this->db->plimit($limit, $offset);
409 }
410
411 $resql = $this->db->query($sql);
412 if ($resql) {
413 $num = $this->db->num_rows($resql);
414 $i = 0;
415 while ($i < ($limit ? min($limit, $num) : $num)) {
416 $obj = $this->db->fetch_object($resql);
417
418 $record = new self($this->db);
419 $record->setVarsFromFetchObj($obj);
420
421 $records[$record->id] = $record;
422
423 $i++;
424 }
425 $this->db->free($resql);
426
427 return $records;
428 } else {
429 $this->errors[] = 'Error '.$this->db->lasterror();
430 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
431
432 return -1;
433 }
434 }
435
443 public function update(User $user, $notrigger = 0)
444 {
445 return $this->updateCommon($user, $notrigger);
446 }
447
455 public function delete(User $user, $notrigger = 0)
456 {
457 return $this->deleteCommon($user, $notrigger);
458 //return $this->deleteCommon($user, $notrigger, 1);
459 }
460
469 public function deleteLine(User $user, $idline, $notrigger = 0)
470 {
471 if ($this->status < 0) {
472 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
473 return -2;
474 }
475
476 return $this->deleteLineCommon($user, $idline, $notrigger);
477 }
478
479
487 public function validate($user, $notrigger = 0)
488 {
489 global $conf, $langs;
490
491 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
492
493 $error = 0;
494
495 // Protection
496 if ($this->status == self::STATUS_VALIDATED) {
497 dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
498 return 0;
499 }
500
501 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->job->write))
502 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->job->job_advance->validate))))
503 {
504 $this->error='NotEnoughPermissions';
505 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
506 return -1;
507 }*/
508
509 $now = dol_now();
510
511 $this->db->begin();
512
513 // Define new ref
514 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
515 $num = $this->getNextNumRef();
516 } else {
517 $num = $this->ref;
518 }
519 $this->newref = $num;
520
521 if (!empty($num)) {
522 // Validate
523 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
524 $sql .= " SET ref = '".$this->db->escape($num)."',";
525 $sql .= " status = ".self::STATUS_VALIDATED;
526 if (!empty($this->fields['date_validation'])) {
527 $sql .= ", date_validation = '".$this->db->idate($now)."'";
528 }
529 if (!empty($this->fields['fk_user_valid'])) { // @phan-suppress-current-line PhanTypeMismatchProperty
530 $sql .= ", fk_user_valid = ".((int) $user->id);
531 }
532 $sql .= " WHERE rowid = ".((int) $this->id);
533
534 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
535 $resql = $this->db->query($sql);
536 if (!$resql) {
537 dol_print_error($this->db);
538 $this->error = $this->db->lasterror();
539 $error++;
540 }
541
542 if (!$error && !$notrigger) {
543 // Call trigger
544 $result = $this->call_trigger('HRM_JOB_VALIDATE', $user);
545 if ($result < 0) {
546 $error++;
547 }
548 // End call triggers
549 }
550 }
551
552 if (!$error) {
553 $this->oldref = $this->ref;
554
555 // Rename directory if dir was a temporary ref
556 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
557 // Now we rename also files into index
558 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'job/".$this->db->escape($this->newref)."'";
559 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'job/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
560 $resql = $this->db->query($sql);
561 if (!$resql) {
562 $error++;
563 $this->error = $this->db->lasterror();
564 }
565 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'job/".$this->db->escape($this->newref)."'";
566 $sql .= " WHERE filepath = 'job/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
567 $resql = $this->db->query($sql);
568 if (!$resql) {
569 $error++;
570 $this->error = $this->db->lasterror();
571 }
572
573 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
574 $oldref = dol_sanitizeFileName($this->ref);
575 $newref = dol_sanitizeFileName($num);
576 $dirsource = $conf->hrm->dir_output.'/job/'.$oldref;
577 $dirdest = $conf->hrm->dir_output.'/job/'.$newref;
578 if (!$error && file_exists($dirsource)) {
579 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
580
581 if (@rename($dirsource, $dirdest)) {
582 dol_syslog("Rename ok");
583 // Rename docs starting with $oldref with $newref
584 $listoffiles = dol_dir_list($conf->hrm->dir_output.'/job/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
585 foreach ($listoffiles as $fileentry) {
586 $dirsource = $fileentry['name'];
587 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
588 $dirsource = $fileentry['path'].'/'.$dirsource;
589 $dirdest = $fileentry['path'].'/'.$dirdest;
590 @rename($dirsource, $dirdest);
591 }
592 }
593 }
594 }
595 }
596
597 // Set new ref and current status
598 if (!$error) {
599 $this->ref = $num;
600 $this->status = self::STATUS_VALIDATED;
601 }
602
603 if (!$error) {
604 $this->db->commit();
605 return 1;
606 } else {
607 $this->db->rollback();
608 return -1;
609 }
610 }
611
618 public function getLastJobForUser($fk_user)
619 {
620 $Tab = $this->getForUser($fk_user);
621
622 if (empty($Tab)) {
623 return '';
624 }
625
626 $lastpos = array_shift($Tab);
627
628 return $lastpos;
629 }
630
637 public function getForUser($userid)
638 {
639 global $db;
640
641 $TReturn = array();
642 $position = new Position($db);
643 $TPosition = $position->getForUser($userid);
644 foreach ($TPosition as $UPosition) {
645 $TReturn[$UPosition->Job->rowid] = $UPosition->Job->ref;
646 }
647 return $TReturn;
648 }
649
657 public function setDraft($user, $notrigger = 0)
658 {
659 // Protection
660 if ($this->status <= self::STATUS_DRAFT) {
661 return 0;
662 }
663
664 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
665 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
666 {
667 $this->error='Permission denied';
668 return -1;
669 }*/
670
671 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'JOB_UNVALIDATE');
672 }
673
681 public function cancel($user, $notrigger = 0)
682 {
683 // Protection
684 if ($this->status != self::STATUS_VALIDATED) {
685 return 0;
686 }
687
688 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
689 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
690 {
691 $this->error='Permission denied';
692 return -1;
693 }*/
694
695 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'JOB_CANCEL');
696 }
697
705 public function reopen($user, $notrigger = 0)
706 {
707 // Protection
708 if ($this->status != self::STATUS_CANCELED) {
709 return 0;
710 }
711
712 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
713 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
714 {
715 $this->error='Permission denied';
716 return -1;
717 }*/
718
719 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'JOB_REOPEN');
720 }
721
732 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
733 {
734 global $conf, $langs, $hookmanager;
735
736 if (!empty($conf->dol_no_mouse_hover)) {
737 $notooltip = 1; // Force disable tooltips
738 }
739
740 $result = '';
741
742 $label = img_picto('', $this->picto).' <u>'.$langs->trans("JobProfile").'</u>';
743 if (isset($this->status)) {
744 $label .= ' '.$this->getLibStatut(5);
745 }
746 $label .= '<br>';
747 $label .= '<b>'.$langs->trans('Label').':</b> '.$this->label;
748
749 $url = dol_buildpath('/hrm/job_card.php', 1).'?id='.$this->id;
750
751 if ($option != 'nolink') {
752 // Add param to save lastsearch_values or not
753 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
754 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
755 $add_save_lastsearch_values = 1;
756 }
757 if ($add_save_lastsearch_values) {
758 $url .= '&save_lastsearch_values=1';
759 }
760 }
761
762 $linkclose = '';
763 if (empty($notooltip)) {
764 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
765 $label = $langs->trans("ShowJob");
766 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
767 }
768 $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
769 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
770 } else {
771 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
772 }
773
774 if ($option == 'nolink') {
775 $linkstart = '<span';
776 } else {
777 $linkstart = '<a href="'.$url.'"';
778 }
779 $linkstart .= $linkclose.'>';
780 if ($option == 'nolink') {
781 $linkend = '</span>';
782 } else {
783 $linkend = '</a>';
784 }
785
786 $result .= $linkstart;
787
788 if (empty($this->showphoto_on_popup)) {
789 if ($withpicto) {
790 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
791 }
792 } else {
793 if ($withpicto) {
794 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
795
796 list($class, $module) = explode('@', $this->picto);
797 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->label);
798 $filearray = dol_dir_list($upload_dir, "files");
799 $filename = $filearray[0]['name'];
800 if (!empty($filename)) {
801 $pospoint = strpos($filearray[0]['name'], '.');
802
803 $pathtophoto = $class.'/'.$this->label.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
804 if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
805 $result .= '<div class="floatleft inline-block valignmiddle divphotoref"><div class="photoref"><img class="photo'.$module.'" alt="No photo" border="0" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$module.'&entity='.$conf->entity.'&file='.urlencode($pathtophoto).'"></div></div>';
806 } else {
807 $result .= '<div class="floatleft inline-block valignmiddle divphotoref"><img class="photouserphoto userphoto" alt="No photo" border="0" src="'.DOL_URL_ROOT.'/viewimage.php?modulepart='.$module.'&entity='.$conf->entity.'&file='.urlencode($pathtophoto).'"></div>';
808 }
809
810 $result .= '</div>';
811 } else {
812 $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
813 }
814 }
815 }
816
817 if ($withpicto != 2) {
818 $result .= $this->label;
819 }
820
821 $result .= $linkend;
822 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
823
824 global $action, $hookmanager;
825 $hookmanager->initHooks(array('jobdao'));
826 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
827 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
828 if ($reshook > 0) {
829 $result = $hookmanager->resPrint;
830 } else {
831 $result .= $hookmanager->resPrint;
832 }
833
834 return $result;
835 }
836
843 public function getLibStatut($mode = 0)
844 {
845 return $this->LibStatut($this->status, $mode);
846 }
847
848 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
856 public function LibStatut($status, $mode = 0)
857 {
858 // phpcs:enable
859 return ''; // There is no status on job profile for the moment
860
861 /*
862 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
863 global $langs;
864 //$langs->load("hrm");
865 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
866 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
867 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
868 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
869 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
870 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
871 }
872
873 $statusType = 'status'.$status;
874 //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
875 if ($status == self::STATUS_CANCELED) {
876 $statusType = 'status6';
877 }
878
879 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
880 */
881 }
882
889 public function info($id)
890 {
891 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
892 $sql .= ' fk_user_creat, fk_user_modif';
893 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
894 $sql .= ' WHERE t.rowid = '.((int) $id);
895 $result = $this->db->query($sql);
896 if ($result) {
897 if ($this->db->num_rows($result)) {
898 $obj = $this->db->fetch_object($result);
899
900 $this->id = $obj->rowid;
901
902 $this->user_creation_id = $obj->fk_user_creat;
903 $this->user_modification_id = $obj->fk_user_modif;
904 $this->date_creation = $this->db->jdate($obj->datec);
905 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
906 }
907
908 $this->db->free($result);
909 } else {
910 dol_print_error($this->db);
911 }
912 }
913
920 public function initAsSpecimen()
921 {
922 // Set here init that are not commonf fields
923 // $this->property1 = ...
924 // $this->property2 = ...
925
926 return $this->initAsSpecimenCommon();
927 }
928
934 public function getLinesArray()
935 {
936 $this->lines = array();
937
938 $objectline = new JobLine($this->db);
939 $result = $objectline->fetchAll('ASC', 'position', 0, 0, '(fk_job:=:'.((int) $this->id).')');
940
941 if (is_numeric($result)) {
942 $this->setErrorsFromObject($objectline);
943 return $result;
944 } else {
945 $this->lines = $result;
946 return $this->lines;
947 }
948 }
949
955 public function getNextNumRef()
956 {
957 global $langs, $conf;
958 $langs->load("hrm");
959
960 if (!getDolGlobalString('hrm_JOB_ADDON')) {
961 $conf->global->hrm_JOB_ADDON = 'mod_job_standard';
962 }
963
964 if (getDolGlobalString('hrm_JOB_ADDON')) {
965 $mybool = false;
966
967 $file = getDolGlobalString('hrm_JOB_ADDON') . ".php";
968 $classname = getDolGlobalString('hrm_JOB_ADDON');
969
970 // Include file with class
971 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
972 foreach ($dirmodels as $reldir) {
973 $dir = dol_buildpath($reldir."core/modules/hrm/");
974
975 // Load file with numbering class (if found)
976 $mybool = ((bool) @include_once $dir.$file) || $mybool;
977 }
978
979 if (!$mybool) {
980 dol_print_error(null, "Failed to include file ".$file);
981 return '';
982 }
983
984 if (class_exists($classname)) {
985 $obj = new $classname();
986 '@phan-var-force ModeleNumRefEvaluation $obj';
987 $numref = $obj->getNextValue($this);
988
989 if ($numref != '' && $numref != '-1') {
990 return $numref;
991 } else {
992 $this->error = $obj->error;
993 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
994 return "";
995 }
996 } else {
997 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
998 return "";
999 }
1000 } else {
1001 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1002 return "";
1003 }
1004 }
1005
1017 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1018 {
1019 global $conf, $langs;
1020
1021 $result = 0;
1022 $includedocgeneration = 0;
1023
1024 $langs->load("hrm");
1025
1026 if (!dol_strlen($modele)) {
1027 $modele = 'standard_job';
1028
1029 if (!empty($this->model_pdf)) {
1030 $modele = $this->model_pdf;
1031 } elseif (getDolGlobalString('JOB_ADDON_PDF')) {
1032 $modele = getDolGlobalString('JOB_ADDON_PDF');
1033 }
1034 }
1035
1036 $modelpath = "core/modules/hrm/doc/";
1037
1038 if ($includedocgeneration && !empty($modele)) {
1039 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1040 }
1041
1042 return $result;
1043 }
1044
1052 public function getKanbanView($option = '', $arraydata = null)
1053 {
1054 global $selected, $langs;
1055
1056 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1057
1058 $return = '<div class="box-flex-item box-flex-grow-zero">';
1059 $return .= '<div class="info-box info-box-sm">';
1060 $return .= '<span class="info-box-icon bg-infobox-action">';
1061 $return .= img_picto('', $this->picto);
1062 $return .= '</span>';
1063 $return .= '<div class="info-box-content">';
1064 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(0) : $this->ref).'</span>';
1065 if ($selected >= 0) {
1066 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1067 }
1068 /*if (property_exists($this, 'deplacement')) {
1069 $return .= '<br><span class="opacitymedium">'.$langs->trans("Type").'</span>';
1070 $return .= ' : <span class="info-box-label ">'.$this->fields['deplacement']['arrayofkeyval'][$this->deplacement].'</span>';
1071 }*/
1072 if (property_exists($this, 'description') && !(empty($this->description))) {
1073 //$return .= '<br><span class="info-box-label opacitymedium">'.$langs->trans("Description").'</span> : ';
1074 $return .= '<br><span class="info-box-label ">'.(strlen($this->description) > 30 ? dol_substr($this->description, 0, 25).'...' : $this->description).'</span>';
1075 }
1076 $return .= '</div>';
1077 $return .= '</div>';
1078 $return .= '</div>';
1079 return $return;
1080 }
1081
1087 public function getSkillRankForJob($id)
1088 {
1089 if (empty($id)) {
1090 return -1;
1091 }
1092 $skillranks = array();
1093 $sql = "SELECT rowid";
1094 $sql .= " FROM ".MAIN_DB_PREFIX."hrm_skillrank";
1095 $sql .= " WHERE fk_object = ".((int) $id);
1096
1097 $resql = $this->db->query($sql);
1098 if ($resql) {
1099 $num = $this->db->num_rows($resql);
1100 $i = 0;
1101 while ($i < $num) {
1102 $obj = $this->db->fetch_object($resql);
1103 $skillranks[] = $obj;
1104 $i++;
1105 }
1106 $this->db->free($resql);
1107 } else {
1108 dol_print_error($this->db);
1109 }
1110 return $skillranks;
1111 }
1112}
1113
1114
1115require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1116
1121{
1122 // To complete with content of an object JobLine
1123 // We should have a field rowid, fk_job and position
1124
1130 public function __construct(DoliDB $db)
1131 {
1132 $this->db = $db;
1133
1134 $this->isextrafieldmanaged = 0;
1135 }
1136}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
$object ref
Definition info.php:89
Parent class of all other business classes (invoices, contracts, proposals, orders,...
deleteLineCommon(User $user, $idline, $notrigger=0)
Delete a line of object in database.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
setErrorsFromObject($object)
setErrorsFromObject
createCommon(User $user, $notrigger=0)
Create object in the database.
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
updateCommon(User $user, $notrigger=0)
Update object into database.
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
initAsSpecimenCommon()
Initialise object with example values Id must be 0 if object instance is a specimen.
copy_linked_contact($objFrom, $source='internal')
Copy contact from one element to current.
fetchLinesCommon($morewhere='', $noextrafields=0)
Load object in memory from the database.
fetchCommon($id, $ref=null, $morewhere='', $noextrafields=0)
Load object in memory from the database.
deleteCommon(User $user, $notrigger=0, $forcechilddeletion=0)
Delete object in database.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage Dolibarr database access.
Class for Job.
Definition job.class.php:38
getNextNumRef()
Returns the reference to the following non used object depending on the active numbering module.
getLastJobForUser($fk_user)
Get the last occupied position for a user.
fetchLines()
Load object lines in memory from the database.
cancel($user, $notrigger=0)
Set cancel status.
__construct(DoliDB $db)
Constructor.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
setDraft($user, $notrigger=0)
Set draft status.
update(User $user, $notrigger=0)
Update object into database.
validate($user, $notrigger=0)
Validate object.
getLibStatut($mode=0)
Return the label of the status.
getLinesArray()
Create an array of lines.
fetch($id, $ref=null)
Load object in memory from the database.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
LibStatut($status, $mode=0)
Return the status.
deleteLine(User $user, $idline, $notrigger=0)
Delete a line of object in database.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionally the picto)
createFromClone(User $user, $fromid)
Clone an object into another one.
reopen($user, $notrigger=0)
Set back to validated status.
getSkillRankForJob($id)
function for get required skills associate to job object
create(User $user, $notrigger=0)
Create object into database.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, $filter='', $filtermode='AND')
Load list of objects in memory from the database.
getForUser($userid)
Get array of occupied positions for a user.
getKanbanView($option='', $arraydata=null)
Return clickable link of object (with eventually picto)
info($id)
Load the info information in the object.
Class JobLine.
__construct(DoliDB $db)
Constructor.
Class for Position.
Class to manage Dolibarr users.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:171
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:63
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0)
forgeSQLFromUniversalSearchCriteria
dol_now($mode='auto')
Return date for now.
dol_substr($string, $start, $length=null, $stringencoding='', $trunconbytes=0)
Make a substring.
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.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79