dolibarr 19.0.3
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 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
28// Put here all includes required by your class file
29require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
30//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php';
31//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php';
32
36class Job extends CommonObject
37{
41 public $module = 'hrm';
42
46 public $element = 'job';
47
51 public $table_element = 'hrm_job';
52
57 public $ismultientitymanaged = 0;
58
62 public $isextrafieldmanaged = 1;
63
67 public $picto = 'technic';
68
69
70 const STATUS_DRAFT = 0;
71 const STATUS_VALIDATED = 1;
72 const STATUS_CANCELED = 9;
73
74
101 // BEGIN MODULEBUILDER PROPERTIES
105 public $fields=array(
106 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"),
107 '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"),
108 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>21, 'notnull'=>0, 'visible'=>1,),
109 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>2,),
110 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>2,),
111 'deplacement' => array('type'=>'select', 'required'=> 1,'label'=> 'NeedBusinessTravels', 'enabled'=> 1, 'position'=> 90, 'notnull'=> 1, 'visible'=> 1, 'arrayofkeyval'=> array(0 =>"No", 1=>"Yes"), 'default'=>0),
112 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>70, 'notnull'=>0, 'visible'=>0,),
113 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>71, 'notnull'=>0, 'visible'=>0,),
114 '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',),
115 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,),
116 );
117 public $rowid;
118 public $ref;
119 public $label;
120 public $description;
121 public $date_creation;
122 public $tms;
123 public $deplacement;
124 public $note_public;
125 public $note_private;
126 public $fk_user_creat;
127 public $fk_user_modif;
128 // END MODULEBUILDER PROPERTIES
129
130
131 // If this object has a subtable with lines
132
133 // /**
134 // * @var string Name of subtable line
135 // */
136 // public $table_element_line = 'hrm_jobline';
137
138 // /**
139 // * @var string Field with ID of parent key if this object has a parent
140 // */
141 public $fk_element = 'fk_job';
142
143 // /**
144 // * @var string Name of subtable class that manage subtable lines
145 // */
146 // public $class_element_line = 'Jobline';
147
148 // /**
149 // * @var array List of child tables. To test if we can delete object.
150 // */
151 protected $childtables = array('hrm_evaluation', 'hrm_job_user');
152
153 // /**
154 // * @var array List of child tables. To know object to delete on cascade.
155 // * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will
156 // * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object
157 // */
158 protected $childtablesoncascade = array("@SkillRank:hrm/class/skillrank.class.php:fk_object:objecttype='job'");
159
160 // /**
161 // * @var JobLine[] Array of subtable lines
162 // */
163 // public $lines = array();
164
165
166
172 public function __construct(DoliDB $db)
173 {
174 global $conf, $langs;
175
176 $this->db = $db;
177
178 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
179 $this->fields['rowid']['visible'] = 0;
180 }
181 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
182 $this->fields['entity']['enabled'] = 0;
183 }
184
185 // Example to show how to set values of fields definition dynamically
186 /*if ($user->rights->hrm->job->read) {
187 $this->fields['myfield']['visible'] = 1;
188 $this->fields['myfield']['noteditable'] = 0;
189 }*/
190
191 // Unset fields that are disabled
192 foreach ($this->fields as $key => $val) {
193 if (isset($val['enabled']) && empty($val['enabled'])) {
194 unset($this->fields[$key]);
195 }
196 }
197
198 // Translate some data of arrayofkeyval
199 if (is_object($langs)) {
200 foreach ($this->fields as $key => $val) {
201 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
202 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
203 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
204 }
205 }
206 }
207 }
208 }
209
217 public function create(User $user, $notrigger = false)
218 {
219 $resultcreate = $this->createCommon($user, $notrigger);
220
221 //$resultvalidate = $this->validate($user, $notrigger);
222
223 return $resultcreate;
224 }
225
233 public function createFromClone(User $user, $fromid)
234 {
235 global $langs, $extrafields;
236 $error = 0;
237
238 dol_syslog(__METHOD__, LOG_DEBUG);
239
240 $object = new self($this->db);
241
242 $this->db->begin();
243
244 // Load source object
245 $result = $object->fetchCommon($fromid);
246 if ($result > 0 && !empty($object->table_element_line)) {
247 $object->fetchLines();
248 }
249
250 // get lines so they will be clone
251 //foreach($this->lines as $line)
252 // $line->fetch_optionals();
253
254 // Reset some properties
255 unset($object->id);
256 unset($object->fk_user_creat);
257 unset($object->import_key);
258
259 // Clear fields
260 if (property_exists($object, 'ref')) {
261 $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
262 }
263 if (property_exists($object, 'label')) {
264 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default'];
265 }
266 if (property_exists($object, 'status')) {
267 $object->status = self::STATUS_DRAFT;
268 }
269 if (property_exists($object, 'date_creation')) {
270 $object->date_creation = dol_now();
271 }
272 if (property_exists($object, 'date_modification')) {
273 $object->date_modification = null;
274 }
275 // ...
276 // Clear extrafields that are unique
277 if (is_array($object->array_options) && count($object->array_options) > 0) {
278 $extrafields->fetch_name_optionals_label($this->table_element);
279 foreach ($object->array_options as $key => $option) {
280 $shortkey = preg_replace('/options_/', '', $key);
281 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
282 //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
283 unset($object->array_options[$key]);
284 }
285 }
286 }
287
288 // Create clone
289 $object->context['createfromclone'] = 'createfromclone';
290 $result = $object->createCommon($user);
291 if ($result < 0) {
292 $error++;
293 $this->error = $object->error;
294 $this->errors = $object->errors;
295 }
296
297 if (!$error) {
298 // copy internal contacts
299 if ($this->copy_linked_contact($object, 'internal') < 0) {
300 $error++;
301 }
302 }
303
304 if (!$error) {
305 // copy external contacts if same company
306 if (property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
307 if ($this->copy_linked_contact($object, 'external') < 0) {
308 $error++;
309 }
310 }
311 }
312
313 unset($object->context['createfromclone']);
314
315 // End
316 if (!$error) {
317 $this->db->commit();
318 return $object;
319 } else {
320 $this->db->rollback();
321 return -1;
322 }
323 }
324
332 public function fetch($id, $ref = null)
333 {
334 $result = $this->fetchCommon($id, $ref);
335 if ($result > 0 && !empty($this->table_element_line)) {
336 $this->fetchLines();
337 }
338 return $result;
339 }
340
346 public function fetchLines()
347 {
348 $this->lines = array();
349
350 $result = $this->fetchLinesCommon();
351 return $result;
352 }
353
354
366 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
367 {
368 global $conf;
369
370 dol_syslog(__METHOD__, LOG_DEBUG);
371
372 $records = array();
373
374 $sql = 'SELECT ';
375 $sql .= $this->getFieldList('t');
376 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
377 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
378 $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
379 } else {
380 $sql .= ' WHERE 1 = 1';
381 }
382 // Manage filter
383 $sqlwhere = array();
384 if (count($filter) > 0) {
385 foreach ($filter as $key => $value) {
386 if ($key == 't.rowid') {
387 $sqlwhere[] = $key.'='.$value;
388 } elseif (array_key_exists($key, $this->fields) && in_array($this->fields[$key]['type'], array('date', 'datetime', 'timestamp'))) {
389 $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\'';
390 } elseif ($key == 'customsql') {
391 $sqlwhere[] = $value;
392 } elseif (strpos($value, '%') === false) {
393 $sqlwhere[] = $key.' IN ('.$this->db->sanitize($this->db->escape($value)).')';
394 } else {
395 $sqlwhere[] = $key.' LIKE \'%'.$this->db->escape($value).'%\'';
396 }
397 }
398 }
399 if (count($sqlwhere) > 0) {
400 $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")";
401 }
402
403 if (!empty($sortfield)) {
404 $sql .= $this->db->order($sortfield, $sortorder);
405 }
406 if (!empty($limit)) {
407 $sql .= ' '.$this->db->plimit($limit, $offset);
408 }
409
410 $resql = $this->db->query($sql);
411 if ($resql) {
412 $num = $this->db->num_rows($resql);
413 $i = 0;
414 while ($i < ($limit ? min($limit, $num) : $num)) {
415 $obj = $this->db->fetch_object($resql);
416
417 $record = new self($this->db);
418 $record->setVarsFromFetchObj($obj);
419
420 $records[$record->id] = $record;
421
422 $i++;
423 }
424 $this->db->free($resql);
425
426 return $records;
427 } else {
428 $this->errors[] = 'Error '.$this->db->lasterror();
429 dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
430
431 return -1;
432 }
433 }
434
442 public function update(User $user, $notrigger = false)
443 {
444 return $this->updateCommon($user, $notrigger);
445 }
446
454 public function delete(User $user, $notrigger = false)
455 {
456 return $this->deleteCommon($user, $notrigger);
457 //return $this->deleteCommon($user, $notrigger, 1);
458 }
459
468 public function deleteLine(User $user, $idline, $notrigger = false)
469 {
470 if ($this->status < 0) {
471 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
472 return -2;
473 }
474
475 return $this->deleteLineCommon($user, $idline, $notrigger);
476 }
477
478
486 public function validate($user, $notrigger = 0)
487 {
488 global $conf, $langs;
489
490 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
491
492 $error = 0;
493
494 // Protection
495 if ($this->status == self::STATUS_VALIDATED) {
496 dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING);
497 return 0;
498 }
499
500 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->job->write))
501 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->job->job_advance->validate))))
502 {
503 $this->error='NotEnoughPermissions';
504 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
505 return -1;
506 }*/
507
508 $now = dol_now();
509
510 $this->db->begin();
511
512 // Define new ref
513 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
514 $num = $this->getNextNumRef();
515 } else {
516 $num = $this->ref;
517 }
518 $this->newref = $num;
519
520 if (!empty($num)) {
521 // Validate
522 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
523 $sql .= " SET ref = '".$this->db->escape($num)."',";
524 $sql .= " status = ".self::STATUS_VALIDATED;
525 if (!empty($this->fields['date_validation'])) {
526 $sql .= ", date_validation = '".$this->db->idate($now)."'";
527 }
528 if (!empty($this->fields['fk_user_valid'])) {
529 $sql .= ", fk_user_valid = ".((int) $user->id);
530 }
531 $sql .= " WHERE rowid = ".((int) $this->id);
532
533 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
534 $resql = $this->db->query($sql);
535 if (!$resql) {
536 dol_print_error($this->db);
537 $this->error = $this->db->lasterror();
538 $error++;
539 }
540
541 if (!$error && !$notrigger) {
542 // Call trigger
543 $result = $this->call_trigger('HRM_JOB_VALIDATE', $user);
544 if ($result < 0) {
545 $error++;
546 }
547 // End call triggers
548 }
549 }
550
551 if (!$error) {
552 $this->oldref = $this->ref;
553
554 // Rename directory if dir was a temporary ref
555 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
556 // Now we rename also files into index
557 $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)."'";
558 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'job/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
559 $resql = $this->db->query($sql);
560 if (!$resql) {
561 $error++;
562 $this->error = $this->db->lasterror();
563 }
564 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'job/".$this->db->escape($this->newref)."'";
565 $sql .= " WHERE filepath = 'job/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
566 $resql = $this->db->query($sql);
567 if (!$resql) {
568 $error++;
569 $this->error = $this->db->lasterror();
570 }
571
572 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
573 $oldref = dol_sanitizeFileName($this->ref);
574 $newref = dol_sanitizeFileName($num);
575 $dirsource = $conf->hrm->dir_output.'/job/'.$oldref;
576 $dirdest = $conf->hrm->dir_output.'/job/'.$newref;
577 if (!$error && file_exists($dirsource)) {
578 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
579
580 if (@rename($dirsource, $dirdest)) {
581 dol_syslog("Rename ok");
582 // Rename docs starting with $oldref with $newref
583 $listoffiles = dol_dir_list($conf->hrm->dir_output.'/job/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
584 foreach ($listoffiles as $fileentry) {
585 $dirsource = $fileentry['name'];
586 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
587 $dirsource = $fileentry['path'].'/'.$dirsource;
588 $dirdest = $fileentry['path'].'/'.$dirdest;
589 @rename($dirsource, $dirdest);
590 }
591 }
592 }
593 }
594 }
595
596 // Set new ref and current status
597 if (!$error) {
598 $this->ref = $num;
599 $this->status = self::STATUS_VALIDATED;
600 }
601
602 if (!$error) {
603 $this->db->commit();
604 return 1;
605 } else {
606 $this->db->rollback();
607 return -1;
608 }
609 }
610
617 public function getLastJobForUser($fk_user)
618 {
619 $Tab = $this->getForUser($fk_user);
620
621 if (empty($Tab)) {
622 return '';
623 }
624
625 $lastpos = array_shift($Tab);
626
627 return $lastpos;
628 }
629
636 public function getForUser($userid)
637 {
638 global $db;
639
640 $TReturn = array();
641 $position = new Position($db);
642 $TPosition = $position->getForUser($userid);
643 foreach ($TPosition as $UPosition) {
644 $TReturn[$UPosition->Job->rowid] = $UPosition->Job->ref;
645 }
646 return $TReturn;
647 }
648
656 public function setDraft($user, $notrigger = 0)
657 {
658 // Protection
659 if ($this->status <= self::STATUS_DRAFT) {
660 return 0;
661 }
662
663 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
664 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
665 {
666 $this->error='Permission denied';
667 return -1;
668 }*/
669
670 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'JOB_UNVALIDATE');
671 }
672
680 public function cancel($user, $notrigger = 0)
681 {
682 // Protection
683 if ($this->status != self::STATUS_VALIDATED) {
684 return 0;
685 }
686
687 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
688 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
689 {
690 $this->error='Permission denied';
691 return -1;
692 }*/
693
694 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'JOB_CANCEL');
695 }
696
704 public function reopen($user, $notrigger = 0)
705 {
706 // Protection
707 if ($this->status != self::STATUS_CANCELED) {
708 return 0;
709 }
710
711 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
712 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
713 {
714 $this->error='Permission denied';
715 return -1;
716 }*/
717
718 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'JOB_REOPEN');
719 }
720
731 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
732 {
733 global $conf, $langs, $hookmanager;
734
735 if (!empty($conf->dol_no_mouse_hover)) {
736 $notooltip = 1; // Force disable tooltips
737 }
738
739 $result = '';
740
741 $label = img_picto('', $this->picto).' <u>'.$langs->trans("JobProfile").'</u>';
742 if (isset($this->status)) {
743 $label .= ' '.$this->getLibStatut(5);
744 }
745 $label .= '<br>';
746 $label .= '<b>'.$langs->trans('Label').':</b> '.$this->label;
747
748 $url = dol_buildpath('/hrm/job_card.php', 1).'?id='.$this->id;
749
750 if ($option != 'nolink') {
751 // Add param to save lastsearch_values or not
752 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
753 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
754 $add_save_lastsearch_values = 1;
755 }
756 if ($add_save_lastsearch_values) {
757 $url .= '&save_lastsearch_values=1';
758 }
759 }
760
761 $linkclose = '';
762 if (empty($notooltip)) {
763 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
764 $label = $langs->trans("ShowJob");
765 $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
766 }
767 $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
768 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
769 } else {
770 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
771 }
772
773 if ($option == 'nolink') {
774 $linkstart = '<span';
775 } else {
776 $linkstart = '<a href="'.$url.'"';
777 }
778 $linkstart .= $linkclose.'>';
779 if ($option == 'nolink') {
780 $linkend = '</span>';
781 } else {
782 $linkend = '</a>';
783 }
784
785 $result .= $linkstart;
786
787 if (empty($this->showphoto_on_popup)) {
788 if ($withpicto) {
789 $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);
790 }
791 } else {
792 if ($withpicto) {
793 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
794
795 list($class, $module) = explode('@', $this->picto);
796 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->label);
797 $filearray = dol_dir_list($upload_dir, "files");
798 $filename = $filearray[0]['name'];
799 if (!empty($filename)) {
800 $pospoint = strpos($filearray[0]['name'], '.');
801
802 $pathtophoto = $class.'/'.$this->label.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
803 if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
804 $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>';
805 } else {
806 $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>';
807 }
808
809 $result .= '</div>';
810 } else {
811 $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);
812 }
813 }
814 }
815
816 if ($withpicto != 2) {
817 $result .= $this->label;
818 }
819
820 $result .= $linkend;
821 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
822
823 global $action, $hookmanager;
824 $hookmanager->initHooks(array('jobdao'));
825 $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
826 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
827 if ($reshook > 0) {
828 $result = $hookmanager->resPrint;
829 } else {
830 $result .= $hookmanager->resPrint;
831 }
832
833 return $result;
834 }
835
842 public function getLibStatut($mode = 0)
843 {
844 return $this->LibStatut($this->status, $mode);
845 }
846
847 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
855 public function LibStatut($status, $mode = 0)
856 {
857 // phpcs:enable
858 return ''; // There is no status on job profile for the moment
859
860 /*
861 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
862 global $langs;
863 //$langs->load("hrm");
864 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
865 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
866 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
867 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
868 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
869 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
870 }
871
872 $statusType = 'status'.$status;
873 //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
874 if ($status == self::STATUS_CANCELED) {
875 $statusType = 'status6';
876 }
877
878 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
879 */
880 }
881
888 public function info($id)
889 {
890 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
891 $sql .= ' fk_user_creat, fk_user_modif';
892 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
893 $sql .= ' WHERE t.rowid = '.((int) $id);
894 $result = $this->db->query($sql);
895 if ($result) {
896 if ($this->db->num_rows($result)) {
897 $obj = $this->db->fetch_object($result);
898
899 $this->id = $obj->rowid;
900
901 $this->user_creation_id = $obj->fk_user_creat;
902 $this->user_modification_id = $obj->fk_user_modif;
903 $this->date_creation = $this->db->jdate($obj->datec);
904 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
905 }
906
907 $this->db->free($result);
908 } else {
909 dol_print_error($this->db);
910 }
911 }
912
919 public function initAsSpecimen()
920 {
921 // Set here init that are not commonf fields
922 // $this->property1 = ...
923 // $this->property2 = ...
924
925 $this->initAsSpecimenCommon();
926 }
927
933 public function getLinesArray()
934 {
935 $this->lines = array();
936
937 $objectline = new JobLine($this->db);
938 $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_job = '.$this->id));
939
940 if (is_numeric($result)) {
941 $this->error = $objectline->error;
942 $this->errors = $objectline->errors;
943 return $result;
944 } else {
945 $this->lines = $result;
946 return $this->lines;
947 }
948 }
949
955 public function getNextNumRef()
956 {
957 global $langs, $conf;
958 $langs->load("hrm");
959
960 if (!getDolGlobalString('hrm_JOB_ADDON')) {
961 $conf->global->hrm_JOB_ADDON = 'mod_job_standard';
962 }
963
964 if (getDolGlobalString('hrm_JOB_ADDON')) {
965 $mybool = false;
966
967 $file = getDolGlobalString('hrm_JOB_ADDON') . ".php";
968 $classname = $conf->global->hrm_JOB_ADDON;
969
970 // Include file with class
971 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
972 foreach ($dirmodels as $reldir) {
973 $dir = dol_buildpath($reldir."core/modules/hrm/");
974
975 // Load file with numbering class (if found)
976 $mybool |= @include_once $dir.$file;
977 }
978
979 if ($mybool === false) {
980 dol_print_error('', "Failed to include file ".$file);
981 return '';
982 }
983
984 if (class_exists($classname)) {
985 $obj = new $classname();
986 $numref = $obj->getNextValue($this);
987
988 if ($numref != '' && $numref != '-1') {
989 return $numref;
990 } else {
991 $this->error = $obj->error;
992 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
993 return "";
994 }
995 } else {
996 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
997 return "";
998 }
999 } else {
1000 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1001 return "";
1002 }
1003 }
1004
1016 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1017 {
1018 global $conf, $langs;
1019
1020 $result = 0;
1021 $includedocgeneration = 0;
1022
1023 $langs->load("hrm");
1024
1025 if (!dol_strlen($modele)) {
1026 $modele = 'standard_job';
1027
1028 if (!empty($this->model_pdf)) {
1029 $modele = $this->model_pdf;
1030 } elseif (getDolGlobalString('JOB_ADDON_PDF')) {
1031 $modele = $conf->global->JOB_ADDON_PDF;
1032 }
1033 }
1034
1035 $modelpath = "core/modules/hrm/doc/";
1036
1037 if ($includedocgeneration && !empty($modele)) {
1038 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1039 }
1040
1041 return $result;
1042 }
1043
1051 public function doScheduledJob()
1052 {
1053 global $conf, $langs;
1054
1055 //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1056
1057 $error = 0;
1058 $this->output = '';
1059 $this->error = '';
1060
1061 dol_syslog(__METHOD__, LOG_DEBUG);
1062
1063 $now = dol_now();
1064
1065 $this->db->begin();
1066
1067 // ...
1068
1069 $this->db->commit();
1070
1071 return $error;
1072 }
1073
1081 public function getKanbanView($option = '', $arraydata = null)
1082 {
1083 global $selected, $langs;
1084
1085 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1086
1087 $return = '<div class="box-flex-item box-flex-grow-zero">';
1088 $return .= '<div class="info-box info-box-sm">';
1089 $return .= '<span class="info-box-icon bg-infobox-action">';
1090 $return .= img_picto('', $this->picto);
1091 $return .= '</span>';
1092 $return .= '<div class="info-box-content">';
1093 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(0) : $this->ref).'</span>';
1094 if ($selected >= 0) {
1095 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1096 }
1097 /*if (property_exists($this, 'deplacement')) {
1098 $return .= '<br><span class="opacitymedium">'.$langs->trans("Type").'</span>';
1099 $return .= ' : <span class="info-box-label ">'.$this->fields['deplacement']['arrayofkeyval'][$this->deplacement].'</span>';
1100 }*/
1101 if (property_exists($this, 'description') && !(empty($this->description))) {
1102 //$return .= '<br><span class="info-box-label opacitymedium">'.$langs->trans("Description").'</span> : ';
1103 $return .= '<br><span class="info-box-label ">'.(strlen($this->description) > 30 ? dol_substr($this->description, 0, 25).'...' : $this->description).'</span>';
1104 }
1105 $return .= '</div>';
1106 $return .= '</div>';
1107 $return .= '</div>';
1108 return $return;
1109 }
1115 public function getSkillRankForJob($id)
1116 {
1117 if (empty($id)) {
1118 return -1;
1119 }
1120 $skillranks = array();
1121 $sql = "SELECT rowid";
1122 $sql .= " FROM ".MAIN_DB_PREFIX."hrm_skillrank";
1123 $sql .= " WHERE fk_object = ".((int) $id);
1124
1125 $resql = $this->db->query($sql);
1126 if ($resql) {
1127 $num = $this->db->num_rows($resql);
1128 $i = 0;
1129 while ($i < $num) {
1130 $obj = $this->db->fetch_object($resql);
1131 $skillranks[] = $obj;
1132 $i++;
1133 }
1134 $this->db->free($resql);
1135 } else {
1136 dol_print_error($this->db);
1137 }
1138 return $skillranks;
1139 }
1140}
1141
1142
1143require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1144
1149{
1150 // To complete with content of an object JobLine
1151 // We should have a field rowid, fk_job and position
1152
1156 public $isextrafieldmanaged = 0;
1157
1163 public function __construct(DoliDB $db)
1164 {
1165 $this->db = $db;
1166 }
1167}
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Definition security.php:604
$object ref
Definition info.php:79
Parent class of all other business classes (invoices, contracts, proposals, orders,...
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
deleteLineCommon(User $user, $idline, $notrigger=false)
Delete a line of object in database.
createCommon(User $user, $notrigger=false)
Create object into database.
deleteCommon(User $user, $notrigger=false, $forcechilddeletion=0)
Delete object in database.
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
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.
updateCommon(User $user, $notrigger=false)
Update object into database.
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.
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:37
doScheduledJob()
Action executed by scheduler CAN BE A CRON TASK.
update(User $user, $notrigger=false)
Update object into database.
getNextNumRef()
Returns the reference to the following non used object depending on the active numbering module.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter=array(), $filtermode='AND')
Load list of objects in memory from the database.
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.
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.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionaly the picto)
createFromClone(User $user, $fromid)
Clone an object into another one.
create(User $user, $notrigger=false)
Create object into database.
reopen($user, $notrigger=0)
Set back to validated status.
deleteLine(User $user, $idline, $notrigger=false)
Delete a line of object in database.
getSkillRankForJob($id)
function for get required skills associate to job object
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($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:62
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_now($mode='auto')
Return date for now.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
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.
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.