dolibarr 19.0.4
position.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
37{
41 public $module = 'hrm';
42
46 public $element = 'position';
47
51 public $table_element = 'hrm_job_user';
52
57 public $ismultientitymanaged = 0;
58
62 public $isextrafieldmanaged = 0;
63
67 public $picto = 'user-cog';
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'=>2, 'index'=>1, 'css'=>'left', 'comment'=>"Id"),
107 //'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>20, 'notnull'=>1, 'visible'=>1, 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'comment'=>"Reference of object"),
108 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>-2,),
109 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>-2,),
110 'fk_contrat' => array('type'=>'integer:Contrat:contrat/class/contrat.class.php', 'label'=>'fk_contrat', 'enabled'=>'isModEnabled("contract")', 'position'=>50, 'notnull'=>0, 'visible'=>0,),
111 'fk_user' => array('type'=>'integer:User:user/class/user.class.php:0:(t.statut:=:1)', 'label'=>'Employee', 'enabled'=>'1', 'position'=>55, 'notnull'=>1, 'visible'=>1, 'default'=>0, 'picto'=>'user', 'css'=>'maxwidth300 widthcentpercentminusxx', 'csslist'=>'tdoverflowmax150'),
112 'fk_job' => array('type'=>'integer:Job:/hrm/class/job.class.php', 'label'=>'JobProfile', 'enabled'=>'1', 'position'=>56, 'notnull'=>1, 'visible'=>1, 'picto'=>'jobprofile', 'css'=>'maxwidth300 widthcentpercentminusxx', 'csslist'=>'tdoverflowmax150'),
113 'date_start' => array('type'=>'date', 'label'=>'DateStart', 'enabled'=>'1', 'position'=>101, 'notnull'=>1, 'visible'=>1,),
114 'date_end' => array('type'=>'date', 'label'=>'DateEnd', 'enabled'=>'1', 'position'=>102, 'notnull'=>0, 'visible'=>1,),
115 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>120, 'notnull'=>0, 'visible'=>3,),
116 'abort_comment' => array('type'=>'varchar(255)', 'label'=>'AbandonmentComment', 'enabled'=>'getDolGlobalInt("HRM_JOB_POSITON_ENDING_COMMENT")', 'position'=>502, 'notnull'=>0, 'visible'=>1,),
117 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>151, 'notnull'=>0, 'visible'=>0,),
118 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>152, 'notnull'=>0, 'visible'=>0,),
119 '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',),
120 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,),
121 );
122 public $rowid;
123 public $ref;
124 public $description;
125 public $date_creation;
126 public $tms;
127 public $fk_contrat;
128 public $fk_user;
129 public $fk_job;
130 public $date_start;
131 public $date_end;
132 public $abort_comment;
133 public $note_public;
134 public $note_private;
135 public $fk_user_creat;
136 public $fk_user_modif;
137
138
139 // END MODULEBUILDER PROPERTIES
140
141
142 // If this object has a subtable with lines
143
144 // /**
145 // * @var string Name of subtable line
146 // */
147 // public $table_element_line = 'hrm_job_userline';
148
149 // /**
150 // * @var string Field with ID of parent key if this object has a parent
151 // */
152 // public $fk_element = 'fk_position';
153
154 // /**
155 // * @var string Name of subtable class that manage subtable lines
156 // */
157 // public $class_element_line = 'Positionline';
158
159 // /**
160 // * @var array List of child tables. To test if we can delete object.
161 // */
162 // protected $childtables = array();
163
164 // /**
165 // * @var array List of child tables. To know object to delete on cascade.
166 // * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will
167 // * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object
168 // */
169 // protected $childtablesoncascade = array('hrm_job_userdet');
170
171 // /**
172 // * @var PositionLine[] Array of subtable lines
173 // */
174 // public $lines = array();
175
176
182 public function __construct(DoliDB $db)
183 {
184 global $conf, $langs;
185
186 $this->db = $db;
187
188 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
189 //$this->fields['rowid']['visible'] = 0;
190 }
191 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
192 $this->fields['entity']['enabled'] = 0;
193 }
194
195 // Example to show how to set values of fields definition dynamically
196 /*if ($user->rights->hrm->position->read) {
197 $this->fields['myfield']['visible'] = 1;
198 $this->fields['myfield']['noteditable'] = 0;
199 }*/
200
201 // Unset fields that are disabled
202 foreach ($this->fields as $key => $val) {
203 if (isset($val['enabled']) && empty($val['enabled'])) {
204 unset($this->fields[$key]);
205 }
206 }
207
208 // Translate some data of arrayofkeyval
209 if (is_object($langs)) {
210 foreach ($this->fields as $key => $val) {
211 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
212 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
213 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
214 }
215 }
216 }
217 }
218 }
219
227 public function create(User $user, $notrigger = false)
228 {
229 $resultcreate = $this->createCommon($user, $notrigger);
230
231 //$resultvalidate = $this->validate($user, $notrigger);
232
233 return $resultcreate;
234 }
235
243 public function createFromClone(User $user, $fromid)
244 {
245 global $langs, $extrafields;
246 $error = 0;
247
248 dol_syslog(__METHOD__, LOG_DEBUG);
249
250 $object = new self($this->db);
251
252 $this->db->begin();
253
254 // Load source object
255 $result = $object->fetchCommon($fromid);
256 if ($result > 0 && !empty($object->table_element_line)) {
257 $object->fetchLines();
258 }
259
260 // get lines so they will be clone
261 //foreach($this->lines as $line)
262 // $line->fetch_optionals();
263
264 // Reset some properties
265 unset($object->id);
266 unset($object->fk_user_creat);
267 unset($object->import_key);
268
269 // Clear fields
270 if (property_exists($object, 'ref')) {
271 $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_" . $object->ref : $this->fields['ref']['default'];
272 }
273 if (property_exists($object, 'label')) {
274 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf") . " " . $object->label : $this->fields['label']['default'];
275 }
276 if (property_exists($object, 'status')) {
277 $object->status = self::STATUS_DRAFT;
278 }
279 if (property_exists($object, 'date_creation')) {
280 $object->date_creation = dol_now();
281 }
282 if (property_exists($object, 'date_modification')) {
283 $object->date_modification = null;
284 }
285 // ...
286 // Clear extrafields that are unique
287 if (is_array($object->array_options) && count($object->array_options) > 0) {
288 $extrafields->fetch_name_optionals_label($this->table_element);
289 foreach ($object->array_options as $key => $option) {
290 $shortkey = preg_replace('/options_/', '', $key);
291 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
292 //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
293 unset($object->array_options[$key]);
294 }
295 }
296 }
297
298 // Create clone
299 $object->context['createfromclone'] = 'createfromclone';
300 $result = $object->createCommon($user);
301 if ($result < 0) {
302 $error++;
303 $this->error = $object->error;
304 $this->errors = $object->errors;
305 }
306
307 if (!$error) {
308 // copy internal contacts
309 if ($this->copy_linked_contact($object, 'internal') < 0) {
310 $error++;
311 }
312 }
313
314 if (!$error) {
315 // copy external contacts if same company
316 if (property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
317 if ($this->copy_linked_contact($object, 'external') < 0) {
318 $error++;
319 }
320 }
321 }
322
323 unset($object->context['createfromclone']);
324
325 // End
326 if (!$error) {
327 $this->db->commit();
328 return $object;
329 } else {
330 $this->db->rollback();
331 return -1;
332 }
333 }
334
342 public function fetch($id, $ref = null)
343 {
344 $result = $this->fetchCommon($id, $ref);
345 if ($result > 0 && !empty($this->table_element_line)) {
346 $this->fetchLines();
347 }
348 return $result;
349 }
350
356 public function fetchLines()
357 {
358 $this->lines = array();
359
360 $result = $this->fetchLinesCommon();
361 return $result;
362 }
363
364
376 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
377 {
378 global $conf;
379
380 dol_syslog(__METHOD__, LOG_DEBUG);
381
382 $records = array();
383
384 $sql = 'SELECT ';
385 $sql .= $this->getFieldList('t');
386 $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
387 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
388 $sql .= ' WHERE t.entity IN (' . getEntity($this->element) . ')';
389 } else {
390 $sql .= ' WHERE 1 = 1';
391 }
392 // Manage filter
393 $sqlwhere = array();
394 if (count($filter) > 0) {
395 foreach ($filter as $key => $value) {
396 if ($key == 't.rowid') {
397 $sqlwhere[] = $key . '=' . $value;
398 } elseif ($key == 'customsql') {
399 $sqlwhere[] = $value;
400 } elseif (array_key_exists($key, $this->fields) && in_array($this->fields[$key]['type'], array('date', 'datetime', 'timestamp'))) {
401 $sqlwhere[] = $key . ' = \'' . $this->db->idate($value) . '\'';
402 } elseif (strpos($value, '%') === false) {
403 $sqlwhere[] = $key . ' IN (' . $this->db->sanitize($this->db->escape($value)) . ')';
404 } else {
405 $sqlwhere[] = $key . ' LIKE \'%' . $this->db->escape($value) . '%\'';
406 }
407 }
408 }
409 if (count($sqlwhere) > 0) {
410 $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")";
411 }
412
413 if (!empty($sortfield)) {
414 $sql .= $this->db->order($sortfield, $sortorder);
415 }
416 if (!empty($limit)) {
417 $sql .= ' ' . $this->db->plimit($limit, $offset);
418 }
419
420 $resql = $this->db->query($sql);
421 if ($resql) {
422 $num = $this->db->num_rows($resql);
423 $i = 0;
424 while ($i < ($limit ? min($limit, $num) : $num)) {
425 $obj = $this->db->fetch_object($resql);
426
427 $record = new self($this->db);
428 $record->setVarsFromFetchObj($obj);
429
430 $records[$record->id] = $record;
431
432 $i++;
433 }
434 $this->db->free($resql);
435
436 return $records;
437 } else {
438 $this->errors[] = 'Error ' . $this->db->lasterror();
439 dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR);
440
441 return -1;
442 }
443 }
444
452 public function update(User $user, $notrigger = false)
453 {
454 return $this->updateCommon($user, $notrigger);
455 }
456
464 public function delete(User $user, $notrigger = false)
465 {
466 return $this->deleteCommon($user, $notrigger);
467 //return $this->deleteCommon($user, $notrigger, 1);
468 }
469
478 public function deleteLine(User $user, $idline, $notrigger = false)
479 {
480 if ($this->status < 0) {
481 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
482 return -2;
483 }
484
485 return $this->deleteLineCommon($user, $idline, $notrigger);
486 }
487
488
496 public function validate($user, $notrigger = 0)
497 {
498 global $conf, $langs;
499
500 require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
501
502 $error = 0;
503
504 // Protection
505 if ($this->status == self::STATUS_VALIDATED) {
506 dol_syslog(get_class($this) . "::validate action abandonned: already validated", LOG_WARNING);
507 return 0;
508 }
509
510 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->position->write))
511 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->position->position_advance->validate))))
512 {
513 $this->error='NotEnoughPermissions';
514 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
515 return -1;
516 }*/
517
518 $now = dol_now();
519
520 $this->db->begin();
521
522 // Define new ref
523 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
524 $num = $this->getNextNumRef();
525 } else {
526 $num = $this->ref;
527 }
528 $this->newref = $num;
529
530 if (!empty($num)) {
531 // Validate
532 $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
533 $sql .= " SET ref = '" . $this->db->escape($num) . "',";
534 $sql .= " status = " . self::STATUS_VALIDATED;
535 if (!empty($this->fields['date_validation'])) {
536 $sql .= ", date_validation = '" . $this->db->idate($now) . "'";
537 }
538 if (!empty($this->fields['fk_user_valid'])) {
539 $sql .= ", fk_user_valid = " . ((int) $user->id);
540 }
541 $sql .= " WHERE rowid = " . ((int) $this->id);
542
543 dol_syslog(get_class($this) . "::validate()", LOG_DEBUG);
544 $resql = $this->db->query($sql);
545 if (!$resql) {
546 dol_print_error($this->db);
547 $this->error = $this->db->lasterror();
548 $error++;
549 }
550
551 if (!$error && !$notrigger) {
552 // Call trigger
553 $result = $this->call_trigger('HRM_POSITION_VALIDATE', $user);
554 if ($result < 0) {
555 $error++;
556 }
557 // End call triggers
558 }
559 }
560
561 if (!$error) {
562 $this->oldref = $this->ref;
563
564 // Rename directory if dir was a temporary ref
565 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
566 // Now we rename also files into index
567 $sql = 'UPDATE ' . MAIN_DB_PREFIX . "ecm_files set filename = CONCAT('" . $this->db->escape($this->newref) . "', SUBSTR(filename, " . (strlen($this->ref) + 1) . ")), filepath = 'position/" . $this->db->escape($this->newref) . "'";
568 $sql .= " WHERE filename LIKE '" . $this->db->escape($this->ref) . "%' AND filepath = 'position/" . $this->db->escape($this->ref) . "' and entity = " . $conf->entity;
569 $resql = $this->db->query($sql);
570 if (!$resql) {
571 $error++;
572 $this->error = $this->db->lasterror();
573 }
574 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'position/".$this->db->escape($this->newref)."'";
575 $sql .= " WHERE filepath = 'position/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
576 $resql = $this->db->query($sql);
577 if (!$resql) {
578 $error++;
579 $this->error = $this->db->lasterror();
580 }
581
582 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
583 $oldref = dol_sanitizeFileName($this->ref);
584 $newref = dol_sanitizeFileName($num);
585 $dirsource = $conf->hrm->dir_output . '/position/' . $oldref;
586 $dirdest = $conf->hrm->dir_output . '/position/' . $newref;
587 if (!$error && file_exists($dirsource)) {
588 dol_syslog(get_class($this) . "::validate() rename dir " . $dirsource . " into " . $dirdest);
589
590 if (@rename($dirsource, $dirdest)) {
591 dol_syslog("Rename ok");
592 // Rename docs starting with $oldref with $newref
593 $listoffiles = dol_dir_list($conf->hrm->dir_output . '/position/' . $newref, 'files', 1, '^' . preg_quote($oldref, '/'));
594 foreach ($listoffiles as $fileentry) {
595 $dirsource = $fileentry['name'];
596 $dirdest = preg_replace('/^' . preg_quote($oldref, '/') . '/', $newref, $dirsource);
597 $dirsource = $fileentry['path'] . '/' . $dirsource;
598 $dirdest = $fileentry['path'] . '/' . $dirdest;
599 @rename($dirsource, $dirdest);
600 }
601 }
602 }
603 }
604 }
605
606 // Set new ref and current status
607 if (!$error) {
608 $this->ref = $num;
609 $this->status = self::STATUS_VALIDATED;
610 }
611
612 if (!$error) {
613 $this->db->commit();
614 return 1;
615 } else {
616 $this->db->rollback();
617 return -1;
618 }
619 }
620
621
629 public function setDraft($user, $notrigger = 0)
630 {
631 // Protection
632 if ($this->status <= self::STATUS_DRAFT) {
633 return 0;
634 }
635
636 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
637 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
638 {
639 $this->error='Permission denied';
640 return -1;
641 }*/
642
643 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'POSITION_UNVALIDATE');
644 }
645
653 public function cancel($user, $notrigger = 0)
654 {
655 // Protection
656 if ($this->status != self::STATUS_VALIDATED) {
657 return 0;
658 }
659
660 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
661 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
662 {
663 $this->error='Permission denied';
664 return -1;
665 }*/
666
667 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'POSITION_CANCEL');
668 }
669
677 public function reopen($user, $notrigger = 0)
678 {
679 // Protection
680 if ($this->status != self::STATUS_CANCELED) {
681 return 0;
682 }
683
684 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
685 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
686 {
687 $this->error='Permission denied';
688 return -1;
689 }*/
690
691 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'POSITION_REOPEN');
692 }
693
704 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
705 {
706 global $conf, $langs, $hookmanager;
707
708 if (!empty($conf->dol_no_mouse_hover)) {
709 $notooltip = 1; // Force disable tooltips
710 }
711
712 $result = '';
713
714 $label = img_picto('', $this->picto) . ' <u>' . $langs->trans("Position") . '</u>';
715 if (isset($this->status)) {
716 $label .= ' ' . $this->getLibStatut(5);
717 }
718 $label .= '<br>';
719 $label .= '<b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
720
721 $url = dol_buildpath('/hrm/position_card.php', 1) . '?id=' . $this->id;
722
723 if ($option != 'nolink') {
724 // Add param to save lastsearch_values or not
725 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
726 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
727 $add_save_lastsearch_values = 1;
728 }
729 if ($add_save_lastsearch_values) {
730 $url .= '&save_lastsearch_values=1';
731 }
732 }
733
734 $linkclose = '';
735 if (empty($notooltip)) {
736 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
737 $label = $langs->trans("ShowPosition");
738 $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"';
739 }
740 $linkclose .= ' title="' . dol_escape_htmltag($label, 1) . '"';
741 $linkclose .= ' class="classfortooltip' . ($morecss ? ' ' . $morecss : '') . '"';
742 } else {
743 $linkclose = ($morecss ? ' class="' . $morecss . '"' : '');
744 }
745
746 if ($option == 'nolink') {
747 $linkstart = '<span';
748 } else {
749 $linkstart = '<a href="' . $url . '"';
750 }
751 $linkstart .= $linkclose . '>';
752 if ($option == 'nolink') {
753 $linkend = '</span>';
754 } else {
755 $linkend = '</a>';
756 }
757
758 $result .= $linkstart;
759
760 if (empty($this->showphoto_on_popup)) {
761 if ($withpicto) {
762 $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);
763 }
764 } else {
765 if ($withpicto) {
766 require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
767
768 list($class, $module) = explode('@', $this->picto);
769 $upload_dir = $conf->$module->multidir_output[$conf->entity] . "/$class/" . dol_sanitizeFileName($this->ref);
770 $filearray = dol_dir_list($upload_dir, "files");
771 $filename = $filearray[0]['name'];
772 if (!empty($filename)) {
773 $pospoint = strpos($filearray[0]['name'], '.');
774
775 $pathtophoto = $class . '/' . $this->ref . '/thumbs/' . substr($filename, 0, $pospoint) . '_mini' . substr($filename, $pospoint);
776 if (!getDolGlobalString(strtoupper($module . '_' . $class) . '_FORMATLISTPHOTOSASUSERS')) {
777 $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>';
778 } else {
779 $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>';
780 }
781
782 $result .= '</div>';
783 } else {
784 $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);
785 }
786 }
787 }
788
789 if ($withpicto != 2) {
790 $result .= $this->ref;
791 }
792
793 $result .= $linkend;
794 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
795
796 global $action, $hookmanager;
797 $hookmanager->initHooks(array('positiondao'));
798 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
799 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
800 if ($reshook > 0) {
801 $result = $hookmanager->resPrint;
802 } else {
803 $result .= $hookmanager->resPrint;
804 }
805
806 return $result;
807 }
808
815 public function getLibStatut($mode = 0)
816 {
817 return $this->LibStatut($this->status, $mode);
818 }
819
820 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
821
829 public function LibStatut($status, $mode = 0)
830 {
831 // phpcs:enable
832 if (is_null($status)) {
833 return '';
834 }
835
836 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
837 global $langs;
838 //$langs->load("hrm");
839 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
840 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
841 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
842 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
843 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
844 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
845 }
846
847 $statusType = 'status' . $status;
848 //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
849 if ($status == self::STATUS_CANCELED) {
850 $statusType = 'status6';
851 }
852
853 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
854 }
855
870 public function showInputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = 0, $nonewbutton = 0)
871 {
872 global $langs;
873
874 if ($key == 'fk_user') {
875 $vacantId = $keyprefix.$key.'vacant'.$keysuffix;
876
877 $out = parent::showInputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss);
878 $out .= '<label class="nowrap position-fk-user classfortooltip" title="'.dol_escape_js($langs->trans('VacantCheckboxHelper')).'"><input type="checkbox" id="'.$vacantId.'" name="'.$vacantId.'" />&nbsp;'.$langs->trans("Vacant").'</label>'; ?>
879 <script type="text/javascript">
880 $(document).ready(function () {
881 var checkbox = $('#<?php print $vacantId; ?>');
882 var searchfkuser = $('#<?php print $keyprefix.$key.$keysuffix; ?>');
883 checkbox.click(function () {
884 if (checkbox.prop('checked')) {
885 searchfkuser.val(0).trigger('change');
886 searchfkuser.prop('disabled', 1);
887 } else {
888 searchfkuser.prop('disabled', 0);
889 }
890 });
891 });
892 </script>
893 <?php
894 } else {
895 $out = parent::showInputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss);
896 }
897
898 return $out;
899 }
900
914 public function showOutputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = '')
915 {
916 global $langs;
917
918 if ($key == 'fk_user' && $this->fk_user == 0) {
919 return $langs->trans("VacantPosition");
920 }
921 return parent::showOutputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss);
922 }
923
924
931 public function info($id)
932 {
933 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
934 $sql .= ' fk_user_creat, fk_user_modif';
935 $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
936 $sql .= ' WHERE t.rowid = ' . ((int) $id);
937 $result = $this->db->query($sql);
938 if ($result) {
939 if ($this->db->num_rows($result)) {
940 $obj = $this->db->fetch_object($result);
941
942 $this->id = $obj->rowid;
943
944 $this->user_creation_id = $obj->fk_user_creat;
945 $this->user_modification_id = $obj->fk_user_modif;
946 $this->date_creation = $this->db->jdate($obj->datec);
947 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
948 }
949
950 $this->db->free($result);
951 } else {
952 dol_print_error($this->db);
953 }
954 }
955
962 public function initAsSpecimen()
963 {
964 // Set here init that are not commonf fields
965 // $this->property1 = ...
966 // $this->property2 = ...
967
968 $this->initAsSpecimenCommon();
969 }
970
976 public function getLinesArray()
977 {
978 $this->lines = array();
979
980 $objectline = new PositionLine($this->db);
981 $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql' => 'fk_position = ' . $this->id));
982
983 if (is_numeric($result)) {
984 $this->error = $objectline->error;
985 $this->errors = $objectline->errors;
986 return $result;
987 } else {
988 $this->lines = $result;
989 return $this->lines;
990 }
991 }
992
998 public function getNextNumRef()
999 {
1000 global $langs, $conf;
1001 $langs->load("hrm");
1002
1003 if (!getDolGlobalString('hrm_POSITION_ADDON')) {
1004 $conf->global->hrm_POSITION_ADDON = 'mod_position_standard';
1005 }
1006
1007 if (getDolGlobalString('hrm_POSITION_ADDON')) {
1008 $mybool = false;
1009
1010 $file = getDolGlobalString('hrm_POSITION_ADDON') . ".php";
1011 $classname = $conf->global->hrm_POSITION_ADDON;
1012
1013 // Include file with class
1014 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1015 foreach ($dirmodels as $reldir) {
1016 $dir = dol_buildpath($reldir . "core/modules/hrm/");
1017
1018 // Load file with numbering class (if found)
1019 $mybool |= @include_once $dir . $file;
1020 }
1021
1022 if ($mybool === false) {
1023 dol_print_error('', "Failed to include file " . $file);
1024 return '';
1025 }
1026
1027 if (class_exists($classname)) {
1028 $obj = new $classname();
1029 $numref = $obj->getNextValue($this);
1030
1031 if ($numref != '' && $numref != '-1') {
1032 return $numref;
1033 } else {
1034 $this->error = $obj->error;
1035 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
1036 return "";
1037 }
1038 } else {
1039 print $langs->trans("Error") . " " . $langs->trans("ClassNotFound") . ' ' . $classname;
1040 return "";
1041 }
1042 } else {
1043 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1044 return "";
1045 }
1046 }
1047
1054 public function getForUser($userid)
1055 {
1056 $TPosition = array();
1057
1058 $TPosition = $this->fetchAll('ASC', 't.rowid', 0, 0, array('customsql' => 'fk_user=' . $userid));
1059
1060 return $TPosition;
1061 }
1062
1074 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1075 {
1076 global $conf, $langs;
1077
1078 $result = 0;
1079 $includedocgeneration = 0;
1080
1081 $langs->load("hrm");
1082
1083 if (!dol_strlen($modele)) {
1084 $modele = 'standard_position';
1085
1086 if (!empty($this->model_pdf)) {
1087 $modele = $this->model_pdf;
1088 } elseif (getDolGlobalString('POSITION_ADDON_PDF')) {
1089 $modele = $conf->global->POSITION_ADDON_PDF;
1090 }
1091 }
1092
1093 $modelpath = "core/modules/hrm/doc/";
1094
1095 if ($includedocgeneration && !empty($modele)) {
1096 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1097 }
1098
1099 return $result;
1100 }
1101
1109 public function doScheduledJob()
1110 {
1111 global $conf, $langs;
1112
1113 //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log';
1114
1115 $error = 0;
1116 $this->output = '';
1117 $this->error = '';
1118
1119 dol_syslog(__METHOD__, LOG_DEBUG);
1120
1121 $now = dol_now();
1122
1123 $this->db->begin();
1124
1125 // ...
1126
1127 $this->db->commit();
1128
1129 return $error;
1130 }
1131
1139 public function getKanbanView($option = '', $arraydata = null)
1140 {
1141 global $selected, $langs;
1142
1143 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1144
1145 $return = '<div class="box-flex-item box-flex-grow-zero">';
1146 $return .= '<div class="info-box info-box-sm">';
1147 $return .= '<span class="info-box-icon bg-infobox-action">';
1148 $return .= img_picto('', $this->picto);
1149 $return .= '</span>';
1150 $return .= '<div class="info-box-content">';
1151 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).'</span>';
1152 $return .= '<input class="fright" id="cb'.$this->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1153 if (!empty($arraydata['user'])) {
1154 $return .= '<br><span class="info-box-label ">'.$arraydata['user'].'</span>';
1155 }
1156 if (!empty($arraydata['job'])) {
1157 //$return .= '<br><span class="info-box-label opacitymedium">'.$langs->trans("JobProfile").'</span> : ';
1158 $return .= '<br><span class="info-box-label ">'.$arraydata['job'].'</span>';
1159 }
1160 if (property_exists($this, 'date_start') && property_exists($this, 'date_end')) {
1161 $return .= '<br><div class ="nothing"><span class="info-box-label ">'.dol_print_date($this->db->jdate($this->date_start), 'day').'</span>';
1162 $return .= ' - <span class="info-box-label ">'.dol_print_date($this->db->jdate($this->date_end), 'day').'</span></div>';
1163 }
1164 $return .= '</div>';
1165 $return .= '</div>';
1166 $return .= '</div>';
1167 return $return;
1168 }
1169}
1170
1171
1172require_once DOL_DOCUMENT_ROOT . '/core/class/commonobjectline.class.php';
1173
1178{
1179 // To complete with content of an object PositionLine
1180 // We should have a field rowid , fk_position and position
1181
1185 public $isextrafieldmanaged = 0;
1186
1192 public function __construct(DoliDB $db)
1193 {
1194 $this->db = $db;
1195 }
1196}
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 Position.
create(User $user, $notrigger=false)
Create object into database.
validate($user, $notrigger=0)
Validate object.
cancel($user, $notrigger=0)
Set cancel status.
info($id)
Load the info information in the object.
update(User $user, $notrigger=false)
Update object into database.
getLibStatut($mode=0)
Return the label of the status.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
deleteLine(User $user, $idline, $notrigger=false)
Delete a line of object in database.
getNextNumRef()
Returns the reference to the following non used object depending on the active numbering module.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionaly the picto)
getLinesArray()
Create an array of lines.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
setDraft($user, $notrigger=0)
Set draft status.
getKanbanView($option='', $arraydata=null)
Return clicable link of object (with eventually picto)
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, array $filter=array(), $filtermode='AND')
Load list of objects in memory from the database.
fetch($id, $ref=null)
Load object in memory from the database.
showInputField($val, $key, $value, $moreparam='', $keysuffix='', $keyprefix='', $morecss=0, $nonewbutton=0)
Return HTML string to put an input field into a page Code very similar with showInputField of extra f...
showOutputField($val, $key, $value, $moreparam='', $keysuffix='', $keyprefix='', $morecss='')
Return HTML string to show a field into a page Code very similar with showOutputField of extra fields...
doScheduledJob()
Action executed by scheduler CAN BE A CRON TASK.
LibStatut($status, $mode=0)
Return the status.
getForUser($userid)
getForUser
reopen($user, $notrigger=0)
Set back to validated status.
fetchLines()
Load object lines in memory from the database.
createFromClone(User $user, $fromid)
Clone an object into another one.
__construct(DoliDB $db)
Constructor.
Class PositionLine.
__construct(DoliDB $db)
Constructor.
Class to manage Dolibarr users.
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_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.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:121