dolibarr 22.0.5
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-2025 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 $tmpjob = new Job($db);
646 if ($tmpjob->fetch($UPosition->fk_job) > 0) {
647 $TReturn[$tmpjob->id] = $tmpjob->label;
648 }
649 }
650 return $TReturn;
651 }
652
660 public function setDraft($user, $notrigger = 0)
661 {
662 // Protection
663 if ($this->status <= self::STATUS_DRAFT) {
664 return 0;
665 }
666
667 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
668 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
669 {
670 $this->error='Permission denied';
671 return -1;
672 }*/
673
674 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'JOB_UNVALIDATE');
675 }
676
684 public function cancel($user, $notrigger = 0)
685 {
686 // Protection
687 if ($this->status != self::STATUS_VALIDATED) {
688 return 0;
689 }
690
691 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
692 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
693 {
694 $this->error='Permission denied';
695 return -1;
696 }*/
697
698 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'JOB_CANCEL');
699 }
700
708 public function reopen($user, $notrigger = 0)
709 {
710 // Protection
711 if ($this->status != self::STATUS_CANCELED) {
712 return 0;
713 }
714
715 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
716 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
717 {
718 $this->error='Permission denied';
719 return -1;
720 }*/
721
722 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'JOB_REOPEN');
723 }
724
735 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
736 {
737 global $conf, $langs, $hookmanager;
738
739 if (!empty($conf->dol_no_mouse_hover)) {
740 $notooltip = 1; // Force disable tooltips
741 }
742
743 $result = '';
744
745 $label = img_picto('', $this->picto).' <u>'.$langs->trans("JobProfile").'</u>';
746 if (isset($this->status)) {
747 $label .= ' '.$this->getLibStatut(5);
748 }
749 $label .= '<br>';
750 $label .= '<b>'.$langs->trans('Label').':</b> '.$this->label;
751
752 $url = dol_buildpath('/hrm/job_card.php', 1).'?id='.$this->id;
753
754 if ($option != 'nolink') {
755 // Add param to save lastsearch_values or not
756 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
757 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
758 $add_save_lastsearch_values = 1;
759 }
760 if ($add_save_lastsearch_values) {
761 $url .= '&save_lastsearch_values=1';
762 }
763 }
764
765 $linkclose = '';
766 if (empty($notooltip)) {
767 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
768 $label = $langs->trans("ShowJob");
769 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
770 }
771 $linkclose .= ' title="'.dolPrintHTMLForAttribute($label).'"';
772 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
773 } else {
774 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
775 }
776
777 if ($option == 'nolink') {
778 $linkstart = '<span';
779 } else {
780 $linkstart = '<a href="'.$url.'"';
781 }
782 $linkstart .= $linkclose.'>';
783 if ($option == 'nolink') {
784 $linkend = '</span>';
785 } else {
786 $linkend = '</a>';
787 }
788
789 $result .= $linkstart;
790
791 if (empty($this->showphoto_on_popup)) {
792 if ($withpicto) {
793 $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);
794 }
795 } else {
796 if ($withpicto) {
797 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
798
799 list($class, $module) = explode('@', $this->picto);
800 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->label);
801 $filearray = dol_dir_list($upload_dir, "files");
802 $filename = $filearray[0]['name'];
803 if (!empty($filename)) {
804 $pospoint = strpos($filearray[0]['name'], '.');
805
806 $pathtophoto = $class.'/'.$this->label.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
807 if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
808 $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>';
809 } else {
810 $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>';
811 }
812
813 $result .= '</div>';
814 } else {
815 $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);
816 }
817 }
818 }
819
820 if ($withpicto != 2) {
821 $result .= $this->label;
822 }
823
824 $result .= $linkend;
825 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
826
827 global $action, $hookmanager;
828 $hookmanager->initHooks(array('jobdao'));
829 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
830 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
831 if ($reshook > 0) {
832 $result = $hookmanager->resPrint;
833 } else {
834 $result .= $hookmanager->resPrint;
835 }
836
837 return $result;
838 }
839
846 public function getLibStatut($mode = 0)
847 {
848 return $this->LibStatut($this->status, $mode);
849 }
850
851 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
859 public function LibStatut($status, $mode = 0)
860 {
861 // phpcs:enable
862 return ''; // There is no status on job profile for the moment
863
864 /*
865 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
866 global $langs;
867 //$langs->load("hrm");
868 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
869 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
870 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
871 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
872 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
873 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
874 }
875
876 $statusType = 'status'.$status;
877 //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
878 if ($status == self::STATUS_CANCELED) {
879 $statusType = 'status6';
880 }
881
882 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
883 */
884 }
885
892 public function info($id)
893 {
894 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
895 $sql .= ' fk_user_creat, fk_user_modif';
896 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
897 $sql .= ' WHERE t.rowid = '.((int) $id);
898 $result = $this->db->query($sql);
899 if ($result) {
900 if ($this->db->num_rows($result)) {
901 $obj = $this->db->fetch_object($result);
902
903 $this->id = $obj->rowid;
904
905 $this->user_creation_id = $obj->fk_user_creat;
906 $this->user_modification_id = $obj->fk_user_modif;
907 $this->date_creation = $this->db->jdate($obj->datec);
908 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
909 }
910
911 $this->db->free($result);
912 } else {
913 dol_print_error($this->db);
914 }
915 }
916
923 public function initAsSpecimen()
924 {
925 // Set here init that are not commonf fields
926 // $this->property1 = ...
927 // $this->property2 = ...
928
929 return $this->initAsSpecimenCommon();
930 }
931
937 public function getLinesArray()
938 {
939 $this->lines = array();
940
941 $objectline = new JobLine($this->db);
942 $result = $objectline->fetchAll('ASC', 'position', 0, 0, '(fk_job:=:'.((int) $this->id).')');
943
944 if (is_numeric($result)) {
945 $this->setErrorsFromObject($objectline);
946 return $result;
947 } else {
948 $this->lines = $result;
949 return $this->lines;
950 }
951 }
952
958 public function getNextNumRef()
959 {
960 global $langs, $conf;
961 $langs->load("hrm");
962
963 if (!getDolGlobalString('hrm_JOB_ADDON')) {
964 $conf->global->hrm_JOB_ADDON = 'mod_job_standard';
965 }
966
967 if (getDolGlobalString('hrm_JOB_ADDON')) {
968 $mybool = false;
969
970 $file = getDolGlobalString('hrm_JOB_ADDON') . ".php";
971 $classname = getDolGlobalString('hrm_JOB_ADDON');
972
973 // Include file with class
974 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
975 foreach ($dirmodels as $reldir) {
976 $dir = dol_buildpath($reldir."core/modules/hrm/");
977
978 // Load file with numbering class (if found)
979 $mybool = ((bool) @include_once $dir.$file) || $mybool;
980 }
981
982 if (!$mybool) {
983 dol_print_error(null, "Failed to include file ".$file);
984 return '';
985 }
986
987 if (class_exists($classname)) {
988 $obj = new $classname();
989 '@phan-var-force ModeleNumRefEvaluation $obj';
990 $numref = $obj->getNextValue($this);
991
992 if ($numref != '' && $numref != '-1') {
993 return $numref;
994 } else {
995 $this->error = $obj->error;
996 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
997 return "";
998 }
999 } else {
1000 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
1001 return "";
1002 }
1003 } else {
1004 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1005 return "";
1006 }
1007 }
1008
1020 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1021 {
1022 global $conf, $langs;
1023
1024 $result = 0;
1025 $includedocgeneration = 0;
1026
1027 $langs->load("hrm");
1028
1029 if (!dol_strlen($modele)) {
1030 $modele = 'standard_job';
1031
1032 if (!empty($this->model_pdf)) {
1033 $modele = $this->model_pdf;
1034 } elseif (getDolGlobalString('JOB_ADDON_PDF')) {
1035 $modele = getDolGlobalString('JOB_ADDON_PDF');
1036 }
1037 }
1038
1039 $modelpath = "core/modules/hrm/doc/";
1040
1041 if ($includedocgeneration && !empty($modele)) {
1042 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1043 }
1044
1045 return $result;
1046 }
1047
1055 public function getKanbanView($option = '', $arraydata = null)
1056 {
1057 global $selected, $langs;
1058
1059 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1060
1061 $return = '<div class="box-flex-item box-flex-grow-zero">';
1062 $return .= '<div class="info-box info-box-sm">';
1063 $return .= '<span class="info-box-icon bg-infobox-action">';
1064 $return .= img_picto('', $this->picto);
1065 $return .= '</span>';
1066 $return .= '<div class="info-box-content">';
1067 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(0) : $this->ref).'</span>';
1068 if ($selected >= 0) {
1069 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1070 }
1071 /*if (property_exists($this, 'deplacement')) {
1072 $return .= '<br><span class="opacitymedium">'.$langs->trans("Type").'</span>';
1073 $return .= ' : <span class="info-box-label ">'.$this->fields['deplacement']['arrayofkeyval'][$this->deplacement].'</span>';
1074 }*/
1075 if (property_exists($this, 'description') && !(empty($this->description))) {
1076 //$return .= '<br><span class="info-box-label opacitymedium">'.$langs->trans("Description").'</span> : ';
1077 $return .= '<br><span class="info-box-label ">'.(strlen($this->description) > 30 ? dol_substr($this->description, 0, 25).'...' : $this->description).'</span>';
1078 }
1079 $return .= '</div>';
1080 $return .= '</div>';
1081 $return .= '</div>';
1082 return $return;
1083 }
1084
1090 public function getSkillRankForJob($id)
1091 {
1092 if (empty($id)) {
1093 return -1;
1094 }
1095 $skillranks = array();
1096 $sql = "SELECT rowid";
1097 $sql .= " FROM ".MAIN_DB_PREFIX."hrm_skillrank";
1098 $sql .= " WHERE fk_object = ".((int) $id);
1099
1100 $resql = $this->db->query($sql);
1101 if ($resql) {
1102 $num = $this->db->num_rows($resql);
1103 $i = 0;
1104 while ($i < $num) {
1105 $obj = $this->db->fetch_object($resql);
1106 $skillranks[] = $obj;
1107 $i++;
1108 }
1109 $this->db->free($resql);
1110 } else {
1111 dol_print_error($this->db);
1112 }
1113 return $skillranks;
1114 }
1115}
1116
1117
1118require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1119
1124{
1125 // To complete with content of an object JobLine
1126 // We should have a field rowid, fk_job and position
1127
1133 public function __construct(DoliDB $db)
1134 {
1135 $this->db = $db;
1136
1137 $this->isextrafieldmanaged = 0;
1138 }
1139}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:67
$object ref
Definition info.php:90
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 job occupied by 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 jobs occupied by 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_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)
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (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_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0)
Clean a string to use it as a file name.
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