dolibarr 21.0.0-alpha
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 $fk_contrat;
115 public $fk_user;
116 public $fk_job;
117 public $date_start;
118 public $date_end;
119 public $abort_comment;
120 public $note_public;
121 public $note_private;
122 public $fk_user_creat;
123 public $fk_user_modif;
124
125
126 // END MODULEBUILDER PROPERTIES
127
128
129 // If this object has a subtable with lines
130
131 // /**
132 // * @var string Name of subtable line
133 // */
134 // public $table_element_line = 'hrm_job_userline';
135
136 // /**
137 // * @var string Field with ID of parent key if this object has a parent
138 // */
139 // public $fk_element = 'fk_position';
140
141 // /**
142 // * @var string Name of subtable class that manage subtable lines
143 // */
144 // public $class_element_line = 'Positionline';
145
146 // /**
147 // * @var array List of child tables. To test if we can delete object.
148 // */
149 // protected $childtables = array();
150
151 // /**
152 // * @var array List of child tables. To know object to delete on cascade.
153 // * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will
154 // * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object
155 // */
156 // protected $childtablesoncascade = array('hrm_job_userdet');
157
158 // /**
159 // * @var PositionLine[] Array of subtable lines
160 // */
161 // public $lines = array();
162
163
169 public function __construct(DoliDB $db)
170 {
171 global $conf, $langs;
172
173 $this->db = $db;
174
175 $this->ismultientitymanaged = 0;
176 $this->isextrafieldmanaged = 0;
177
178 if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
179 //$this->fields['rowid']['visible'] = 0;
180 }
181 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
182 $this->fields['entity']['enabled'] = 0;
183 }
184
185 // Example to show how to set values of fields definition dynamically
186 /*if ($user->rights->hrm->position->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 = 0)
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++;
294 }
295
296 if (!$error) {
297 // copy internal contacts
298 if ($this->copy_linked_contact($object, 'internal') < 0) {
299 $error++;
300 }
301 }
302
303 if (!$error) {
304 // copy external contacts if same company
305 if (property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
306 if ($this->copy_linked_contact($object, 'external') < 0) {
307 $error++;
308 }
309 }
310 }
311
312 unset($object->context['createfromclone']);
313
314 // End
315 if (!$error) {
316 $this->db->commit();
317 return $object;
318 } else {
319 $this->db->rollback();
320 return -1;
321 }
322 }
323
331 public function fetch($id, $ref = null)
332 {
333 $result = $this->fetchCommon($id, $ref);
334 if ($result > 0 && !empty($this->table_element_line)) {
335 $this->fetchLines();
336 }
337 return $result;
338 }
339
345 public function fetchLines()
346 {
347 $this->lines = array();
348
349 $result = $this->fetchLinesCommon();
350 return $result;
351 }
352
353
366 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
367 {
368 dol_syslog(__METHOD__, LOG_DEBUG);
369
370 $records = array();
371
372 $sql = 'SELECT ';
373 $sql .= $this->getFieldList('t');
374 $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
375 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
376 $sql .= ' WHERE t.entity IN (' . getEntity($this->element) . ')';
377 } else {
378 $sql .= ' WHERE 1 = 1';
379 }
380
381 // Manage filter
382 $errormessage = '';
383 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
384 if ($errormessage) {
385 $this->errors[] = $errormessage;
386 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
387 return -1;
388 }
389
390 if (!empty($sortfield)) {
391 $sql .= $this->db->order($sortfield, $sortorder);
392 }
393 if (!empty($limit)) {
394 $sql .= ' ' . $this->db->plimit($limit, $offset);
395 }
396
397 $resql = $this->db->query($sql);
398 if ($resql) {
399 $num = $this->db->num_rows($resql);
400 $i = 0;
401 while ($i < ($limit ? min($limit, $num) : $num)) {
402 $obj = $this->db->fetch_object($resql);
403
404 $record = new self($this->db);
405 $record->setVarsFromFetchObj($obj);
406
407 $records[$record->id] = $record;
408
409 $i++;
410 }
411 $this->db->free($resql);
412
413 return $records;
414 } else {
415 $this->errors[] = 'Error ' . $this->db->lasterror();
416 dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR);
417
418 return -1;
419 }
420 }
421
429 public function update(User $user, $notrigger = 0)
430 {
431 return $this->updateCommon($user, $notrigger);
432 }
433
441 public function delete(User $user, $notrigger = 0)
442 {
443 return $this->deleteCommon($user, $notrigger);
444 //return $this->deleteCommon($user, $notrigger, 1);
445 }
446
455 public function deleteLine(User $user, $idline, $notrigger = 0)
456 {
457 if ($this->status < 0) {
458 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
459 return -2;
460 }
461
462 return $this->deleteLineCommon($user, $idline, $notrigger);
463 }
464
465
473 public function validate($user, $notrigger = 0)
474 {
475 global $conf, $langs;
476
477 require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
478
479 $error = 0;
480
481 // Protection
482 if ($this->status == self::STATUS_VALIDATED) {
483 dol_syslog(get_class($this) . "::validate action abandoned: already validated", LOG_WARNING);
484 return 0;
485 }
486
487 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->position->write))
488 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->position->position_advance->validate))))
489 {
490 $this->error='NotEnoughPermissions';
491 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
492 return -1;
493 }*/
494
495 $now = dol_now();
496
497 $this->db->begin();
498
499 // Define new ref
500 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
501 $num = $this->getNextNumRef();
502 } else {
503 $num = $this->ref;
504 }
505 $this->newref = $num;
506
507 if (!empty($num)) {
508 // Validate
509 $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
510 $sql .= " SET ref = '" . $this->db->escape($num) . "',";
511 $sql .= " status = " . self::STATUS_VALIDATED;
512 if (!empty($this->fields['date_validation'])) {
513 $sql .= ", date_validation = '" . $this->db->idate($now) . "'";
514 }
515 if (!empty($this->fields['fk_user_valid'])) {
516 $sql .= ", fk_user_valid = " . ((int) $user->id);
517 }
518 $sql .= " WHERE rowid = " . ((int) $this->id);
519
520 dol_syslog(get_class($this) . "::validate()", LOG_DEBUG);
521 $resql = $this->db->query($sql);
522 if (!$resql) {
523 dol_print_error($this->db);
524 $this->error = $this->db->lasterror();
525 $error++;
526 }
527
528 if (!$error && !$notrigger) {
529 // Call trigger
530 $result = $this->call_trigger('HRM_POSITION_VALIDATE', $user);
531 if ($result < 0) {
532 $error++;
533 }
534 // End call triggers
535 }
536 }
537
538 if (!$error) {
539 $this->oldref = $this->ref;
540
541 // Rename directory if dir was a temporary ref
542 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
543 // Now we rename also files into index
544 $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) . "'";
545 $sql .= " WHERE filename LIKE '" . $this->db->escape($this->ref) . "%' AND filepath = 'position/" . $this->db->escape($this->ref) . "' and entity = " . $conf->entity;
546 $resql = $this->db->query($sql);
547 if (!$resql) {
548 $error++;
549 $this->error = $this->db->lasterror();
550 }
551 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'position/".$this->db->escape($this->newref)."'";
552 $sql .= " WHERE filepath = 'position/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
553 $resql = $this->db->query($sql);
554 if (!$resql) {
555 $error++;
556 $this->error = $this->db->lasterror();
557 }
558
559 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
560 $oldref = dol_sanitizeFileName($this->ref);
561 $newref = dol_sanitizeFileName($num);
562 $dirsource = $conf->hrm->dir_output . '/position/' . $oldref;
563 $dirdest = $conf->hrm->dir_output . '/position/' . $newref;
564 if (!$error && file_exists($dirsource)) {
565 dol_syslog(get_class($this) . "::validate() rename dir " . $dirsource . " into " . $dirdest);
566
567 if (@rename($dirsource, $dirdest)) {
568 dol_syslog("Rename ok");
569 // Rename docs starting with $oldref with $newref
570 $listoffiles = dol_dir_list($conf->hrm->dir_output . '/position/' . $newref, 'files', 1, '^' . preg_quote($oldref, '/'));
571 foreach ($listoffiles as $fileentry) {
572 $dirsource = $fileentry['name'];
573 $dirdest = preg_replace('/^' . preg_quote($oldref, '/') . '/', $newref, $dirsource);
574 $dirsource = $fileentry['path'] . '/' . $dirsource;
575 $dirdest = $fileentry['path'] . '/' . $dirdest;
576 @rename($dirsource, $dirdest);
577 }
578 }
579 }
580 }
581 }
582
583 // Set new ref and current status
584 if (!$error) {
585 $this->ref = $num;
586 $this->status = self::STATUS_VALIDATED;
587 }
588
589 if (!$error) {
590 $this->db->commit();
591 return 1;
592 } else {
593 $this->db->rollback();
594 return -1;
595 }
596 }
597
598
606 public function setDraft($user, $notrigger = 0)
607 {
608 // Protection
609 if ($this->status <= self::STATUS_DRAFT) {
610 return 0;
611 }
612
613 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
614 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
615 {
616 $this->error='Permission denied';
617 return -1;
618 }*/
619
620 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'POSITION_UNVALIDATE');
621 }
622
630 public function cancel($user, $notrigger = 0)
631 {
632 // Protection
633 if ($this->status != self::STATUS_VALIDATED) {
634 return 0;
635 }
636
637 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
638 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
639 {
640 $this->error='Permission denied';
641 return -1;
642 }*/
643
644 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'POSITION_CANCEL');
645 }
646
654 public function reopen($user, $notrigger = 0)
655 {
656 // Protection
657 if ($this->status != self::STATUS_CANCELED) {
658 return 0;
659 }
660
661 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
662 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
663 {
664 $this->error='Permission denied';
665 return -1;
666 }*/
667
668 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'POSITION_REOPEN');
669 }
670
681 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
682 {
683 global $conf, $langs, $hookmanager;
684
685 if (!empty($conf->dol_no_mouse_hover)) {
686 $notooltip = 1; // Force disable tooltips
687 }
688
689 $result = '';
690
691 $label = img_picto('', $this->picto) . ' <u>' . $langs->trans("Position") . '</u>';
692 if (isset($this->status)) {
693 $label .= ' ' . $this->getLibStatut(5);
694 }
695 $label .= '<br>';
696 $label .= '<b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
697
698 $url = dol_buildpath('/hrm/position_card.php', 1) . '?id=' . $this->id;
699
700 if ($option != 'nolink') {
701 // Add param to save lastsearch_values or not
702 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
703 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
704 $add_save_lastsearch_values = 1;
705 }
706 if ($add_save_lastsearch_values) {
707 $url .= '&save_lastsearch_values=1';
708 }
709 }
710
711 $linkclose = '';
712 if (empty($notooltip)) {
713 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
714 $label = $langs->trans("ShowPosition");
715 $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"';
716 }
717 $linkclose .= ' title="' . dol_escape_htmltag($label, 1) . '"';
718 $linkclose .= ' class="classfortooltip' . ($morecss ? ' ' . $morecss : '') . '"';
719 } else {
720 $linkclose = ($morecss ? ' class="' . $morecss . '"' : '');
721 }
722
723 if ($option == 'nolink') {
724 $linkstart = '<span';
725 } else {
726 $linkstart = '<a href="' . $url . '"';
727 }
728 $linkstart .= $linkclose . '>';
729 if ($option == 'nolink') {
730 $linkend = '</span>';
731 } else {
732 $linkend = '</a>';
733 }
734
735 $result .= $linkstart;
736
737 if (empty($this->showphoto_on_popup)) {
738 if ($withpicto) {
739 $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);
740 }
741 } else {
742 if ($withpicto) {
743 require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
744
745 list($class, $module) = explode('@', $this->picto);
746 $upload_dir = $conf->$module->multidir_output[$conf->entity] . "/$class/" . dol_sanitizeFileName($this->ref);
747 $filearray = dol_dir_list($upload_dir, "files");
748 $filename = $filearray[0]['name'];
749 if (!empty($filename)) {
750 $pospoint = strpos($filearray[0]['name'], '.');
751
752 $pathtophoto = $class . '/' . $this->ref . '/thumbs/' . substr($filename, 0, $pospoint) . '_mini' . substr($filename, $pospoint);
753 if (!getDolGlobalString(strtoupper($module . '_' . $class) . '_FORMATLISTPHOTOSASUSERS')) {
754 $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>';
755 } else {
756 $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>';
757 }
758
759 $result .= '</div>';
760 } else {
761 $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);
762 }
763 }
764 }
765
766 if ($withpicto != 2) {
767 $result .= $this->ref;
768 }
769
770 $result .= $linkend;
771 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
772
773 global $action, $hookmanager;
774 $hookmanager->initHooks(array('positiondao'));
775 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
776 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
777 if ($reshook > 0) {
778 $result = $hookmanager->resPrint;
779 } else {
780 $result .= $hookmanager->resPrint;
781 }
782
783 return $result;
784 }
785
792 public function getLibStatut($mode = 0)
793 {
794 return $this->LibStatut($this->status, $mode);
795 }
796
797 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
798
806 public function LibStatut($status, $mode = 0)
807 {
808 // phpcs:enable
809 if (is_null($status)) {
810 return '';
811 }
812
813 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
814 global $langs;
815 //$langs->load("hrm");
816 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
817 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
818 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
819 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
820 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
821 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
822 }
823
824 $statusType = 'status' . $status;
825 //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
826 if ($status == self::STATUS_CANCELED) {
827 $statusType = 'status6';
828 }
829
830 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
831 }
832
847 public function showInputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = 0, $nonewbutton = 0)
848 {
849 global $langs;
850
851 if ($key == 'fk_user') {
852 $vacantId = $keyprefix.$key.'vacant'.$keysuffix;
853
854 $out = parent::showInputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss);
855 $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>'; ?>
856 <script type="text/javascript">
857 $(document).ready(function () {
858 var checkbox = $('#<?php print $vacantId; ?>');
859 var searchfkuser = $('#<?php print $keyprefix.$key.$keysuffix; ?>');
860 checkbox.click(function () {
861 if (checkbox.prop('checked')) {
862 searchfkuser.val(0).trigger('change');
863 searchfkuser.prop('disabled', 1);
864 } else {
865 searchfkuser.prop('disabled', 0);
866 }
867 });
868 });
869 </script>
870 <?php
871 } else {
872 $out = parent::showInputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss);
873 }
874
875 return $out;
876 }
877
891 public function showOutputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = '')
892 {
893 global $langs;
894
895 if ($key == 'fk_user' && $this->fk_user == 0) {
896 return $langs->trans("VacantPosition");
897 }
898 return parent::showOutputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss);
899 }
900
901
908 public function info($id)
909 {
910 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
911 $sql .= ' fk_user_creat, fk_user_modif';
912 $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
913 $sql .= ' WHERE t.rowid = ' . ((int) $id);
914 $result = $this->db->query($sql);
915 if ($result) {
916 if ($this->db->num_rows($result)) {
917 $obj = $this->db->fetch_object($result);
918
919 $this->id = $obj->rowid;
920
921 $this->user_creation_id = $obj->fk_user_creat;
922 $this->user_modification_id = $obj->fk_user_modif;
923 $this->date_creation = $this->db->jdate($obj->datec);
924 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
925 }
926
927 $this->db->free($result);
928 } else {
929 dol_print_error($this->db);
930 }
931 }
932
939 public function initAsSpecimen()
940 {
941 // Set here init that are not commonf fields
942 // $this->property1 = ...
943 // $this->property2 = ...
944
945 return $this->initAsSpecimenCommon();
946 }
947
953 public function getLinesArray()
954 {
955 $this->lines = array();
956
957 $objectline = new PositionLine($this->db);
958 $result = $objectline->fetchAll('ASC', 'position', 0, 0, '(fk_position:=:'.((int) $this->id).')');
959
960 if (is_numeric($result)) {
961 $this->setErrorsFromObject($objectline);
962 return $result;
963 } else {
964 $this->lines = $result;
965 return $this->lines;
966 }
967 }
968
974 public function getNextNumRef()
975 {
976 global $langs, $conf;
977 $langs->load("hrm");
978
979 if (!getDolGlobalString('hrm_POSITION_ADDON')) {
980 $conf->global->hrm_POSITION_ADDON = 'mod_position_standard';
981 }
982
983 if (getDolGlobalString('hrm_POSITION_ADDON')) {
984 $mybool = false;
985
986 $file = getDolGlobalString('hrm_POSITION_ADDON') . ".php";
987 $classname = getDolGlobalString('hrm_POSITION_ADDON');
988
989 // Include file with class
990 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
991 foreach ($dirmodels as $reldir) {
992 $dir = dol_buildpath($reldir . "core/modules/hrm/");
993
994 // Load file with numbering class (if found)
995 $mybool = ((bool) @include_once $dir.$file) || $mybool;
996 }
997
998 if ($mybool === false) {
999 dol_print_error(null, "Failed to include file " . $file);
1000 return '';
1001 }
1002
1003 if (class_exists($classname)) {
1004 $obj = new $classname();
1005 $numref = $obj->getNextValue($this);
1006
1007 if ($numref != '' && $numref != '-1') {
1008 return $numref;
1009 } else {
1010 $this->error = $obj->error;
1011 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
1012 return "";
1013 }
1014 } else {
1015 print $langs->trans("Error") . " " . $langs->trans("ClassNotFound") . ' ' . $classname;
1016 return "";
1017 }
1018 } else {
1019 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1020 return "";
1021 }
1022 }
1023
1030 public function getForUser($userid)
1031 {
1032 $TPosition = array();
1033
1034 $TPosition = $this->fetchAll('ASC', 't.rowid', 0, 0, '(fk_user:=:'.((int) $userid).')');
1035
1036 return $TPosition;
1037 }
1038
1050 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1051 {
1052 global $conf, $langs;
1053
1054 $result = 0;
1055 $includedocgeneration = 0;
1056
1057 $langs->load("hrm");
1058
1059 if (!dol_strlen($modele)) {
1060 $modele = 'standard_position';
1061
1062 if (!empty($this->model_pdf)) {
1063 $modele = $this->model_pdf;
1064 } elseif (getDolGlobalString('POSITION_ADDON_PDF')) {
1065 $modele = getDolGlobalString('POSITION_ADDON_PDF');
1066 }
1067 }
1068
1069 $modelpath = "core/modules/hrm/doc/";
1070
1071 if ($includedocgeneration && !empty($modele)) {
1072 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1073 }
1074
1075 return $result;
1076 }
1077
1085 public function getKanbanView($option = '', $arraydata = null)
1086 {
1087 global $selected, $langs;
1088
1089 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1090
1091 $return = '<div class="box-flex-item box-flex-grow-zero">';
1092 $return .= '<div class="info-box info-box-sm">';
1093 $return .= '<span class="info-box-icon bg-infobox-action">';
1094 $return .= img_picto('', $this->picto);
1095 $return .= '</span>';
1096 $return .= '<div class="info-box-content">';
1097 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).'</span>';
1098 $return .= '<input class="fright" id="cb'.$this->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1099 if (!empty($arraydata['user'])) {
1100 $return .= '<br><span class="info-box-label ">'.$arraydata['user'].'</span>';
1101 }
1102 if (!empty($arraydata['job'])) {
1103 //$return .= '<br><span class="info-box-label opacitymedium">'.$langs->trans("JobProfile").'</span> : ';
1104 $return .= '<br><span class="info-box-label ">'.$arraydata['job'].'</span>';
1105 }
1106 if (property_exists($this, 'date_start') && property_exists($this, 'date_end')) {
1107 $return .= '<br><div class ="nothing"><span class="info-box-label ">'.dol_print_date($this->db->jdate($this->date_start), 'day').'</span>';
1108 $return .= ' - <span class="info-box-label ">'.dol_print_date($this->db->jdate($this->date_end), 'day').'</span></div>';
1109 }
1110 $return .= '</div>';
1111 $return .= '</div>';
1112 $return .= '</div>';
1113 return $return;
1114 }
1115}
1116
1117
1118require_once DOL_DOCUMENT_ROOT . '/core/class/commonobjectline.class.php';
1119
1124{
1125 // To complete with content of an object PositionLine
1126 // We should have a field rowid , fk_position and position
1127
1133 public function __construct(DoliDB $db)
1134 {
1135 $this->db = $db;
1136
1137 $this->isextrafieldmanaged = 0;
1138 }
1139}
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:626
$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