dolibarr  18.0.6
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
29 require_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 
36 class 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 (empty($conf->global->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 (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++; $this->error = $this->db->lasterror();
562  }
563  $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'job/".$this->db->escape($this->newref)."'";
564  $sql .= " WHERE filepath = 'job/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
565  $resql = $this->db->query($sql);
566  if (!$resql) {
567  $error++; $this->error = $this->db->lasterror();
568  }
569 
570  // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
571  $oldref = dol_sanitizeFileName($this->ref);
572  $newref = dol_sanitizeFileName($num);
573  $dirsource = $conf->hrm->dir_output.'/job/'.$oldref;
574  $dirdest = $conf->hrm->dir_output.'/job/'.$newref;
575  if (!$error && file_exists($dirsource)) {
576  dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest);
577 
578  if (@rename($dirsource, $dirdest)) {
579  dol_syslog("Rename ok");
580  // Rename docs starting with $oldref with $newref
581  $listoffiles = dol_dir_list($conf->hrm->dir_output.'/job/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
582  foreach ($listoffiles as $fileentry) {
583  $dirsource = $fileentry['name'];
584  $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
585  $dirsource = $fileentry['path'].'/'.$dirsource;
586  $dirdest = $fileentry['path'].'/'.$dirdest;
587  @rename($dirsource, $dirdest);
588  }
589  }
590  }
591  }
592  }
593 
594  // Set new ref and current status
595  if (!$error) {
596  $this->ref = $num;
597  $this->status = self::STATUS_VALIDATED;
598  }
599 
600  if (!$error) {
601  $this->db->commit();
602  return 1;
603  } else {
604  $this->db->rollback();
605  return -1;
606  }
607  }
608 
615  public function getLastJobForUser($fk_user)
616  {
617  $Tab = $this->getForUser($fk_user);
618 
619  if (empty($Tab)) return '';
620 
621  $lastpos = array_shift($Tab);
622 
623  return $lastpos;
624  }
625 
632  public function getForUser($userid)
633  {
634  global $db;
635 
636  $TReturn = array();
637  $position = new Position($db);
638  $TPosition = $position->getForUser($userid);
639  foreach ($TPosition as $UPosition) {
640  $TReturn[$UPosition->Job->rowid] = $UPosition->Job->ref;
641  }
642  return $TReturn;
643  }
644 
652  public function setDraft($user, $notrigger = 0)
653  {
654  // Protection
655  if ($this->status <= self::STATUS_DRAFT) {
656  return 0;
657  }
658 
659  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
660  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
661  {
662  $this->error='Permission denied';
663  return -1;
664  }*/
665 
666  return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'JOB_UNVALIDATE');
667  }
668 
676  public function cancel($user, $notrigger = 0)
677  {
678  // Protection
679  if ($this->status != self::STATUS_VALIDATED) {
680  return 0;
681  }
682 
683  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
684  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
685  {
686  $this->error='Permission denied';
687  return -1;
688  }*/
689 
690  return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'JOB_CANCEL');
691  }
692 
700  public function reopen($user, $notrigger = 0)
701  {
702  // Protection
703  if ($this->status != self::STATUS_CANCELED) {
704  return 0;
705  }
706 
707  /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
708  || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
709  {
710  $this->error='Permission denied';
711  return -1;
712  }*/
713 
714  return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'JOB_REOPEN');
715  }
716 
727  public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
728  {
729  global $conf, $langs, $hookmanager;
730 
731  if (!empty($conf->dol_no_mouse_hover)) {
732  $notooltip = 1; // Force disable tooltips
733  }
734 
735  $result = '';
736 
737  $label = img_picto('', $this->picto).' <u>'.$langs->trans("JobProfile").'</u>';
738  if (isset($this->status)) {
739  $label .= ' '.$this->getLibStatut(5);
740  }
741  $label .= '<br>';
742  $label .= '<b>'.$langs->trans('Label').':</b> '.$this->label;
743 
744  $url = dol_buildpath('/hrm/job_card.php', 1).'?id='.$this->id;
745 
746  if ($option != 'nolink') {
747  // Add param to save lastsearch_values or not
748  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
749  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
750  $add_save_lastsearch_values = 1;
751  }
752  if ($add_save_lastsearch_values) {
753  $url .= '&save_lastsearch_values=1';
754  }
755  }
756 
757  $linkclose = '';
758  if (empty($notooltip)) {
759  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
760  $label = $langs->trans("ShowJob");
761  $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
762  }
763  $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
764  $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
765  } else {
766  $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
767  }
768 
769  if ($option == 'nolink') {
770  $linkstart = '<span';
771  } else {
772  $linkstart = '<a href="'.$url.'"';
773  }
774  $linkstart .= $linkclose.'>';
775  if ($option == 'nolink') {
776  $linkend = '</span>';
777  } else {
778  $linkend = '</a>';
779  }
780 
781  $result .= $linkstart;
782 
783  if (empty($this->showphoto_on_popup)) {
784  if ($withpicto) {
785  $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);
786  }
787  } else {
788  if ($withpicto) {
789  require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
790 
791  list($class, $module) = explode('@', $this->picto);
792  $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->label);
793  $filearray = dol_dir_list($upload_dir, "files");
794  $filename = $filearray[0]['name'];
795  if (!empty($filename)) {
796  $pospoint = strpos($filearray[0]['name'], '.');
797 
798  $pathtophoto = $class.'/'.$this->label.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint);
799  if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) {
800  $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>';
801  } else {
802  $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>';
803  }
804 
805  $result .= '</div>';
806  } else {
807  $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);
808  }
809  }
810  }
811 
812  if ($withpicto != 2) {
813  $result .= $this->label;
814  }
815 
816  $result .= $linkend;
817  //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
818 
819  global $action, $hookmanager;
820  $hookmanager->initHooks(array('jobdao'));
821  $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
822  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
823  if ($reshook > 0) {
824  $result = $hookmanager->resPrint;
825  } else {
826  $result .= $hookmanager->resPrint;
827  }
828 
829  return $result;
830  }
831 
838  public function getLibStatut($mode = 0)
839  {
840  return $this->LibStatut($this->status, $mode);
841  }
842 
843  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
851  public function LibStatut($status, $mode = 0)
852  {
853  // phpcs:enable
854  return ''; // There is no status on job profile for the moment
855 
856  /*
857  if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
858  global $langs;
859  //$langs->load("hrm");
860  $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
861  $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
862  $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
863  $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
864  $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
865  $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
866  }
867 
868  $statusType = 'status'.$status;
869  //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
870  if ($status == self::STATUS_CANCELED) {
871  $statusType = 'status6';
872  }
873 
874  return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
875  */
876  }
877 
884  public function info($id)
885  {
886  $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
887  $sql .= ' fk_user_creat, fk_user_modif';
888  $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
889  $sql .= ' WHERE t.rowid = '.((int) $id);
890  $result = $this->db->query($sql);
891  if ($result) {
892  if ($this->db->num_rows($result)) {
893  $obj = $this->db->fetch_object($result);
894  $this->id = $obj->rowid;
895 
896  $this->user_creation_id = $obj->fk_user_creat;
897  $this->user_modification_id = $obj->fk_user_modif;
898  $this->date_creation = $this->db->jdate($obj->datec);
899  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
900  }
901 
902  $this->db->free($result);
903  } else {
904  dol_print_error($this->db);
905  }
906  }
907 
914  public function initAsSpecimen()
915  {
916  // Set here init that are not commonf fields
917  // $this->property1 = ...
918  // $this->property2 = ...
919 
920  $this->initAsSpecimenCommon();
921  }
922 
928  public function getLinesArray()
929  {
930  $this->lines = array();
931 
932  $objectline = new JobLine($this->db);
933  $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_job = '.$this->id));
934 
935  if (is_numeric($result)) {
936  $this->error = $objectline->error;
937  $this->errors = $objectline->errors;
938  return $result;
939  } else {
940  $this->lines = $result;
941  return $this->lines;
942  }
943  }
944 
950  public function getNextNumRef()
951  {
952  global $langs, $conf;
953  $langs->load("hrm");
954 
955  if (empty($conf->global->hrm_JOB_ADDON)) {
956  $conf->global->hrm_JOB_ADDON = 'mod_job_standard';
957  }
958 
959  if (!empty($conf->global->hrm_JOB_ADDON)) {
960  $mybool = false;
961 
962  $file = $conf->global->hrm_JOB_ADDON.".php";
963  $classname = $conf->global->hrm_JOB_ADDON;
964 
965  // Include file with class
966  $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
967  foreach ($dirmodels as $reldir) {
968  $dir = dol_buildpath($reldir."core/modules/hrm/");
969 
970  // Load file with numbering class (if found)
971  $mybool |= @include_once $dir.$file;
972  }
973 
974  if ($mybool === false) {
975  dol_print_error('', "Failed to include file ".$file);
976  return '';
977  }
978 
979  if (class_exists($classname)) {
980  $obj = new $classname();
981  $numref = $obj->getNextValue($this);
982 
983  if ($numref != '' && $numref != '-1') {
984  return $numref;
985  } else {
986  $this->error = $obj->error;
987  //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
988  return "";
989  }
990  } else {
991  print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname;
992  return "";
993  }
994  } else {
995  print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
996  return "";
997  }
998  }
999 
1011  public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1012  {
1013  global $conf, $langs;
1014 
1015  $result = 0;
1016  $includedocgeneration = 0;
1017 
1018  $langs->load("hrm");
1019 
1020  if (!dol_strlen($modele)) {
1021  $modele = 'standard_job';
1022 
1023  if (!empty($this->model_pdf)) {
1024  $modele = $this->model_pdf;
1025  } elseif (!empty($conf->global->JOB_ADDON_PDF)) {
1026  $modele = $conf->global->JOB_ADDON_PDF;
1027  }
1028  }
1029 
1030  $modelpath = "core/modules/hrm/doc/";
1031 
1032  if ($includedocgeneration && !empty($modele)) {
1033  $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1034  }
1035 
1036  return $result;
1037  }
1038 
1046  public function doScheduledJob()
1047  {
1048  global $conf, $langs;
1049 
1050  //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1051 
1052  $error = 0;
1053  $this->output = '';
1054  $this->error = '';
1055 
1056  dol_syslog(__METHOD__, LOG_DEBUG);
1057 
1058  $now = dol_now();
1059 
1060  $this->db->begin();
1061 
1062  // ...
1063 
1064  $this->db->commit();
1065 
1066  return $error;
1067  }
1068 
1076  public function getKanbanView($option = '', $arraydata = null)
1077  {
1078  global $selected, $langs;
1079 
1080  $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1081 
1082  $return = '<div class="box-flex-item box-flex-grow-zero">';
1083  $return .= '<div class="info-box info-box-sm">';
1084  $return .= '<span class="info-box-icon bg-infobox-action">';
1085  $return .= img_picto('', $this->picto);
1086  $return .= '</span>';
1087  $return .= '<div class="info-box-content">';
1088  $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(0) : $this->ref).'</span>';
1089  $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1090  /*if (property_exists($this, 'deplacement')) {
1091  $return .= '<br><span class="opacitymedium">'.$langs->trans("Type").'</span>';
1092  $return .= ' : <span class="info-box-label ">'.$this->fields['deplacement']['arrayofkeyval'][$this->deplacement].'</span>';
1093  }*/
1094  if (property_exists($this, 'description') && !(empty($this->description))) {
1095  //$return .= '<br><span class="info-box-label opacitymedium">'.$langs->trans("Description").'</span> : ';
1096  $return .= '<br><span class="info-box-label ">'.(strlen($this->description) > 30 ? dol_substr($this->description, 0, 25).'...' : $this->description).'</span>';
1097  }
1098  $return .= '</div>';
1099  $return .= '</div>';
1100  $return .= '</div>';
1101  return $return;
1102  }
1103 }
1104 
1105 
1106 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
1107 
1112 {
1113  // To complete with content of an object JobLine
1114  // We should have a field rowid, fk_job and position
1115 
1119  public $isextrafieldmanaged = 0;
1120 
1126  public function __construct(DoliDB $db)
1127  {
1128  $this->db = $db;
1129  }
1130 }
$object ref
Definition: info.php:78
Parent class of all other business classes (invoices, contracts, proposals, orders,...
deleteLineCommon(User $user, $idline, $notrigger=false)
Delete a line of object in database.
fetchCommon($id, $ref=null, $morewhere='')
Load object in memory from the 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.
copy_linked_contact($objFrom, $source='internal')
Copy contact from one element to current.
updateCommon(User $user, $notrigger=false)
Update object into database.
fetchLinesCommon($morewhere='')
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.
Definition: job.class.php:1046
update(User $user, $notrigger=false)
Update object into database.
Definition: job.class.php:442
getNextNumRef()
Returns the reference to the following non used object depending on the active numbering module.
Definition: job.class.php:950
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter=array(), $filtermode='AND')
Load list of objects in memory from the database.
Definition: job.class.php:366
getLastJobForUser($fk_user)
Get the last occupied position for a user.
Definition: job.class.php:615
fetchLines()
Load object lines in memory from the database.
Definition: job.class.php:346
cancel($user, $notrigger=0)
Set cancel status.
Definition: job.class.php:676
__construct(DoliDB $db)
Constructor.
Definition: job.class.php:172
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
Definition: job.class.php:1011
setDraft($user, $notrigger=0)
Set draft status.
Definition: job.class.php:652
validate($user, $notrigger=0)
Validate object.
Definition: job.class.php:486
getLibStatut($mode=0)
Return the label of the status.
Definition: job.class.php:838
getLinesArray()
Create an array of lines.
Definition: job.class.php:928
fetch($id, $ref=null)
Load object in memory from the database.
Definition: job.class.php:332
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
Definition: job.class.php:914
LibStatut($status, $mode=0)
Return the status.
Definition: job.class.php:851
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionaly the picto)
Definition: job.class.php:727
createFromClone(User $user, $fromid)
Clone an object into another one.
Definition: job.class.php:233
create(User $user, $notrigger=false)
Create object into database.
Definition: job.class.php:217
reopen($user, $notrigger=0)
Set back to validated status.
Definition: job.class.php:700
deleteLine(User $user, $idline, $notrigger=false)
Delete a line of object in database.
Definition: job.class.php:468
getForUser($userid)
Get array of occupied positions for a user.
Definition: job.class.php:632
getKanbanView($option='', $arraydata=null)
Return clicable link of object (with eventually picto)
Definition: job.class.php:1076
info($id)
Load the info information in the object.
Definition: job.class.php:884
Class JobLine.
Definition: job.class.php:1112
__construct(DoliDB $db)
Constructor.
Definition: job.class.php:1126
Class for Position.
Class to manage Dolibarr users.
Definition: user.class.php:48
if(isModEnabled('facture') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $sql
Social contributions to pay.
Definition: index.php:746
print *****$script_file(".$version.") pid 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.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.