dolibarr 20.0.0
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 );
107 public $rowid;
108 public $ref;
109 public $label;
110 public $description;
111 public $date_creation;
112
113 public $deplacement;
114 public $fk_user_creat;
115 public $fk_user_modif;
116 // END MODULEBUILDER PROPERTIES
117
118
119 // If this object has a subtable with lines
120
121 // /**
122 // * @var string Name of subtable line
123 // */
124 // public $table_element_line = 'hrm_jobline';
125
129 public $fk_element = 'fk_job';
130
131 // /**
132 // * @var string Name of subtable class that manage subtable lines
133 // */
134 // public $class_element_line = 'Jobline';
135
139 protected $childtables = array(
140 'hrm_evaluation' => ['name' => 'Evaluation'],
141 'hrm_job_user' => ['name' => 'Job'],
142 );
143
149 protected $childtablesoncascade = array("@SkillRank:hrm/class/skillrank.class.php:fk_object:(objecttype:=:'job')");
150
151 // /**
152 // * @var JobLine[] Array of subtable lines
153 // */
154 // public $lines = array();
155
156
157
163 public function __construct(DoliDB $db)
164 {
165 global $conf, $langs;
166
167 $this->db = $db;
168
169 $this->ismultientitymanaged = 0;
170 $this->isextrafieldmanaged = 1;
171
172 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
173 $this->fields['rowid']['visible'] = 0;
174 }
175 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
176 $this->fields['entity']['enabled'] = 0;
177 }
178
179 // Example to show how to set values of fields definition dynamically
180 /*if ($user->rights->hrm->job->read) {
181 $this->fields['myfield']['visible'] = 1;
182 $this->fields['myfield']['noteditable'] = 0;
183 }*/
184
185 // Unset fields that are disabled
186 foreach ($this->fields as $key => $val) {
187 if (isset($val['enabled']) && empty($val['enabled'])) {
188 unset($this->fields[$key]);
189 }
190 }
191
192 // Translate some data of arrayofkeyval
193 if (is_object($langs)) {
194 foreach ($this->fields as $key => $val) {
195 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
196 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
197 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
198 }
199 }
200 }
201 }
202 }
203
211 public function create(User $user, $notrigger = 0)
212 {
213 $resultcreate = $this->createCommon($user, $notrigger);
214
215 //$resultvalidate = $this->validate($user, $notrigger);
216
217 return $resultcreate;
218 }
219
227 public function createFromClone(User $user, $fromid)
228 {
229 global $langs, $extrafields;
230 $error = 0;
231
232 dol_syslog(__METHOD__, LOG_DEBUG);
233
234 $object = new self($this->db);
235
236 $this->db->begin();
237
238 // Load source object
239 $result = $object->fetchCommon($fromid);
240 if ($result > 0 && !empty($object->table_element_line)) {
241 $object->fetchLines();
242 }
243
244 // get lines so they will be clone
245 //foreach($this->lines as $line)
246 // $line->fetch_optionals();
247
248 // Reset some properties
249 unset($object->id);
250 unset($object->fk_user_creat);
251 unset($object->import_key);
252
253 // Clear fields
254 if (property_exists($object, 'ref')) {
255 $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
256 }
257 if (property_exists($object, 'label')) {
258 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
259 }
260 if (property_exists($object, 'status')) {
261 $object->status = self::STATUS_DRAFT;
262 }
263 if (property_exists($object, 'date_creation')) {
264 $object->date_creation = dol_now();
265 }
266 if (property_exists($object, 'date_modification')) {
267 $object->date_modification = null;
268 }
269 // ...
270 // Clear extrafields that are unique
271 if (is_array($object->array_options) && count($object->array_options) > 0) {
272 $extrafields->fetch_name_optionals_label($this->table_element);
273 foreach ($object->array_options as $key => $option) {
274 $shortkey = preg_replace('/options_/', '', $key);
275 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
276 //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
277 unset($object->array_options[$key]);
278 }
279 }
280 }
281
282 // Create clone
283 $object->context['createfromclone'] = 'createfromclone';
284 $result = $object->createCommon($user);
285 if ($result < 0) {
286 $error++;
288 }
289
290 if (!$error) {
291 // copy internal contacts
292 if ($this->copy_linked_contact($object, 'internal') < 0) {
293 $error++;
294 }
295 }
296
297 if (!$error) {
298 // copy external contacts if same company
299 if (property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
300 if ($this->copy_linked_contact($object, 'external') < 0) {
301 $error++;
302 }
303 }
304 }
305
306 unset($object->context['createfromclone']);
307
308 // End
309 if (!$error) {
310 $this->db->commit();
311 return $object;
312 } else {
313 $this->db->rollback();
314 return -1;
315 }
316 }
317
325 public function fetch($id, $ref = null)
326 {
327 $result = $this->fetchCommon($id, $ref);
328 if ($result > 0 && !empty($this->table_element_line)) {
329 $this->fetchLines();
330 }
331 return $result;
332 }
333
339 public function fetchLines()
340 {
341 $this->lines = array();
342
343 $result = $this->fetchLinesCommon();
344 return $result;
345 }
346
347
360 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
361 {
362 dol_syslog(__METHOD__, LOG_DEBUG);
363
364 $records = array();
365
366 $sql = 'SELECT ';
367 $sql .= $this->getFieldList('t');
368 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
369 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
370 $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
371 } else {
372 $sql .= ' WHERE 1 = 1';
373 }
374
375 // Manage filter
376 $errormessage = '';
377 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
378 if ($errormessage) {
379 $this->errors[] = $errormessage;
380 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
381 return -1;
382 }
383
384 if (!empty($sortfield)) {
385 $sql .= $this->db->order($sortfield, $sortorder);
386 }
387 if (!empty($limit)) {
388 $sql .= ' '.$this->db->plimit($limit, $offset);
389 }
390
391 $resql = $this->db->query($sql);
392 if ($resql) {
393 $num = $this->db->num_rows($resql);
394 $i = 0;
395 while ($i < ($limit ? min($limit, $num) : $num)) {
396 $obj = $this->db->fetch_object($resql);
397
398 $record = new self($this->db);
399 $record->setVarsFromFetchObj($obj);
400
401 $records[$record->id] = $record;
402
403 $i++;
404 }
405 $this->db->free($resql);
406
407 return $records;
408 } else {
409 $this->errors[] = 'Error '.$this->db->lasterror();
410 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
411
412 return -1;
413 }
414 }
415
423 public function update(User $user, $notrigger = 0)
424 {
425 return $this->updateCommon($user, $notrigger);
426 }
427
435 public function delete(User $user, $notrigger = 0)
436 {
437 return $this->deleteCommon($user, $notrigger);
438 //return $this->deleteCommon($user, $notrigger, 1);
439 }
440
449 public function deleteLine(User $user, $idline, $notrigger = 0)
450 {
451 if ($this->status < 0) {
452 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
453 return -2;
454 }
455
456 return $this->deleteLineCommon($user, $idline, $notrigger);
457 }
458
459
467 public function validate($user, $notrigger = 0)
468 {
469 global $conf, $langs;
470
471 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
472
473 $error = 0;
474
475 // Protection
476 if ($this->status == self::STATUS_VALIDATED) {
477 dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
478 return 0;
479 }
480
481 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->job->write))
482 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->job->job_advance->validate))))
483 {
484 $this->error='NotEnoughPermissions';
485 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
486 return -1;
487 }*/
488
489 $now = dol_now();
490
491 $this->db->begin();
492
493 // Define new ref
494 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
495 $num = $this->getNextNumRef();
496 } else {
497 $num = $this->ref;
498 }
499 $this->newref = $num;
500
501 if (!empty($num)) {
502 // Validate
503 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
504 $sql .= " SET ref = '".$this->db->escape($num)."',";
505 $sql .= " status = ".self::STATUS_VALIDATED;
506 if (!empty($this->fields['date_validation'])) {
507 $sql .= ", date_validation = '".$this->db->idate($now)."'";
508 }
509 if (!empty($this->fields['fk_user_valid'])) {
510 $sql .= ", fk_user_valid = ".((int) $user->id);
511 }
512 $sql .= " WHERE rowid = ".((int) $this->id);
513
514 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
515 $resql = $this->db->query($sql);
516 if (!$resql) {
517 dol_print_error($this->db);
518 $this->error = $this->db->lasterror();
519 $error++;
520 }
521
522 if (!$error && !$notrigger) {
523 // Call trigger
524 $result = $this->call_trigger('HRM_JOB_VALIDATE', $user);
525 if ($result < 0) {
526 $error++;
527 }
528 // End call triggers
529 }
530 }
531
532 if (!$error) {
533 $this->oldref = $this->ref;
534
535 // Rename directory if dir was a temporary ref
536 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
537 // Now we rename also files into index
538 $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)."'";
539 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'job/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
540 $resql = $this->db->query($sql);
541 if (!$resql) {
542 $error++;
543 $this->error = $this->db->lasterror();
544 }
545 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'job/".$this->db->escape($this->newref)."'";
546 $sql .= " WHERE filepath = 'job/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
547 $resql = $this->db->query($sql);
548 if (!$resql) {
549 $error++;
550 $this->error = $this->db->lasterror();
551 }
552
553 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
554 $oldref = dol_sanitizeFileName($this->ref);
555 $newref = dol_sanitizeFileName($num);
556 $dirsource = $conf->hrm->dir_output.'/job/'.$oldref;
557 $dirdest = $conf->hrm->dir_output.'/job/'.$newref;
558 if (!$error && file_exists($dirsource)) {
559 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
560
561 if (@rename($dirsource, $dirdest)) {
562 dol_syslog("Rename ok");
563 // Rename docs starting with $oldref with $newref
564 $listoffiles = dol_dir_list($conf->hrm->dir_output.'/job/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
565 foreach ($listoffiles as $fileentry) {
566 $dirsource = $fileentry['name'];
567 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
568 $dirsource = $fileentry['path'].'/'.$dirsource;
569 $dirdest = $fileentry['path'].'/'.$dirdest;
570 @rename($dirsource, $dirdest);
571 }
572 }
573 }
574 }
575 }
576
577 // Set new ref and current status
578 if (!$error) {
579 $this->ref = $num;
580 $this->status = self::STATUS_VALIDATED;
581 }
582
583 if (!$error) {
584 $this->db->commit();
585 return 1;
586 } else {
587 $this->db->rollback();
588 return -1;
589 }
590 }
591
598 public function getLastJobForUser($fk_user)
599 {
600 $Tab = $this->getForUser($fk_user);
601
602 if (empty($Tab)) {
603 return '';
604 }
605
606 $lastpos = array_shift($Tab);
607
608 return $lastpos;
609 }
610
617 public function getForUser($userid)
618 {
619 global $db;
620
621 $TReturn = array();
622 $position = new Position($db);
623 $TPosition = $position->getForUser($userid);
624 foreach ($TPosition as $UPosition) {
625 $TReturn[$UPosition->Job->rowid] = $UPosition->Job->ref;
626 }
627 return $TReturn;
628 }
629
637 public function setDraft($user, $notrigger = 0)
638 {
639 // Protection
640 if ($this->status <= self::STATUS_DRAFT) {
641 return 0;
642 }
643
644 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
645 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
646 {
647 $this->error='Permission denied';
648 return -1;
649 }*/
650
651 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'JOB_UNVALIDATE');
652 }
653
661 public function cancel($user, $notrigger = 0)
662 {
663 // Protection
664 if ($this->status != self::STATUS_VALIDATED) {
665 return 0;
666 }
667
668 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
669 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
670 {
671 $this->error='Permission denied';
672 return -1;
673 }*/
674
675 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'JOB_CANCEL');
676 }
677
685 public function reopen($user, $notrigger = 0)
686 {
687 // Protection
688 if ($this->status != self::STATUS_CANCELED) {
689 return 0;
690 }
691
692 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
693 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
694 {
695 $this->error='Permission denied';
696 return -1;
697 }*/
698
699 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'JOB_REOPEN');
700 }
701
712 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
713 {
714 global $conf, $langs, $hookmanager;
715
716 if (!empty($conf->dol_no_mouse_hover)) {
717 $notooltip = 1; // Force disable tooltips
718 }
719
720 $result = '';
721
722 $label = img_picto('', $this->picto).' <u>'.$langs->trans("JobProfile").'</u>';
723 if (isset($this->status)) {
724 $label .= ' '.$this->getLibStatut(5);
725 }
726 $label .= '<br>';
727 $label .= '<b>'.$langs->trans('Label').':</b> '.$this->label;
728
729 $url = dol_buildpath('/hrm/job_card.php', 1).'?id='.$this->id;
730
731 if ($option != 'nolink') {
732 // Add param to save lastsearch_values or not
733 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
734 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
735 $add_save_lastsearch_values = 1;
736 }
737 if ($add_save_lastsearch_values) {
738 $url .= '&save_lastsearch_values=1';
739 }
740 }
741
742 $linkclose = '';
743 if (empty($notooltip)) {
744 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
745 $label = $langs->trans("ShowJob");
746 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
747 }
748 $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
749 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
750 } else {
751 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
752 }
753
754 if ($option == 'nolink') {
755 $linkstart = '<span';
756 } else {
757 $linkstart = '<a href="'.$url.'"';
758 }
759 $linkstart .= $linkclose.'>';
760 if ($option == 'nolink') {
761 $linkend = '</span>';
762 } else {
763 $linkend = '</a>';
764 }
765
766 $result .= $linkstart;
767
768 if (empty($this->showphoto_on_popup)) {
769 if ($withpicto) {
770 $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);
771 }
772 } else {
773 if ($withpicto) {
774 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
775
776 list($class, $module) = explode('@', $this->picto);
777 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->label);
778 $filearray = dol_dir_list($upload_dir, "files");
779 $filename = $filearray[0]['name'];
780 if (!empty($filename)) {
781 $pospoint = strpos($filearray[0]['name'], '.');
782
783 $pathtophoto = $class.'/'.$this->label.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
784 if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
785 $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>';
786 } else {
787 $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>';
788 }
789
790 $result .= '</div>';
791 } else {
792 $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);
793 }
794 }
795 }
796
797 if ($withpicto != 2) {
798 $result .= $this->label;
799 }
800
801 $result .= $linkend;
802 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
803
804 global $action, $hookmanager;
805 $hookmanager->initHooks(array('jobdao'));
806 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
807 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
808 if ($reshook > 0) {
809 $result = $hookmanager->resPrint;
810 } else {
811 $result .= $hookmanager->resPrint;
812 }
813
814 return $result;
815 }
816
823 public function getLibStatut($mode = 0)
824 {
825 return $this->LibStatut($this->status, $mode);
826 }
827
828 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
836 public function LibStatut($status, $mode = 0)
837 {
838 // phpcs:enable
839 return ''; // There is no status on job profile for the moment
840
841 /*
842 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
843 global $langs;
844 //$langs->load("hrm");
845 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
846 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
847 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
848 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
849 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
850 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
851 }
852
853 $statusType = 'status'.$status;
854 //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
855 if ($status == self::STATUS_CANCELED) {
856 $statusType = 'status6';
857 }
858
859 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
860 */
861 }
862
869 public function info($id)
870 {
871 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
872 $sql .= ' fk_user_creat, fk_user_modif';
873 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
874 $sql .= ' WHERE t.rowid = '.((int) $id);
875 $result = $this->db->query($sql);
876 if ($result) {
877 if ($this->db->num_rows($result)) {
878 $obj = $this->db->fetch_object($result);
879
880 $this->id = $obj->rowid;
881
882 $this->user_creation_id = $obj->fk_user_creat;
883 $this->user_modification_id = $obj->fk_user_modif;
884 $this->date_creation = $this->db->jdate($obj->datec);
885 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
886 }
887
888 $this->db->free($result);
889 } else {
890 dol_print_error($this->db);
891 }
892 }
893
900 public function initAsSpecimen()
901 {
902 // Set here init that are not commonf fields
903 // $this->property1 = ...
904 // $this->property2 = ...
905
906 return $this->initAsSpecimenCommon();
907 }
908
914 public function getLinesArray()
915 {
916 $this->lines = array();
917
918 $objectline = new JobLine($this->db);
919 $result = $objectline->fetchAll('ASC', 'position', 0, 0, '(fk_job:=:'.((int) $this->id).')');
920
921 if (is_numeric($result)) {
922 $this->setErrorsFromObject($objectline);
923 return $result;
924 } else {
925 $this->lines = $result;
926 return $this->lines;
927 }
928 }
929
935 public function getNextNumRef()
936 {
937 global $langs, $conf;
938 $langs->load("hrm");
939
940 if (!getDolGlobalString('hrm_JOB_ADDON')) {
941 $conf->global->hrm_JOB_ADDON = 'mod_job_standard';
942 }
943
944 if (getDolGlobalString('hrm_JOB_ADDON')) {
945 $mybool = false;
946
947 $file = getDolGlobalString('hrm_JOB_ADDON') . ".php";
948 $classname = getDolGlobalString('hrm_JOB_ADDON');
949
950 // Include file with class
951 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
952 foreach ($dirmodels as $reldir) {
953 $dir = dol_buildpath($reldir."core/modules/hrm/");
954
955 // Load file with numbering class (if found)
956 $mybool = ((bool) @include_once $dir.$file) || $mybool;
957 }
958
959 if ($mybool === false) {
960 dol_print_error(null, "Failed to include file ".$file);
961 return '';
962 }
963
964 if (class_exists($classname)) {
965 $obj = new $classname();
966 $numref = $obj->getNextValue($this);
967
968 if ($numref != '' && $numref != '-1') {
969 return $numref;
970 } else {
971 $this->error = $obj->error;
972 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
973 return "";
974 }
975 } else {
976 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
977 return "";
978 }
979 } else {
980 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
981 return "";
982 }
983 }
984
996 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
997 {
998 global $conf, $langs;
999
1000 $result = 0;
1001 $includedocgeneration = 0;
1002
1003 $langs->load("hrm");
1004
1005 if (!dol_strlen($modele)) {
1006 $modele = 'standard_job';
1007
1008 if (!empty($this->model_pdf)) {
1009 $modele = $this->model_pdf;
1010 } elseif (getDolGlobalString('JOB_ADDON_PDF')) {
1011 $modele = getDolGlobalString('JOB_ADDON_PDF');
1012 }
1013 }
1014
1015 $modelpath = "core/modules/hrm/doc/";
1016
1017 if ($includedocgeneration && !empty($modele)) {
1018 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1019 }
1020
1021 return $result;
1022 }
1023
1031 public function getKanbanView($option = '', $arraydata = null)
1032 {
1033 global $selected, $langs;
1034
1035 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1036
1037 $return = '<div class="box-flex-item box-flex-grow-zero">';
1038 $return .= '<div class="info-box info-box-sm">';
1039 $return .= '<span class="info-box-icon bg-infobox-action">';
1040 $return .= img_picto('', $this->picto);
1041 $return .= '</span>';
1042 $return .= '<div class="info-box-content">';
1043 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(0) : $this->ref).'</span>';
1044 if ($selected >= 0) {
1045 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1046 }
1047 /*if (property_exists($this, 'deplacement')) {
1048 $return .= '<br><span class="opacitymedium">'.$langs->trans("Type").'</span>';
1049 $return .= ' : <span class="info-box-label ">'.$this->fields['deplacement']['arrayofkeyval'][$this->deplacement].'</span>';
1050 }*/
1051 if (property_exists($this, 'description') && !(empty($this->description))) {
1052 //$return .= '<br><span class="info-box-label opacitymedium">'.$langs->trans("Description").'</span> : ';
1053 $return .= '<br><span class="info-box-label ">'.(strlen($this->description) > 30 ? dol_substr($this->description, 0, 25).'...' : $this->description).'</span>';
1054 }
1055 $return .= '</div>';
1056 $return .= '</div>';
1057 $return .= '</div>';
1058 return $return;
1059 }
1060
1066 public function getSkillRankForJob($id)
1067 {
1068 if (empty($id)) {
1069 return -1;
1070 }
1071 $skillranks = array();
1072 $sql = "SELECT rowid";
1073 $sql .= " FROM ".MAIN_DB_PREFIX."hrm_skillrank";
1074 $sql .= " WHERE fk_object = ".((int) $id);
1075
1076 $resql = $this->db->query($sql);
1077 if ($resql) {
1078 $num = $this->db->num_rows($resql);
1079 $i = 0;
1080 while ($i < $num) {
1081 $obj = $this->db->fetch_object($resql);
1082 $skillranks[] = $obj;
1083 $i++;
1084 }
1085 $this->db->free($resql);
1086 } else {
1087 dol_print_error($this->db);
1088 }
1089 return $skillranks;
1090 }
1091}
1092
1093
1094require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1095
1100{
1101 // To complete with content of an object JobLine
1102 // We should have a field rowid, fk_job and position
1103
1109 public function __construct(DoliDB $db)
1110 {
1111 $this->db = $db;
1112
1113 $this->isextrafieldmanaged = 0;
1114 }
1115}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition security.php:636
$object ref
Definition info.php:79
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 clicable 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 $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 dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.