dolibarr 24.0.0-beta
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-2025 Frédéric France <frederic.france@free.fr>
8 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
30// Put here all includes required by your class file
31require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php';
32
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 );
114 public $rowid;
118 public $ref;
122 public $description;
126 public $fk_contrat;
130 public $fk_user;
134 public $fk_job;
138 public $date_start;
142 public $date_end;
146 public $abort_comment;
150 public $note_public;
154 public $note_private;
158 public $fk_user_creat;
162 public $fk_user_modif;
163
164
165 // END MODULEBUILDER PROPERTIES
166
167
168 // If this object has a subtable with lines
169
170 // /**
171 // * @var string Name of subtable line
172 // */
173 // public $table_element_line = 'hrm_job_userline';
174
175 // /**
176 // * @var string Field with ID of parent key if this object has a parent
177 // */
178 // public $fk_element = 'fk_position';
179
180 // /**
181 // * @var string Name of subtable class that manage subtable lines
182 // */
183 // public $class_element_line = 'Positionline';
184
185 // /**
186 // * @var array List of child tables. To test if we can delete object.
187 // */
188 // protected $childtables = array();
189
190 // /**
191 // * @var array List of child tables. To know object to delete on cascade.
192 // * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will
193 // * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object
194 // */
195 // protected $childtablesoncascade = array('hrm_job_userdet');
196
197 // /**
198 // * @var PositionLine[] Array of subtable lines
199 // */
200 // public $lines = array();
201
202
208 public function __construct(DoliDB $db)
209 {
210 global $langs;
211
212 $this->db = $db;
213
214 $this->ismultientitymanaged = 0;
215 $this->isextrafieldmanaged = 0;
216
217 //if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
218 //$this->fields['rowid']['visible'] = 0;
219 //}
220 if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
221 $this->fields['entity']['enabled'] = 0;
222 }
223
224 // Example to show how to set values of fields definition dynamically
225 /*if ($user->rights->hrm->position->read) {
226 $this->fields['myfield']['visible'] = 1;
227 $this->fields['myfield']['noteditable'] = 0;
228 }*/
229
230 // Unset fields that are disabled
231 foreach ($this->fields as $key => $val) {
232 if (isset($val['enabled']) && empty($val['enabled'])) {
233 unset($this->fields[$key]);
234 }
235 }
236
237 // Translate some data of arrayofkeyval
238 if (is_object($langs)) {
239 foreach ($this->fields as $key => $val) {
240 if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
241 foreach ($val['arrayofkeyval'] as $key2 => $val2) {
242 $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
243 }
244 }
245 }
246 }
247 }
248
256 public function create(User $user, $notrigger = 0)
257 {
258 $resultcreate = $this->createCommon($user, $notrigger);
259
260 //$resultvalidate = $this->validate($user, $notrigger);
261
262 return $resultcreate;
263 }
264
272 public function createFromClone(User $user, $fromid)
273 {
274 global $langs, $extrafields;
275 $error = 0;
276
277 dol_syslog(__METHOD__, LOG_DEBUG);
278
279 $object = new self($this->db);
280
281 $this->db->begin();
282
283 // Load source object
284 $result = $object->fetchCommon($fromid);
285 if ($result > 0 && !empty($object->table_element_line)) {
286 $object->fetchLines();
287 }
288
289 // get lines so they will be clone
290 //foreach($this->lines as $line)
291 // $line->fetch_optionals();
292
293 // Reset some properties
294 unset($object->id);
295 unset($object->fk_user_creat);
296 unset($object->user_ceation_id);
297 unset($object->import_key);
298
299 // Clear fields
300 if (property_exists($object, 'ref')) {
301 $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_" . $object->ref : $this->fields['ref']['default'];
302 }
303 if (property_exists($object, 'status')) {
304 $object->status = self::STATUS_DRAFT;
305 }
306 if (property_exists($object, 'date_creation')) {
307 $object->date_creation = dol_now();
308 }
309 if (property_exists($object, 'date_modification')) {
310 $object->date_modification = null;
311 }
312 // ...
313 // Clear extrafields that are unique
314 if (is_array($object->array_options) && count($object->array_options) > 0) {
315 $extrafields->fetch_name_optionals_label($this->table_element);
316 foreach ($object->array_options as $key => $option) {
317 $shortkey = preg_replace('/options_/', '', $key);
318 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
319 //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
320 unset($object->array_options[$key]);
321 }
322 }
323 }
324
325 // Create clone
326 $object->context['createfromclone'] = 'createfromclone';
327 $result = $object->createCommon($user);
328 if ($result < 0) {
329 $error++;
331 }
332
333 if (!$error) {
334 // copy internal contacts
335 if ($this->copy_linked_contact($object, 'internal') < 0) {
336 $error++;
337 }
338 }
339
340 if (!$error) {
341 // copy external contacts if same company
342 if (property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
343 if ($this->copy_linked_contact($object, 'external') < 0) {
344 $error++;
345 }
346 }
347 }
348
349 unset($object->context['createfromclone']);
350
351 // End
352 if (!$error) {
353 $this->db->commit();
354 return $object;
355 } else {
356 $this->db->rollback();
357 return -1;
358 }
359 }
360
368 public function fetch($id, $ref = null)
369 {
370 $result = $this->fetchCommon($id, $ref);
371 if ($result > 0 && !empty($this->table_element_line)) {
372 $this->fetchLines();
373 }
374 return $result;
375 }
376
382 public function fetchLines()
383 {
384 $this->lines = array();
385
386 $result = $this->fetchLinesCommon();
387 return $result;
388 }
389
390
403 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
404 {
405 dol_syslog(__METHOD__, LOG_DEBUG);
406
407 $records = array();
408
409 $sql = 'SELECT ';
410 $sql .= $this->getFieldList('t');
411 $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
412 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
413 $sql .= ' WHERE t.entity IN (' . getEntity($this->element) . ')';
414 } else {
415 $sql .= ' WHERE 1 = 1';
416 }
417
418 // Manage filter
419 $errormessage = '';
420 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
421 if ($errormessage) {
422 $this->errors[] = $errormessage;
423 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
424 return -1;
425 }
426
427 if (!empty($sortfield)) {
428 $sql .= $this->db->order($sortfield, $sortorder);
429 }
430 if (!empty($limit)) {
431 $sql .= ' ' . $this->db->plimit($limit, $offset);
432 }
433
434 $resql = $this->db->query($sql);
435 if ($resql) {
436 $num = $this->db->num_rows($resql);
437 $i = 0;
438 while ($i < ($limit ? min($limit, $num) : $num)) {
439 $obj = $this->db->fetch_object($resql);
440
441 $record = new self($this->db);
442 $record->setVarsFromFetchObj($obj);
443
444 $records[$record->id] = $record;
445
446 $i++;
447 }
448 $this->db->free($resql);
449
450 return $records;
451 } else {
452 $this->errors[] = 'Error ' . $this->db->lasterror();
453 dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR);
454
455 return -1;
456 }
457 }
458
466 public function update(User $user, $notrigger = 0)
467 {
468 return $this->updateCommon($user, $notrigger);
469 }
470
478 public function delete(User $user, $notrigger = 0)
479 {
480 return $this->deleteCommon($user, $notrigger);
481 //return $this->deleteCommon($user, $notrigger, 1);
482 }
483
492 public function deleteLine(User $user, $idline, $notrigger = 0)
493 {
494 if ($this->status < 0) {
495 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
496 return -2;
497 }
498
499 return $this->deleteLineCommon($user, $idline, $notrigger);
500 }
501
502
510 public function validate($user, $notrigger = 0)
511 {
512 global $conf, $langs;
513
514 require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
515
516 $error = 0;
517
518 // Protection
519 if ($this->status == self::STATUS_VALIDATED) {
520 dol_syslog(get_class($this) . "::validate action abandoned: already validated", LOG_WARNING);
521 return 0;
522 }
523
524 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->position->write))
525 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->position->position_advance->validate))))
526 {
527 $this->error='NotEnoughPermissions';
528 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
529 return -1;
530 }*/
531
532 $now = dol_now();
533
534 $this->db->begin();
535
536 // Define new ref
537 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
538 $num = $this->getNextNumRef();
539 } else {
540 $num = (string) $this->ref;
541 }
542 $this->newref = $num;
543
544 if (!empty($num)) {
545 // Validate
546 $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
547 $sql .= " SET ref = '" . $this->db->escape($num) . "',";
548 $sql .= " status = " . self::STATUS_VALIDATED;
549 if (!empty($this->fields['date_validation'])) {
550 $sql .= ", date_validation = '" . $this->db->idate($now) . "'";
551 }
552 if (!empty($this->fields['fk_user_valid'])) { // @phan-suppress-current-line PhanTypeMismatchProperty
553 $sql .= ", fk_user_valid = " . ((int) $user->id);
554 }
555 $sql .= " WHERE rowid = " . ((int) $this->id);
556
557 dol_syslog(get_class($this) . "::validate()", LOG_DEBUG);
558 $resql = $this->db->query($sql);
559 if (!$resql) {
560 dol_print_error($this->db);
561 $this->error = $this->db->lasterror();
562 $error++;
563 }
564
565 if (!$error && !$notrigger) {
566 // Call trigger
567 $result = $this->call_trigger('HRM_POSITION_VALIDATE', $user);
568 if ($result < 0) {
569 $error++;
570 }
571 // End call triggers
572 }
573 }
574
575 if (!$error) {
576 $this->oldref = $this->ref;
577
578 // Rename directory if dir was a temporary ref
579 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
580 // Now we rename also files into index
581 $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) . "'";
582 $sql .= " WHERE filename LIKE '" . $this->db->escape($this->ref) . "%' AND filepath = 'position/" . $this->db->escape($this->ref) . "' and entity = " . $conf->entity;
583 $resql = $this->db->query($sql);
584 if (!$resql) {
585 $error++;
586 $this->error = $this->db->lasterror();
587 }
588 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'position/".$this->db->escape($this->newref)."'";
589 $sql .= " WHERE filepath = 'position/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
590 $resql = $this->db->query($sql);
591 if (!$resql) {
592 $error++;
593 $this->error = $this->db->lasterror();
594 }
595
596 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
597 $oldref = dol_sanitizeFileName($this->ref);
598 $newref = dol_sanitizeFileName($num);
599 $dirsource = $conf->hrm->dir_output . '/position/' . $oldref;
600 $dirdest = $conf->hrm->dir_output . '/position/' . $newref;
601 if (!$error && file_exists($dirsource)) {
602 dol_syslog(get_class($this) . "::validate() rename dir " . $dirsource . " into " . $dirdest);
603
604 if (@rename($dirsource, $dirdest)) {
605 dol_syslog("Rename ok");
606 // Rename docs starting with $oldref with $newref
607 $listoffiles = dol_dir_list($conf->hrm->dir_output . '/position/' . $newref, 'files', 1, '^' . preg_quote($oldref, '/'));
608 foreach ($listoffiles as $fileentry) {
609 $dirsource = $fileentry['name'];
610 $dirdest = preg_replace('/^' . preg_quote($oldref, '/') . '/', $newref, $dirsource);
611 $dirsource = $fileentry['path'] . '/' . $dirsource;
612 $dirdest = $fileentry['path'] . '/' . $dirdest;
613 @rename($dirsource, $dirdest);
614 }
615 }
616 }
617 }
618 }
619
620 // Set new ref and current status
621 if (!$error) {
622 $this->ref = $num;
623 $this->status = self::STATUS_VALIDATED;
624 }
625
626 if (!$error) {
627 $this->db->commit();
628 return 1;
629 } else {
630 $this->db->rollback();
631 return -1;
632 }
633 }
634
635
643 public function setDraft($user, $notrigger = 0)
644 {
645 // Protection
646 if ($this->status <= self::STATUS_DRAFT) {
647 return 0;
648 }
649
650 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
651 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
652 {
653 $this->error='Permission denied';
654 return -1;
655 }*/
656
657 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'POSITION_UNVALIDATE');
658 }
659
667 public function cancel($user, $notrigger = 0)
668 {
669 // Protection
670 if ($this->status != self::STATUS_VALIDATED) {
671 return 0;
672 }
673
674 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
675 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
676 {
677 $this->error='Permission denied';
678 return -1;
679 }*/
680
681 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'POSITION_CANCEL');
682 }
683
691 public function reopen($user, $notrigger = 0)
692 {
693 // Protection
694 if ($this->status != self::STATUS_CANCELED) {
695 return 0;
696 }
697
698 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
699 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
700 {
701 $this->error='Permission denied';
702 return -1;
703 }*/
704
705 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'POSITION_REOPEN');
706 }
707
718 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
719 {
720 global $conf, $langs, $hookmanager;
721
722 if (!empty($conf->dol_no_mouse_hover)) {
723 $notooltip = 1; // Force disable tooltips
724 }
725
726 $result = '';
727
728 $label = img_picto('', $this->picto) . ' <u>' . $langs->trans("Position") . '</u>';
729 if (isset($this->status)) {
730 $label .= ' ' . $this->getLibStatut(5);
731 }
732 $label .= '<br>';
733 $label .= '<b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
734
735 $url = dol_buildpath('/hrm/position_card.php', 1) . '?id=' . $this->id;
736
737 if ($option != 'nolink') {
738 // Add param to save lastsearch_values or not
739 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
740 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
741 $add_save_lastsearch_values = 1;
742 }
743 if ($add_save_lastsearch_values) {
744 $url .= '&save_lastsearch_values=1';
745 }
746 }
747
748 $linkclose = '';
749 if (empty($notooltip)) {
750 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
751 $label = $langs->trans("ShowPosition");
752 $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"';
753 }
754 $linkclose .= ' title="' . dol_escape_htmltag($label, 1) . '"';
755 $linkclose .= ' class="classfortooltip' . ($morecss ? ' ' . $morecss : '') . '"';
756 } else {
757 $linkclose = ($morecss ? ' class="' . $morecss . '"' : '');
758 }
759
760 if ($option == 'nolink') {
761 $linkstart = '<span';
762 } else {
763 $linkstart = '<a href="' . $url . '"';
764 }
765 $linkstart .= $linkclose . '>';
766 if ($option == 'nolink') {
767 $linkend = '</span>';
768 } else {
769 $linkend = '</a>';
770 }
771
772 $result .= $linkstart;
773
774 if (empty($this->showphoto_on_popup)) {
775 if ($withpicto) {
776 $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);
777 }
778 } else {
779 if ($withpicto) {
780 require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
781
782 list($class, $module) = explode('@', $this->picto);
783 $upload_dir = $conf->$module->multidir_output[$conf->entity] . "/$class/" . dol_sanitizeFileName($this->ref);
784 $filearray = dol_dir_list($upload_dir, "files");
785 $filename = $filearray[0]['name'];
786 if (!empty($filename)) {
787 $pospoint = strpos($filearray[0]['name'], '.');
788
789 $pathtophoto = $class . '/' . $this->ref . '/thumbs/' . substr($filename, 0, $pospoint) . '_mini' . substr($filename, $pospoint);
790 if (!getDolGlobalString(strtoupper($module . '_' . $class) . '_FORMATLISTPHOTOSASUSERS')) {
791 $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>';
792 } else {
793 $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>';
794 }
795
796 $result .= '</div>';
797 } else {
798 $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);
799 }
800 }
801 }
802
803 if ($withpicto != 2) {
804 $result .= $this->ref;
805 }
806
807 $result .= $linkend;
808 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
809
810 global $action, $hookmanager;
811 $hookmanager->initHooks(array('positiondao'));
812 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
813 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
814 if ($reshook > 0) {
815 $result = $hookmanager->resPrint;
816 } else {
817 $result .= $hookmanager->resPrint;
818 }
819
820 return $result;
821 }
822
829 public function getLibStatut($mode = 0)
830 {
831 return $this->LibStatut($this->status, $mode);
832 }
833
834 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
835
843 public function LibStatut($status, $mode = 0)
844 {
845 // phpcs:enable
846 if (is_null($status)) {
847 return '';
848 }
849
850 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
851 global $langs;
852 //$langs->load("hrm");
853 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
854 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
855 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
856 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
857 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
858 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
859 }
860
861 $statusType = 'status' . $status;
862 //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
863 if ($status == self::STATUS_CANCELED) {
864 $statusType = 'status6';
865 }
866
867 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
868 }
869
884 public function showInputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = 0, $nonewbutton = 0)
885 {
886 global $langs;
887
888 if ($key == 'fk_user') {
889 $vacantId = $keyprefix.$key.'vacant'.$keysuffix;
890
891 $out = parent::showInputField(null, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss);
892 $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>'; ?>
893 <script type="text/javascript">
894 $(document).ready(function () {
895 var checkbox = $('#<?php print $vacantId; ?>');
896 var searchfkuser = $('#<?php print $keyprefix.$key.$keysuffix; ?>');
897 checkbox.click(function () {
898 if (checkbox.prop('checked')) {
899 searchfkuser.val(0).trigger('change');
900 searchfkuser.prop('disabled', 1);
901 } else {
902 searchfkuser.prop('disabled', 0);
903 }
904 });
905 });
906 </script>
907 <?php
908 } else {
909 $out = parent::showInputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss);
910 }
911
912 return $out;
913 }
914
928 public function showOutputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = '')
929 {
930 global $langs;
931
932 if ($key == 'fk_user' && $this->fk_user == 0) {
933 return $langs->trans("VacantPosition");
934 }
935 return parent::showOutputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss);
936 }
937
938
945 public function info($id)
946 {
947 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
948 $sql .= ' fk_user_creat, fk_user_modif';
949 $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
950 $sql .= ' WHERE t.rowid = ' . ((int) $id);
951 $result = $this->db->query($sql);
952 if ($result) {
953 if ($this->db->num_rows($result)) {
954 $obj = $this->db->fetch_object($result);
955
956 $this->id = $obj->rowid;
957
958 $this->user_creation_id = $obj->fk_user_creat;
959 $this->user_modification_id = $obj->fk_user_modif;
960 $this->date_creation = $this->db->jdate($obj->datec);
961 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
962 }
963
964 $this->db->free($result);
965 } else {
966 dol_print_error($this->db);
967 }
968 }
969
976 public function initAsSpecimen()
977 {
978 // Set here init that are not commonf fields
979 // $this->property1 = ...
980 // $this->property2 = ...
981
982 return $this->initAsSpecimenCommon();
983 }
984
990 public function getLinesArray()
991 {
992 $this->lines = array();
993
994 $objectline = new PositionLine($this->db);
995 $result = $objectline->fetchAll('ASC', 'position', 0, 0, '(fk_position:=:'.((int) $this->id).')');
996
997 if (is_numeric($result)) {
998 $this->setErrorsFromObject($objectline);
999 return $result;
1000 } else {
1001 $this->lines = $result;
1002 return $this->lines;
1003 }
1004 }
1005
1011 public function getNextNumRef()
1012 {
1013 global $langs, $conf;
1014 $langs->load("hrm");
1015
1016 if (!getDolGlobalString('hrm_POSITION_ADDON')) {
1017 $conf->global->hrm_POSITION_ADDON = 'mod_position_standard';
1018 }
1019
1020 if (getDolGlobalString('hrm_POSITION_ADDON')) {
1021 $mybool = false;
1022
1023 $file = getDolGlobalString('hrm_POSITION_ADDON') . ".php";
1024 $classname = getDolGlobalString('hrm_POSITION_ADDON');
1025
1026 // Include file with class
1027 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1028 foreach ($dirmodels as $reldir) {
1029 $dir = dol_buildpath($reldir . "core/modules/hrm/");
1030
1031 // Load file with numbering class (if found)
1032 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1033 }
1034
1035 if (!$mybool) {
1036 dol_print_error(null, "Failed to include file " . $file);
1037 return '';
1038 }
1039
1040 if (class_exists($classname)) {
1041 $obj = new $classname();
1042 '@phan-var-force ModeleNumRefEvaluation $obj';
1043 $numref = $obj->getNextValue($this);
1044
1045 if ($numref != '' && $numref != '-1') {
1046 return $numref;
1047 } else {
1048 $this->error = $obj->error;
1049 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
1050 return "";
1051 }
1052 } else {
1053 print $langs->trans("Error") . " " . $langs->trans("ClassNotFound") . ' ' . $classname;
1054 return "";
1055 }
1056 } else {
1057 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1058 return "";
1059 }
1060 }
1061
1068 public function getForUser($userid)
1069 {
1070 $TPosition = array();
1071
1072 $TPosition = $this->fetchAll('ASC', 't.rowid', 0, 0, '(fk_user:=:'.((int) $userid).')');
1073
1074 return $TPosition;
1075 }
1076
1088 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1089 {
1090 global $conf, $langs;
1091
1092 $result = 0;
1093 $includedocgeneration = 0;
1094
1095 $langs->load("hrm");
1096
1097 if (!dol_strlen($modele)) {
1098 $modele = 'standard_position';
1099
1100 if (!empty($this->model_pdf)) {
1101 $modele = $this->model_pdf;
1102 } elseif (getDolGlobalString('POSITION_ADDON_PDF')) {
1103 $modele = getDolGlobalString('POSITION_ADDON_PDF');
1104 }
1105 }
1106
1107 $modelpath = "core/modules/hrm/doc/";
1108
1109 if ($includedocgeneration && !empty($modele)) {
1110 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1111 }
1112
1113 return $result;
1114 }
1115
1123 public function getKanbanView($option = '', $arraydata = null)
1124 {
1125 global $selected, $langs;
1126
1127 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1128
1129 $return = '<div class="box-flex-item box-flex-grow-zero">';
1130 $return .= '<div class="info-box info-box-sm">';
1131 $return .= '<span class="info-box-icon bg-infobox-action">';
1132 $return .= img_picto('', $this->picto);
1133 $return .= '</span>';
1134 $return .= '<div class="info-box-content">';
1135 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).'</span>';
1136 $return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1137 if (!empty($arraydata['user'])) {
1138 $return .= '<br><span class="info-box-label ">'.$arraydata['user'].'</span>';
1139 }
1140 if (!empty($arraydata['job'])) {
1141 //$return .= '<br><span class="info-box-label opacitymedium">'.$langs->trans("JobProfile").'</span> : ';
1142 $return .= '<br><span class="info-box-label ">'.$arraydata['job'].'</span>';
1143 }
1144 if (property_exists($this, 'date_start') && property_exists($this, 'date_end')) {
1145 $return .= '<br><div class ="nothing"><span class="info-box-label ">'.dol_print_date($this->db->jdate($this->date_start), 'day').'</span>';
1146 $return .= ' - <span class="info-box-label ">'.dol_print_date($this->db->jdate($this->date_end), 'day').'</span></div>';
1147 }
1148 $return .= '</div>';
1149 $return .= '</div>';
1150 $return .= '</div>';
1151 return $return;
1152 }
1153}
1154
1155
1156require_once DOL_DOCUMENT_ROOT . '/core/class/commonobjectline.class.php';
1157
1162{
1163 // To complete with content of an object PositionLine
1164 // We should have a field rowid , fk_position and position
1165
1171 public function __construct(DoliDB $db)
1172 {
1173 $this->db = $db;
1174
1175 $this->isextrafieldmanaged = 0;
1176 }
1177}
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
$object ref
Definition info.php:90
Parent class of all other business classes (invoices, contracts, proposals, orders,...
deleteLineCommon(User $user, $idline, $notrigger=0)
Delete a line of object in database.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
setErrorsFromObject($object)
setErrorsFromObject
createCommon(User $user, $notrigger=0)
Create object in the database.
getFieldList($alias='', $excludefields=array())
Function to concat keys of fields.
updateCommon(User $user, $notrigger=0)
Update object into database.
setStatusCommon($user, $status, $notrigger=0, $triggercode='')
Set to a status.
initAsSpecimenCommon()
Initialise object with example values Id must be 0 if object instance is a specimen.
copy_linked_contact($objFrom, $source='internal')
Copy contact from one element to current.
fetchLinesCommon($morewhere='', $noextrafields=0)
Load object in memory from the database.
fetchCommon($id, $ref=null, $morewhere='', $noextrafields=0)
Load object in memory from the database.
deleteCommon(User $user, $notrigger=0, $forcechilddeletion=0)
Delete object in database.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage Dolibarr database access.
Class for 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 clickable 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.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:168
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:64
dol_now($mode='gmt')
Return date for now.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
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...
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
Definition repair.php:130