dolibarr 24.0.0-beta
job.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
4 * Copyright (C) 2021 Greg Rastklan <greg.rastklan@atm-consulting.fr>
5 * Copyright (C) 2021 Jean-Pascal BOUDET <jean-pascal.boudet@atm-consulting.fr>
6 * Copyright (C) 2021 Grégory BLEMAND <gregory.blemand@atm-consulting.fr>
7 * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
8 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
30// Put here all includes required by your class file
31require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
32
33
37class Job extends CommonObject
38{
42 public $module = 'hrm';
43
47 public $element = 'job';
48
52 public $table_element = 'hrm_job';
53
57 public $picto = 'technic';
58
59
60 const STATUS_DRAFT = 0;
61 const STATUS_VALIDATED = 1;
62 const STATUS_CANCELED = 9;
63
64
91 // BEGIN MODULEBUILDER PROPERTIES
95 public $fields = array(
96 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 0, 'noteditable' => 1, 'index' => 1, 'css' => 'left', 'comment' => "Id"),
97 'label' => array('type' => 'varchar(128)', 'label' => 'Label', 'enabled' => 1, 'position' => 20, 'notnull' => 1, 'visible' => 1, 'index' => 1, 'searchall' => 1, 'showoncombobox' => 1, 'comment' => "Label of object"),
98 'description' => array('type' => 'text', 'label' => 'Description', 'enabled' => 1, 'position' => 21, 'notnull' => 0, 'visible' => 1,),
99 'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'position' => 500, 'notnull' => 1, 'visible' => -2,),
100 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'position' => 501, 'notnull' => 0, 'visible' => -2,),
101 'deplacement' => array('type' => 'select', 'required' => 1,'label' => 'NeedBusinessTravels', 'enabled' => 1, 'position' => 90, 'notnull' => 1, 'visible' => 1, 'arrayofkeyval' => array(0 => "No", 1 => "Yes"), 'default' => '0'),
102 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'position' => 70, 'notnull' => 0, 'visible' => 0,),
103 'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'position' => 71, 'notnull' => 0, 'visible' => 0,),
104 'fk_user_creat' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'enabled' => 1, 'position' => 510, 'notnull' => 1, 'visible' => -2, 'foreignkey' => 'user.rowid',),
105 'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'position' => 511, 'notnull' => -1, 'visible' => -2,),
106 );
110 public $rowid;
114 public $ref;
118 public $label;
122 public $description;
126 public $deplacement;
130 public $fk_user_creat;
134 public $fk_user_modif;
135 // END MODULEBUILDER PROPERTIES
136
137
141 public $fk_element = 'fk_job';
142
146 protected $childtables = array(
147 'hrm_evaluation' => ['name' => 'Evaluation'],
148 'hrm_job_user' => ['name' => 'Job'],
149 );
150
156 protected $childtablesoncascade = array("@SkillRank:hrm/class/skillrank.class.php:fk_object:(objecttype:=:'job')");
157
158 // /**
159 // * @var JobLine[] Array of subtable lines
160 // */
161 // public $lines = array();
162
163
164
170 public function __construct(DoliDB $db)
171 {
172 global $conf, $langs;
173
174 $this->db = $db;
175
176 $this->ismultientitymanaged = 0;
177 $this->isextrafieldmanaged = 1;
178
179 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
180 $this->fields['rowid']['visible'] = 0;
181 }
182 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
183 $this->fields['entity']['enabled'] = 0;
184 }
185
186 // Example to show how to set values of fields definition dynamically
187 /*if ($user->rights->hrm->job->read) {
188 $this->fields['myfield']['visible'] = 1;
189 $this->fields['myfield']['noteditable'] = 0;
190 }*/
191
192 // Unset fields that are disabled
193 foreach ($this->fields as $key => $val) {
194 if (isset($val['enabled']) && empty($val['enabled'])) {
195 unset($this->fields[$key]);
196 }
197 }
198
199 // Translate some data of arrayofkeyval
200 if (is_object($langs)) {
201 foreach ($this->fields as $key => $val) {
202 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
203 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
204 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
205 }
206 }
207 }
208 }
209 }
210
218 public function create(User $user, $notrigger = 0)
219 {
220 $resultcreate = $this->createCommon($user, $notrigger);
221
222 //$resultvalidate = $this->validate($user, $notrigger);
223
224 return $resultcreate;
225 }
226
234 public function createFromClone(User $user, $fromid)
235 {
236 global $langs, $extrafields;
237 $error = 0;
238
239 dol_syslog(__METHOD__, LOG_DEBUG);
240
241 $object = new self($this->db);
242
243 $this->db->begin();
244
245 // Load source object
246 $result = $object->fetchCommon($fromid);
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 $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default'];
255 $object->label = $langs->trans("CopyOf")." ".$object->label;
256 $object->date_creation = dol_now();
257 $object->date_modification = null;
258
259 // Clear extrafields that are unique
260 if (is_array($object->array_options) && count($object->array_options) > 0) {
261 $extrafields->fetch_name_optionals_label($this->table_element);
262 foreach ($object->array_options as $key => $option) {
263 $shortkey = preg_replace('/options_/', '', $key);
264 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
265 unset($object->array_options[$key]);
266 }
267 }
268 }
269
270 // Create clone
271 $object->context['createfromclone'] = 'createfromclone';
272 $result = $object->createCommon($user);
273 if ($result < 0) {
274 $error++;
276 }
277
278 if (!$error) {
279 // copy internal contacts
280 if ($this->copy_linked_contact($object, 'internal') < 0) {
281 $error++;
282 }
283 }
284
285 if (!$error) {
286 // copy external contacts if same company
287 if (property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
288 if ($this->copy_linked_contact($object, 'external') < 0) {
289 $error++;
290 }
291 }
292 }
293
294 unset($object->context['createfromclone']);
295
296 // End
297 if (!$error) {
298 $this->db->commit();
299 return $object;
300 } else {
301 $this->db->rollback();
302 return -1;
303 }
304 }
305
313 public function fetch($id, $ref = null)
314 {
315 $result = $this->fetchCommon($id, $ref);
316
317 return $result;
318 }
319
325 public function fetchLines()
326 {
327 $this->lines = array();
328
329 $result = $this->fetchLinesCommon();
330 return $result;
331 }
332
333
346 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
347 {
348 dol_syslog(__METHOD__, LOG_DEBUG);
349
350 $records = array();
351
352 $sql = 'SELECT ';
353 $sql .= $this->getFieldList('t');
354 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
355 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
356 $sql .= ' WHERE t.entity IN ('.getEntity($this->element).')';
357 } else {
358 $sql .= ' WHERE 1 = 1';
359 }
360
361 // Manage filter
362 $errormessage = '';
363 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
364 if ($errormessage) {
365 $this->errors[] = $errormessage;
366 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
367 return -1;
368 }
369
370 if (!empty($sortfield)) {
371 $sql .= $this->db->order($sortfield, $sortorder);
372 }
373 if (!empty($limit)) {
374 $sql .= ' '.$this->db->plimit($limit, $offset);
375 }
376
377 $resql = $this->db->query($sql);
378 if ($resql) {
379 $num = $this->db->num_rows($resql);
380 $i = 0;
381 while ($i < ($limit ? min($limit, $num) : $num)) {
382 $obj = $this->db->fetch_object($resql);
383
384 $record = new self($this->db);
385 $record->setVarsFromFetchObj($obj);
386
387 $records[$record->id] = $record;
388
389 $i++;
390 }
391 $this->db->free($resql);
392
393 return $records;
394 } else {
395 $this->errors[] = 'Error '.$this->db->lasterror();
396 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
397
398 return -1;
399 }
400 }
401
409 public function update(User $user, $notrigger = 0)
410 {
411 return $this->updateCommon($user, $notrigger);
412 }
413
421 public function delete(User $user, $notrigger = 0)
422 {
423 return $this->deleteCommon($user, $notrigger);
424 //return $this->deleteCommon($user, $notrigger, 1);
425 }
426
435 public function deleteLine(User $user, $idline, $notrigger = 0)
436 {
437 if ($this->status < 0) {
438 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
439 return -2;
440 }
441
442 return $this->deleteLineCommon($user, $idline, $notrigger);
443 }
444
445
453 public function validate($user, $notrigger = 0)
454 {
455 global $conf, $langs;
456
457 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
458
459 $error = 0;
460
461 // Protection
462 if ($this->status == self::STATUS_VALIDATED) {
463 dol_syslog(get_class($this)."::validate action abandoned: already validated", LOG_WARNING);
464 return 0;
465 }
466
467 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->job->write))
468 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->job->job_advance->validate))))
469 {
470 $this->error='NotEnoughPermissions';
471 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
472 return -1;
473 }*/
474
475 $now = dol_now();
476
477 $this->db->begin();
478
479 // Define new ref
480 if (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref)) { // empty should not happened, but when it occurs, the test save life
481 $num = $this->getNextNumRef();
482 } else {
483 $num = (string) $this->ref;
484 }
485 $this->newref = $num;
486
487 if (!empty($num)) {
488 // Validate
489 $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
490 $sql .= " SET ref = '".$this->db->escape($num)."',";
491 $sql .= " status = ".self::STATUS_VALIDATED;
492 if (!empty($this->fields['date_validation'])) {
493 $sql .= ", date_validation = '".$this->db->idate($now)."'";
494 }
495 if (!empty($this->fields['fk_user_valid'])) { // @phan-suppress-current-line PhanTypeMismatchProperty
496 $sql .= ", fk_user_valid = ".((int) $user->id);
497 }
498 $sql .= " WHERE rowid = ".((int) $this->id);
499
500 dol_syslog(get_class($this)."::validate()", LOG_DEBUG);
501 $resql = $this->db->query($sql);
502 if (!$resql) {
503 dol_print_error($this->db);
504 $this->error = $this->db->lasterror();
505 $error++;
506 }
507
508 if (!$error && !$notrigger) {
509 // Call trigger
510 $result = $this->call_trigger('HRM_JOB_VALIDATE', $user);
511 if ($result < 0) {
512 $error++;
513 }
514 // End call triggers
515 }
516 }
517
518 if (!$error) {
519 $this->oldref = $this->ref;
520
521 // Rename directory if dir was a temporary ref
522 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
523 // Now we rename also files into index
524 $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)."'";
525 $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'job/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
526 $resql = $this->db->query($sql);
527 if (!$resql) {
528 $error++;
529 $this->error = $this->db->lasterror();
530 }
531 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'job/".$this->db->escape($this->newref)."'";
532 $sql .= " WHERE filepath = 'job/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
533 $resql = $this->db->query($sql);
534 if (!$resql) {
535 $error++;
536 $this->error = $this->db->lasterror();
537 }
538
539 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
540 $oldref = dol_sanitizeFileName($this->ref);
541 $newref = dol_sanitizeFileName($num);
542 $dirsource = $conf->hrm->dir_output.'/job/'.$oldref;
543 $dirdest = $conf->hrm->dir_output.'/job/'.$newref;
544 if (!$error && file_exists($dirsource)) {
545 dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
546
547 if (@rename($dirsource, $dirdest)) {
548 dol_syslog("Rename ok");
549 // Rename docs starting with $oldref with $newref
550 $listoffiles = dol_dir_list($conf->hrm->dir_output.'/job/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
551 foreach ($listoffiles as $fileentry) {
552 $dirsource = $fileentry['name'];
553 $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
554 $dirsource = $fileentry['path'].'/'.$dirsource;
555 $dirdest = $fileentry['path'].'/'.$dirdest;
556 @rename($dirsource, $dirdest);
557 }
558 }
559 }
560 }
561 }
562
563 // Set new ref and current status
564 if (!$error) {
565 $this->ref = $num;
566 $this->status = self::STATUS_VALIDATED;
567 }
568
569 if (!$error) {
570 $this->db->commit();
571 return 1;
572 } else {
573 $this->db->rollback();
574 return -1;
575 }
576 }
577
584 public function getLastJobForUser($fk_user)
585 {
586 $Tab = $this->getForUser($fk_user);
587
588 if (empty($Tab)) {
589 return '';
590 }
591
592 $lastpos = array_shift($Tab);
593
594 return $lastpos;
595 }
596
603 public function getForUser($userid)
604 {
605 global $db;
606
607 $TReturn = array();
608 $position = new Position($db);
609 $TPosition = $position->getForUser($userid);
610 foreach ($TPosition as $UPosition) {
611 $TReturn[$UPosition->Job->rowid] = $UPosition->Job->ref;
612 }
613 return $TReturn;
614 }
615
623 public function setDraft($user, $notrigger = 0)
624 {
625 // Protection
626 if ($this->status <= self::STATUS_DRAFT) {
627 return 0;
628 }
629
630 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
631 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
632 {
633 $this->error='Permission denied';
634 return -1;
635 }*/
636
637 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'JOB_UNVALIDATE');
638 }
639
647 public function cancel($user, $notrigger = 0)
648 {
649 // Protection
650 if ($this->status != self::STATUS_VALIDATED) {
651 return 0;
652 }
653
654 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
655 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
656 {
657 $this->error='Permission denied';
658 return -1;
659 }*/
660
661 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'JOB_CANCEL');
662 }
663
671 public function reopen($user, $notrigger = 0)
672 {
673 // Protection
674 if ($this->status != self::STATUS_CANCELED) {
675 return 0;
676 }
677
678 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
679 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
680 {
681 $this->error='Permission denied';
682 return -1;
683 }*/
684
685 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'JOB_REOPEN');
686 }
687
698 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
699 {
700 global $conf, $langs, $hookmanager;
701
702 if (!empty($conf->dol_no_mouse_hover)) {
703 $notooltip = 1; // Force disable tooltips
704 }
705
706 $result = '';
707
708 $label = img_picto('', $this->picto).' <u>'.$langs->trans("JobProfile").'</u>';
709 if (isset($this->status)) {
710 $label .= ' '.$this->getLibStatut(5);
711 }
712 $label .= '<br>';
713 $label .= '<b>'.$langs->trans('Label').':</b> '.$this->label;
714
715 $url = dol_buildpath('/hrm/job_card.php', 1).'?id='.$this->id;
716
717 if ($option != 'nolink') {
718 // Add param to save lastsearch_values or not
719 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
720 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
721 $add_save_lastsearch_values = 1;
722 }
723 if ($add_save_lastsearch_values) {
724 $url .= '&save_lastsearch_values=1';
725 }
726 }
727
728 $linkclose = '';
729 if (empty($notooltip)) {
730 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
731 $label = $langs->trans("ShowJob");
732 $linkclose .= ' alt="'.dolPrintHTMLForAttribute($label).'"';
733 }
734 $linkclose .= ' title="'.dolPrintHTMLForAttribute($label).'"';
735 $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
736 } else {
737 $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
738 }
739
740 if ($option == 'nolink') {
741 $linkstart = '<span';
742 } else {
743 $linkstart = '<a href="'.$url.'"';
744 }
745 $linkstart .= $linkclose.'>';
746 if ($option == 'nolink') {
747 $linkend = '</span>';
748 } else {
749 $linkend = '</a>';
750 }
751
752 $result .= $linkstart;
753
754 if (empty($this->showphoto_on_popup)) {
755 if ($withpicto) {
756 $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);
757 }
758 } else {
759 if ($withpicto) {
760 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
761
762 list($class, $module) = explode('@', $this->picto);
763 $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->label);
764 $filearray = dol_dir_list($upload_dir, "files");
765 $filename = $filearray[0]['name'];
766 if (!empty($filename)) {
767 $pospoint = strpos($filearray[0]['name'], '.');
768
769 $pathtophoto = $class.'/'.$this->label.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
770 if (!getDolGlobalString(strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS')) {
771 $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>';
772 } else {
773 $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>';
774 }
775
776 $result .= '</div>';
777 } else {
778 $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);
779 }
780 }
781 }
782
783 if ($withpicto != 2) {
784 $result .= $this->label;
785 }
786
787 $result .= $linkend;
788 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
789
790 global $action, $hookmanager;
791 $hookmanager->initHooks(array('jobdao'));
792 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
793 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
794 if ($reshook > 0) {
795 $result = $hookmanager->resPrint;
796 } else {
797 $result .= $hookmanager->resPrint;
798 }
799
800 return $result;
801 }
802
809 public function getLibStatut($mode = 0)
810 {
811 return $this->LibStatut($this->status, $mode);
812 }
813
814 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
822 public function LibStatut($status, $mode = 0)
823 {
824 // phpcs:enable
825
826 return ''; // There is no status on job profile for the moment
827 }
828
835 public function info($id)
836 {
837 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
838 $sql .= ' fk_user_creat, fk_user_modif';
839 $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
840 $sql .= ' WHERE t.rowid = '.((int) $id);
841 $result = $this->db->query($sql);
842 if ($result) {
843 if ($this->db->num_rows($result)) {
844 $obj = $this->db->fetch_object($result);
845
846 $this->id = $obj->rowid;
847
848 $this->user_creation_id = $obj->fk_user_creat;
849 $this->user_modification_id = $obj->fk_user_modif;
850 $this->date_creation = $this->db->jdate($obj->datec);
851 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
852 }
853
854 $this->db->free($result);
855 } else {
856 dol_print_error($this->db);
857 }
858 }
859
866 public function initAsSpecimen()
867 {
868 // Set here init that are not commonf fields
869 // $this->property1 = ...
870 // $this->property2 = ...
871
872 return $this->initAsSpecimenCommon();
873 }
874
880 public function getLinesArray()
881 {
882 $this->lines = array();
883
884 $objectline = new JobLine($this->db);
885 $result = $objectline->fetchAll('ASC', 'position', 0, 0, '(fk_job:=:'.((int) $this->id).')');
886
887 if (is_numeric($result)) {
888 $this->setErrorsFromObject($objectline);
889 return $result;
890 } else {
891 $this->lines = $result;
892 return $this->lines;
893 }
894 }
895
901 public function getNextNumRef()
902 {
903 global $langs, $conf;
904 $langs->load("hrm");
905
906 if (!getDolGlobalString('hrm_JOB_ADDON')) {
907 $conf->global->hrm_JOB_ADDON = 'mod_job_standard';
908 }
909
910 if (getDolGlobalString('hrm_JOB_ADDON')) {
911 $mybool = false;
912
913 $file = getDolGlobalString('hrm_JOB_ADDON') . ".php";
914 $classname = getDolGlobalString('hrm_JOB_ADDON');
915
916 // Include file with class
917 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
918 foreach ($dirmodels as $reldir) {
919 $dir = dol_buildpath($reldir."core/modules/hrm/");
920
921 // Load file with numbering class (if found)
922 $mybool = ((bool) @include_once $dir.$file) || $mybool;
923 }
924
925 if (!$mybool) {
926 dol_print_error(null, "Failed to include file ".$file);
927 return '';
928 }
929
930 if (class_exists($classname)) {
931 $obj = new $classname();
932 '@phan-var-force ModeleNumRefEvaluation $obj';
934 $numref = $obj->getNextValue($this);
935
936 if ($numref != '' && $numref != '-1') {
937 return $numref;
938 } else {
939 $this->error = $obj->error;
940 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
941 return "";
942 }
943 } else {
944 print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
945 return "";
946 }
947 } else {
948 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
949 return "";
950 }
951 }
952
964 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
965 {
966 global $conf, $langs;
967
968 $result = 0;
969
970 $langs->load("hrm");
971
972 if (!dol_strlen($modele)) {
973 $modele = 'standard_job';
974
975 if (!empty($this->model_pdf)) {
976 $modele = $this->model_pdf;
977 } elseif (getDolGlobalString('JOB_ADDON_PDF')) {
978 $modele = getDolGlobalString('JOB_ADDON_PDF');
979 }
980 }
981
982 $modelpath = "core/modules/hrm/doc/";
983
984 if (!empty($modele)) {
985 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
986 }
987
988 return $result;
989 }
990
998 public function getKanbanView($option = '', $arraydata = null)
999 {
1000 global $selected, $langs;
1001
1002 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1003
1004 $return = '<div class="box-flex-item box-flex-grow-zero">';
1005 $return .= '<div class="info-box info-box-sm">';
1006 $return .= '<span class="info-box-icon bg-infobox-action">';
1007 $return .= img_picto('', $this->picto);
1008 $return .= '</span>';
1009 $return .= '<div class="info-box-content">';
1010 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . $this->getNomUrl(0) . '</span>';
1011 if ($selected >= 0) {
1012 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1013 }
1014 /*if (property_exists($this, 'deplacement')) {
1015 $return .= '<br><span class="opacitymedium">'.$langs->trans("Type").'</span>';
1016 $return .= ' : <span class="info-box-label ">'.$this->fields['deplacement']['arrayofkeyval'][$this->deplacement].'</span>';
1017 }*/
1018 if (empty($this->description)) {
1019 //$return .= '<br><span class="info-box-label opacitymedium">'.$langs->trans("Description").'</span> : ';
1020 $return .= '<br><span class="info-box-label ">' . dol_trunc($this->description, 25) . '</span>';
1021 }
1022 $return .= '</div>';
1023 $return .= '</div>';
1024 $return .= '</div>';
1025 return $return;
1026 }
1027
1033 public function getSkillRankForJob($id)
1034 {
1035 if (empty($id)) {
1036 return -1;
1037 }
1038 $skillranks = array();
1039 $sql = "SELECT rowid";
1040 $sql .= " FROM ".MAIN_DB_PREFIX."hrm_skillrank";
1041 $sql .= " WHERE fk_object = ".((int) $id);
1042
1043 $resql = $this->db->query($sql);
1044 if ($resql) {
1045 $num = $this->db->num_rows($resql);
1046 $i = 0;
1047 while ($i < $num) {
1048 $obj = $this->db->fetch_object($resql);
1049 $skillranks[] = $obj->rowid;
1050 $i++;
1051 }
1052 $this->db->free($resql);
1053 } else {
1054 dol_print_error($this->db);
1055 }
1056 return $skillranks;
1057 }
1058}
1059
1060
1061require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1062
1067{
1068 // To complete with content of an object JobLine
1069 // We should have a field rowid, fk_job and position
1070
1076 public function __construct(DoliDB $db)
1077 {
1078 $this->db = $db;
1079
1080 $this->isextrafieldmanaged = 0;
1081 }
1082}
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
$object ref
Definition info.php:90
Parent class of all other business classes (invoices, contracts, proposals, orders,...
deleteLineCommon(User $user, $idline, $notrigger=0)
Delete a line of object in database.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
setErrorsFromObject($object)
setErrorsFromObject
createCommon(User $user, $notrigger=0)
Create object in the database.
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
updateCommon(User $user, $notrigger=0)
Update object into database.
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
initAsSpecimenCommon()
Initialise object with example values Id must be 0 if object instance is a specimen.
copy_linked_contact($objFrom, $source='internal')
Copy contact from one element to current.
fetchLinesCommon($morewhere='', $noextrafields=0)
Load object in memory from the database.
fetchCommon($id, $ref=null, $morewhere='', $noextrafields=0)
Load object in memory from the database.
deleteCommon(User $user, $notrigger=0, $forcechilddeletion=0)
Delete object in database.
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
getLastJobForUser($fk_user)
Get the last occupied position for a user.
fetchLines()
Load object lines in memory from the database.
cancel($user, $notrigger=0)
Set cancel status.
__construct(DoliDB $db)
Constructor.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
setDraft($user, $notrigger=0)
Set draft status.
update(User $user, $notrigger=0)
Update object into database.
validate($user, $notrigger=0)
Validate object.
getLibStatut($mode=0)
Return the label of the status.
getLinesArray()
Create an array of lines.
fetch($id, $ref=null)
Load object in memory from the database.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
LibStatut($status, $mode=0)
Return the status.
deleteLine(User $user, $idline, $notrigger=0)
Delete a line of object in database.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionally the picto)
createFromClone(User $user, $fromid)
Clone an object into another one.
reopen($user, $notrigger=0)
Set back to validated status.
getSkillRankForJob($id)
function for get required skills associate to job object
create(User $user, $notrigger=0)
Create object into database.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, $filter='', $filtermode='AND')
Load list of objects in memory from the database.
getForUser($userid)
Get array of occupied positions for a user.
getKanbanView($option='', $arraydata=null)
Return clickable link of object (with eventually picto)
info($id)
Load the info information in the object.
Class JobLine.
__construct(DoliDB $db)
Constructor.
Class for Position.
Class to manage Dolibarr users.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:168
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.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
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:64
dol_now($mode='gmt')
Return date for now.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php