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