dolibarr 20.0.0
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 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
8 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
30// Put here all includes required by your class file
31require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php';
32
37{
41 public $module = 'hrm';
42
46 public $element = 'position';
47
51 public $table_element = 'hrm_job_user';
52
56 public $picto = 'user-cog';
57
58
59 const STATUS_DRAFT = 0;
60 const STATUS_VALIDATED = 1;
61 const STATUS_CANCELED = 9;
62
63
90 // BEGIN MODULEBUILDER PROPERTIES
94 public $fields = array(
95 'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 2, 'index' => 1, 'css' => 'left', 'comment' => "Id"),
96 //'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"),
97 'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'position' => 500, 'notnull' => 1, 'visible' => -2,),
98 'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'position' => 501, 'notnull' => 0, 'visible' => -2,),
99 'fk_contrat' => array('type' => 'integer:Contrat:contrat/class/contrat.class.php', 'label' => 'fk_contrat', 'enabled' => 'isModEnabled("contract")', 'position' => 50, 'notnull' => 0, 'visible' => 0,),
100 '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'),
101 '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'),
102 'date_start' => array('type' => 'date', 'label' => 'DateStart', 'enabled' => 1, 'position' => 101, 'notnull' => 1, 'visible' => 1,),
103 'date_end' => array('type' => 'date', 'label' => 'DateEnd', 'enabled' => 1, 'position' => 102, 'notnull' => 0, 'visible' => 1,),
104 'description' => array('type' => 'text', 'label' => 'Description', 'enabled' => 1, 'position' => 120, 'notnull' => 0, 'visible' => 3,),
105 'abort_comment' => array('type' => 'varchar(255)', 'label' => 'AbandonmentComment', 'enabled' => 'getDolGlobalInt("HRM_JOB_POSITON_ENDING_COMMENT")', 'position' => 502, 'notnull' => 0, 'visible' => 1,),
106 'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'position' => 151, 'notnull' => 0, 'visible' => 0,),
107 'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'position' => 152, 'notnull' => 0, 'visible' => 0,),
108 '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',),
109 'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'position' => 511, 'notnull' => -1, 'visible' => -2,),
110 );
111 public $rowid;
112 public $ref;
113 public $description;
114 public $date_creation;
115 public $fk_contrat;
116 public $fk_user;
117 public $fk_job;
118 public $date_start;
119 public $date_end;
120 public $abort_comment;
121 public $note_public;
122 public $note_private;
123 public $fk_user_creat;
124 public $fk_user_modif;
125
126
127 // END MODULEBUILDER PROPERTIES
128
129
130 // If this object has a subtable with lines
131
132 // /**
133 // * @var string Name of subtable line
134 // */
135 // public $table_element_line = 'hrm_job_userline';
136
137 // /**
138 // * @var string Field with ID of parent key if this object has a parent
139 // */
140 // public $fk_element = 'fk_position';
141
142 // /**
143 // * @var string Name of subtable class that manage subtable lines
144 // */
145 // public $class_element_line = 'Positionline';
146
147 // /**
148 // * @var array List of child tables. To test if we can delete object.
149 // */
150 // protected $childtables = array();
151
152 // /**
153 // * @var array List of child tables. To know object to delete on cascade.
154 // * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will
155 // * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object
156 // */
157 // protected $childtablesoncascade = array('hrm_job_userdet');
158
159 // /**
160 // * @var PositionLine[] Array of subtable lines
161 // */
162 // public $lines = array();
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 = 0;
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->position->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 if ($result > 0 && !empty($object->table_element_line)) {
248 $object->fetchLines();
249 }
250
251 // get lines so they will be clone
252 //foreach($this->lines as $line)
253 // $line->fetch_optionals();
254
255 // Reset some properties
256 unset($object->id);
257 unset($object->fk_user_creat);
258 unset($object->import_key);
259
260 // Clear fields
261 if (property_exists($object, 'ref')) {
262 $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_" . $object->ref : $this->fields['ref']['default'];
263 }
264 if (property_exists($object, 'label')) {
265 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf") . " " . $object->label : $this->fields['label']['default'];
266 }
267 if (property_exists($object, 'status')) {
268 $object->status = self::STATUS_DRAFT;
269 }
270 if (property_exists($object, 'date_creation')) {
271 $object->date_creation = dol_now();
272 }
273 if (property_exists($object, 'date_modification')) {
274 $object->date_modification = null;
275 }
276 // ...
277 // Clear extrafields that are unique
278 if (is_array($object->array_options) && count($object->array_options) > 0) {
279 $extrafields->fetch_name_optionals_label($this->table_element);
280 foreach ($object->array_options as $key => $option) {
281 $shortkey = preg_replace('/options_/', '', $key);
282 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
283 //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
284 unset($object->array_options[$key]);
285 }
286 }
287 }
288
289 // Create clone
290 $object->context['createfromclone'] = 'createfromclone';
291 $result = $object->createCommon($user);
292 if ($result < 0) {
293 $error++;
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
367 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
368 {
369 dol_syslog(__METHOD__, LOG_DEBUG);
370
371 $records = array();
372
373 $sql = 'SELECT ';
374 $sql .= $this->getFieldList('t');
375 $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
376 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
377 $sql .= ' WHERE t.entity IN (' . getEntity($this->element) . ')';
378 } else {
379 $sql .= ' WHERE 1 = 1';
380 }
381
382 // Manage filter
383 $errormessage = '';
384 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
385 if ($errormessage) {
386 $this->errors[] = $errormessage;
387 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
388 return -1;
389 }
390
391 if (!empty($sortfield)) {
392 $sql .= $this->db->order($sortfield, $sortorder);
393 }
394 if (!empty($limit)) {
395 $sql .= ' ' . $this->db->plimit($limit, $offset);
396 }
397
398 $resql = $this->db->query($sql);
399 if ($resql) {
400 $num = $this->db->num_rows($resql);
401 $i = 0;
402 while ($i < ($limit ? min($limit, $num) : $num)) {
403 $obj = $this->db->fetch_object($resql);
404
405 $record = new self($this->db);
406 $record->setVarsFromFetchObj($obj);
407
408 $records[$record->id] = $record;
409
410 $i++;
411 }
412 $this->db->free($resql);
413
414 return $records;
415 } else {
416 $this->errors[] = 'Error ' . $this->db->lasterror();
417 dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR);
418
419 return -1;
420 }
421 }
422
430 public function update(User $user, $notrigger = 0)
431 {
432 return $this->updateCommon($user, $notrigger);
433 }
434
442 public function delete(User $user, $notrigger = 0)
443 {
444 return $this->deleteCommon($user, $notrigger);
445 //return $this->deleteCommon($user, $notrigger, 1);
446 }
447
456 public function deleteLine(User $user, $idline, $notrigger = 0)
457 {
458 if ($this->status < 0) {
459 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
460 return -2;
461 }
462
463 return $this->deleteLineCommon($user, $idline, $notrigger);
464 }
465
466
474 public function validate($user, $notrigger = 0)
475 {
476 global $conf, $langs;
477
478 require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
479
480 $error = 0;
481
482 // Protection
483 if ($this->status == self::STATUS_VALIDATED) {
484 dol_syslog(get_class($this) . "::validate action abandoned: already validated", LOG_WARNING);
485 return 0;
486 }
487
488 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->position->write))
489 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->position->position_advance->validate))))
490 {
491 $this->error='NotEnoughPermissions';
492 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
493 return -1;
494 }*/
495
496 $now = dol_now();
497
498 $this->db->begin();
499
500 // Define new ref
501 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
502 $num = $this->getNextNumRef();
503 } else {
504 $num = $this->ref;
505 }
506 $this->newref = $num;
507
508 if (!empty($num)) {
509 // Validate
510 $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
511 $sql .= " SET ref = '" . $this->db->escape($num) . "',";
512 $sql .= " status = " . self::STATUS_VALIDATED;
513 if (!empty($this->fields['date_validation'])) {
514 $sql .= ", date_validation = '" . $this->db->idate($now) . "'";
515 }
516 if (!empty($this->fields['fk_user_valid'])) {
517 $sql .= ", fk_user_valid = " . ((int) $user->id);
518 }
519 $sql .= " WHERE rowid = " . ((int) $this->id);
520
521 dol_syslog(get_class($this) . "::validate()", LOG_DEBUG);
522 $resql = $this->db->query($sql);
523 if (!$resql) {
524 dol_print_error($this->db);
525 $this->error = $this->db->lasterror();
526 $error++;
527 }
528
529 if (!$error && !$notrigger) {
530 // Call trigger
531 $result = $this->call_trigger('HRM_POSITION_VALIDATE', $user);
532 if ($result < 0) {
533 $error++;
534 }
535 // End call triggers
536 }
537 }
538
539 if (!$error) {
540 $this->oldref = $this->ref;
541
542 // Rename directory if dir was a temporary ref
543 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
544 // Now we rename also files into index
545 $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) . "'";
546 $sql .= " WHERE filename LIKE '" . $this->db->escape($this->ref) . "%' AND filepath = 'position/" . $this->db->escape($this->ref) . "' and entity = " . $conf->entity;
547 $resql = $this->db->query($sql);
548 if (!$resql) {
549 $error++;
550 $this->error = $this->db->lasterror();
551 }
552 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'position/".$this->db->escape($this->newref)."'";
553 $sql .= " WHERE filepath = 'position/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
554 $resql = $this->db->query($sql);
555 if (!$resql) {
556 $error++;
557 $this->error = $this->db->lasterror();
558 }
559
560 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
561 $oldref = dol_sanitizeFileName($this->ref);
562 $newref = dol_sanitizeFileName($num);
563 $dirsource = $conf->hrm->dir_output . '/position/' . $oldref;
564 $dirdest = $conf->hrm->dir_output . '/position/' . $newref;
565 if (!$error && file_exists($dirsource)) {
566 dol_syslog(get_class($this) . "::validate() rename dir " . $dirsource . " into " . $dirdest);
567
568 if (@rename($dirsource, $dirdest)) {
569 dol_syslog("Rename ok");
570 // Rename docs starting with $oldref with $newref
571 $listoffiles = dol_dir_list($conf->hrm->dir_output . '/position/' . $newref, 'files', 1, '^' . preg_quote($oldref, '/'));
572 foreach ($listoffiles as $fileentry) {
573 $dirsource = $fileentry['name'];
574 $dirdest = preg_replace('/^' . preg_quote($oldref, '/') . '/', $newref, $dirsource);
575 $dirsource = $fileentry['path'] . '/' . $dirsource;
576 $dirdest = $fileentry['path'] . '/' . $dirdest;
577 @rename($dirsource, $dirdest);
578 }
579 }
580 }
581 }
582 }
583
584 // Set new ref and current status
585 if (!$error) {
586 $this->ref = $num;
587 $this->status = self::STATUS_VALIDATED;
588 }
589
590 if (!$error) {
591 $this->db->commit();
592 return 1;
593 } else {
594 $this->db->rollback();
595 return -1;
596 }
597 }
598
599
607 public function setDraft($user, $notrigger = 0)
608 {
609 // Protection
610 if ($this->status <= self::STATUS_DRAFT) {
611 return 0;
612 }
613
614 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
615 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
616 {
617 $this->error='Permission denied';
618 return -1;
619 }*/
620
621 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'POSITION_UNVALIDATE');
622 }
623
631 public function cancel($user, $notrigger = 0)
632 {
633 // Protection
634 if ($this->status != self::STATUS_VALIDATED) {
635 return 0;
636 }
637
638 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
639 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
640 {
641 $this->error='Permission denied';
642 return -1;
643 }*/
644
645 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'POSITION_CANCEL');
646 }
647
655 public function reopen($user, $notrigger = 0)
656 {
657 // Protection
658 if ($this->status != self::STATUS_CANCELED) {
659 return 0;
660 }
661
662 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
663 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
664 {
665 $this->error='Permission denied';
666 return -1;
667 }*/
668
669 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'POSITION_REOPEN');
670 }
671
682 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
683 {
684 global $conf, $langs, $hookmanager;
685
686 if (!empty($conf->dol_no_mouse_hover)) {
687 $notooltip = 1; // Force disable tooltips
688 }
689
690 $result = '';
691
692 $label = img_picto('', $this->picto) . ' <u>' . $langs->trans("Position") . '</u>';
693 if (isset($this->status)) {
694 $label .= ' ' . $this->getLibStatut(5);
695 }
696 $label .= '<br>';
697 $label .= '<b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
698
699 $url = dol_buildpath('/hrm/position_card.php', 1) . '?id=' . $this->id;
700
701 if ($option != 'nolink') {
702 // Add param to save lastsearch_values or not
703 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
704 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
705 $add_save_lastsearch_values = 1;
706 }
707 if ($add_save_lastsearch_values) {
708 $url .= '&save_lastsearch_values=1';
709 }
710 }
711
712 $linkclose = '';
713 if (empty($notooltip)) {
714 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
715 $label = $langs->trans("ShowPosition");
716 $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"';
717 }
718 $linkclose .= ' title="' . dol_escape_htmltag($label, 1) . '"';
719 $linkclose .= ' class="classfortooltip' . ($morecss ? ' ' . $morecss : '') . '"';
720 } else {
721 $linkclose = ($morecss ? ' class="' . $morecss . '"' : '');
722 }
723
724 if ($option == 'nolink') {
725 $linkstart = '<span';
726 } else {
727 $linkstart = '<a href="' . $url . '"';
728 }
729 $linkstart .= $linkclose . '>';
730 if ($option == 'nolink') {
731 $linkend = '</span>';
732 } else {
733 $linkend = '</a>';
734 }
735
736 $result .= $linkstart;
737
738 if (empty($this->showphoto_on_popup)) {
739 if ($withpicto) {
740 $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);
741 }
742 } else {
743 if ($withpicto) {
744 require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
745
746 list($class, $module) = explode('@', $this->picto);
747 $upload_dir = $conf->$module->multidir_output[$conf->entity] . "/$class/" . dol_sanitizeFileName($this->ref);
748 $filearray = dol_dir_list($upload_dir, "files");
749 $filename = $filearray[0]['name'];
750 if (!empty($filename)) {
751 $pospoint = strpos($filearray[0]['name'], '.');
752
753 $pathtophoto = $class . '/' . $this->ref . '/thumbs/' . substr($filename, 0, $pospoint) . '_mini' . substr($filename, $pospoint);
754 if (!getDolGlobalString(strtoupper($module . '_' . $class) . '_FORMATLISTPHOTOSASUSERS')) {
755 $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>';
756 } else {
757 $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>';
758 }
759
760 $result .= '</div>';
761 } else {
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 }
765 }
766
767 if ($withpicto != 2) {
768 $result .= $this->ref;
769 }
770
771 $result .= $linkend;
772 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
773
774 global $action, $hookmanager;
775 $hookmanager->initHooks(array('positiondao'));
776 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
777 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
778 if ($reshook > 0) {
779 $result = $hookmanager->resPrint;
780 } else {
781 $result .= $hookmanager->resPrint;
782 }
783
784 return $result;
785 }
786
793 public function getLibStatut($mode = 0)
794 {
795 return $this->LibStatut($this->status, $mode);
796 }
797
798 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
799
807 public function LibStatut($status, $mode = 0)
808 {
809 // phpcs:enable
810 if (is_null($status)) {
811 return '';
812 }
813
814 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
815 global $langs;
816 //$langs->load("hrm");
817 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
818 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
819 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
820 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
821 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
822 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
823 }
824
825 $statusType = 'status' . $status;
826 //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
827 if ($status == self::STATUS_CANCELED) {
828 $statusType = 'status6';
829 }
830
831 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
832 }
833
848 public function showInputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = 0, $nonewbutton = 0)
849 {
850 global $langs;
851
852 if ($key == 'fk_user') {
853 $vacantId = $keyprefix.$key.'vacant'.$keysuffix;
854
855 $out = parent::showInputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss);
856 $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>'; ?>
857 <script type="text/javascript">
858 $(document).ready(function () {
859 var checkbox = $('#<?php print $vacantId; ?>');
860 var searchfkuser = $('#<?php print $keyprefix.$key.$keysuffix; ?>');
861 checkbox.click(function () {
862 if (checkbox.prop('checked')) {
863 searchfkuser.val(0).trigger('change');
864 searchfkuser.prop('disabled', 1);
865 } else {
866 searchfkuser.prop('disabled', 0);
867 }
868 });
869 });
870 </script>
871 <?php
872 } else {
873 $out = parent::showInputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss);
874 }
875
876 return $out;
877 }
878
892 public function showOutputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = '')
893 {
894 global $langs;
895
896 if ($key == 'fk_user' && $this->fk_user == 0) {
897 return $langs->trans("VacantPosition");
898 }
899 return parent::showOutputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss);
900 }
901
902
909 public function info($id)
910 {
911 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
912 $sql .= ' fk_user_creat, fk_user_modif';
913 $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
914 $sql .= ' WHERE t.rowid = ' . ((int) $id);
915 $result = $this->db->query($sql);
916 if ($result) {
917 if ($this->db->num_rows($result)) {
918 $obj = $this->db->fetch_object($result);
919
920 $this->id = $obj->rowid;
921
922 $this->user_creation_id = $obj->fk_user_creat;
923 $this->user_modification_id = $obj->fk_user_modif;
924 $this->date_creation = $this->db->jdate($obj->datec);
925 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
926 }
927
928 $this->db->free($result);
929 } else {
930 dol_print_error($this->db);
931 }
932 }
933
940 public function initAsSpecimen()
941 {
942 // Set here init that are not commonf fields
943 // $this->property1 = ...
944 // $this->property2 = ...
945
946 return $this->initAsSpecimenCommon();
947 }
948
954 public function getLinesArray()
955 {
956 $this->lines = array();
957
958 $objectline = new PositionLine($this->db);
959 $result = $objectline->fetchAll('ASC', 'position', 0, 0, '(fk_position:=:'.((int) $this->id).')');
960
961 if (is_numeric($result)) {
962 $this->setErrorsFromObject($objectline);
963 return $result;
964 } else {
965 $this->lines = $result;
966 return $this->lines;
967 }
968 }
969
975 public function getNextNumRef()
976 {
977 global $langs, $conf;
978 $langs->load("hrm");
979
980 if (!getDolGlobalString('hrm_POSITION_ADDON')) {
981 $conf->global->hrm_POSITION_ADDON = 'mod_position_standard';
982 }
983
984 if (getDolGlobalString('hrm_POSITION_ADDON')) {
985 $mybool = false;
986
987 $file = getDolGlobalString('hrm_POSITION_ADDON') . ".php";
988 $classname = getDolGlobalString('hrm_POSITION_ADDON');
989
990 // Include file with class
991 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
992 foreach ($dirmodels as $reldir) {
993 $dir = dol_buildpath($reldir . "core/modules/hrm/");
994
995 // Load file with numbering class (if found)
996 $mybool = ((bool) @include_once $dir.$file) || $mybool;
997 }
998
999 if ($mybool === false) {
1000 dol_print_error(null, "Failed to include file " . $file);
1001 return '';
1002 }
1003
1004 if (class_exists($classname)) {
1005 $obj = new $classname();
1006 $numref = $obj->getNextValue($this);
1007
1008 if ($numref != '' && $numref != '-1') {
1009 return $numref;
1010 } else {
1011 $this->error = $obj->error;
1012 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
1013 return "";
1014 }
1015 } else {
1016 print $langs->trans("Error") . " " . $langs->trans("ClassNotFound") . ' ' . $classname;
1017 return "";
1018 }
1019 } else {
1020 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1021 return "";
1022 }
1023 }
1024
1031 public function getForUser($userid)
1032 {
1033 $TPosition = array();
1034
1035 $TPosition = $this->fetchAll('ASC', 't.rowid', 0, 0, '(fk_user:=:'.((int) $userid).')');
1036
1037 return $TPosition;
1038 }
1039
1051 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1052 {
1053 global $conf, $langs;
1054
1055 $result = 0;
1056 $includedocgeneration = 0;
1057
1058 $langs->load("hrm");
1059
1060 if (!dol_strlen($modele)) {
1061 $modele = 'standard_position';
1062
1063 if (!empty($this->model_pdf)) {
1064 $modele = $this->model_pdf;
1065 } elseif (getDolGlobalString('POSITION_ADDON_PDF')) {
1066 $modele = getDolGlobalString('POSITION_ADDON_PDF');
1067 }
1068 }
1069
1070 $modelpath = "core/modules/hrm/doc/";
1071
1072 if ($includedocgeneration && !empty($modele)) {
1073 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1074 }
1075
1076 return $result;
1077 }
1078
1086 public function getKanbanView($option = '', $arraydata = null)
1087 {
1088 global $selected, $langs;
1089
1090 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1091
1092 $return = '<div class="box-flex-item box-flex-grow-zero">';
1093 $return .= '<div class="info-box info-box-sm">';
1094 $return .= '<span class="info-box-icon bg-infobox-action">';
1095 $return .= img_picto('', $this->picto);
1096 $return .= '</span>';
1097 $return .= '<div class="info-box-content">';
1098 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).'</span>';
1099 $return .= '<input class="fright" id="cb'.$this->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1100 if (!empty($arraydata['user'])) {
1101 $return .= '<br><span class="info-box-label ">'.$arraydata['user'].'</span>';
1102 }
1103 if (!empty($arraydata['job'])) {
1104 //$return .= '<br><span class="info-box-label opacitymedium">'.$langs->trans("JobProfile").'</span> : ';
1105 $return .= '<br><span class="info-box-label ">'.$arraydata['job'].'</span>';
1106 }
1107 if (property_exists($this, 'date_start') && property_exists($this, 'date_end')) {
1108 $return .= '<br><div class ="nothing"><span class="info-box-label ">'.dol_print_date($this->db->jdate($this->date_start), 'day').'</span>';
1109 $return .= ' - <span class="info-box-label ">'.dol_print_date($this->db->jdate($this->date_end), 'day').'</span></div>';
1110 }
1111 $return .= '</div>';
1112 $return .= '</div>';
1113 $return .= '</div>';
1114 return $return;
1115 }
1116}
1117
1118
1119require_once DOL_DOCUMENT_ROOT . '/core/class/commonobjectline.class.php';
1120
1125{
1126 // To complete with content of an object PositionLine
1127 // We should have a field rowid , fk_position and position
1128
1134 public function __construct(DoliDB $db)
1135 {
1136 $this->db = $db;
1137
1138 $this->isextrafieldmanaged = 0;
1139 }
1140}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition security.php:636
$object ref
Definition info.php:79
Parent class of all other business classes (invoices, contracts, proposals, orders,...
deleteLineCommon(User $user, $idline, $notrigger=0)
Delete a line of object in database.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
setErrorsFromObject($object)
setErrorsFromObject
createCommon(User $user, $notrigger=0)
Create object in the database.
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
updateCommon(User $user, $notrigger=0)
Update object into database.
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
initAsSpecimenCommon()
Initialise object with example values Id must be 0 if object instance is a specimen.
copy_linked_contact($objFrom, $source='internal')
Copy contact from one element to current.
fetchLinesCommon($morewhere='', $noextrafields=0)
Load object in memory from the database.
fetchCommon($id, $ref=null, $morewhere='', $noextrafields=0)
Load object in memory from the database.
deleteCommon(User $user, $notrigger=0, $forcechilddeletion=0)
Delete object in database.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage Dolibarr database access.
Class for Position.
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=0)
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.
fetchAll($sortorder='', $sortfield='', $limit=0, $offset=0, $filter='', $filtermode='AND')
Load list of objects in memory from the 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 optionally 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)
deleteLine(User $user, $idline, $notrigger=0)
Delete a line of object in 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...
create(User $user, $notrigger=0)
Create object into database.
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...
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($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:63
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0)
forgeSQLFromUniversalSearchCriteria
dol_now($mode='auto')
Return date for now.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
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:139