dolibarr 21.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 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 );
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 $conf, $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->import_key);
297
298 // Clear fields
299 if (property_exists($object, 'ref')) {
300 $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_" . $object->ref : $this->fields['ref']['default'];
301 }
302 if (property_exists($object, 'label')) {
303 $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf") . " " . $object->label : $this->fields['label']['default'];
304 }
305 if (property_exists($object, 'status')) {
306 $object->status = self::STATUS_DRAFT;
307 }
308 if (property_exists($object, 'date_creation')) {
309 $object->date_creation = dol_now();
310 }
311 if (property_exists($object, 'date_modification')) {
312 $object->date_modification = null;
313 }
314 // ...
315 // Clear extrafields that are unique
316 if (is_array($object->array_options) && count($object->array_options) > 0) {
317 $extrafields->fetch_name_optionals_label($this->table_element);
318 foreach ($object->array_options as $key => $option) {
319 $shortkey = preg_replace('/options_/', '', $key);
320 if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
321 //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
322 unset($object->array_options[$key]);
323 }
324 }
325 }
326
327 // Create clone
328 $object->context['createfromclone'] = 'createfromclone';
329 $result = $object->createCommon($user);
330 if ($result < 0) {
331 $error++;
333 }
334
335 if (!$error) {
336 // copy internal contacts
337 if ($this->copy_linked_contact($object, 'internal') < 0) {
338 $error++;
339 }
340 }
341
342 if (!$error) {
343 // copy external contacts if same company
344 if (property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
345 if ($this->copy_linked_contact($object, 'external') < 0) {
346 $error++;
347 }
348 }
349 }
350
351 unset($object->context['createfromclone']);
352
353 // End
354 if (!$error) {
355 $this->db->commit();
356 return $object;
357 } else {
358 $this->db->rollback();
359 return -1;
360 }
361 }
362
370 public function fetch($id, $ref = null)
371 {
372 $result = $this->fetchCommon($id, $ref);
373 if ($result > 0 && !empty($this->table_element_line)) {
374 $this->fetchLines();
375 }
376 return $result;
377 }
378
384 public function fetchLines()
385 {
386 $this->lines = array();
387
388 $result = $this->fetchLinesCommon();
389 return $result;
390 }
391
392
405 public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
406 {
407 dol_syslog(__METHOD__, LOG_DEBUG);
408
409 $records = array();
410
411 $sql = 'SELECT ';
412 $sql .= $this->getFieldList('t');
413 $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
414 if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
415 $sql .= ' WHERE t.entity IN (' . getEntity($this->element) . ')';
416 } else {
417 $sql .= ' WHERE 1 = 1';
418 }
419
420 // Manage filter
421 $errormessage = '';
422 $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
423 if ($errormessage) {
424 $this->errors[] = $errormessage;
425 dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR);
426 return -1;
427 }
428
429 if (!empty($sortfield)) {
430 $sql .= $this->db->order($sortfield, $sortorder);
431 }
432 if (!empty($limit)) {
433 $sql .= ' ' . $this->db->plimit($limit, $offset);
434 }
435
436 $resql = $this->db->query($sql);
437 if ($resql) {
438 $num = $this->db->num_rows($resql);
439 $i = 0;
440 while ($i < ($limit ? min($limit, $num) : $num)) {
441 $obj = $this->db->fetch_object($resql);
442
443 $record = new self($this->db);
444 $record->setVarsFromFetchObj($obj);
445
446 $records[$record->id] = $record;
447
448 $i++;
449 }
450 $this->db->free($resql);
451
452 return $records;
453 } else {
454 $this->errors[] = 'Error ' . $this->db->lasterror();
455 dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR);
456
457 return -1;
458 }
459 }
460
468 public function update(User $user, $notrigger = 0)
469 {
470 return $this->updateCommon($user, $notrigger);
471 }
472
480 public function delete(User $user, $notrigger = 0)
481 {
482 return $this->deleteCommon($user, $notrigger);
483 //return $this->deleteCommon($user, $notrigger, 1);
484 }
485
494 public function deleteLine(User $user, $idline, $notrigger = 0)
495 {
496 if ($this->status < 0) {
497 $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
498 return -2;
499 }
500
501 return $this->deleteLineCommon($user, $idline, $notrigger);
502 }
503
504
512 public function validate($user, $notrigger = 0)
513 {
514 global $conf, $langs;
515
516 require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
517
518 $error = 0;
519
520 // Protection
521 if ($this->status == self::STATUS_VALIDATED) {
522 dol_syslog(get_class($this) . "::validate action abandoned: already validated", LOG_WARNING);
523 return 0;
524 }
525
526 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->position->write))
527 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->position->position_advance->validate))))
528 {
529 $this->error='NotEnoughPermissions';
530 dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
531 return -1;
532 }*/
533
534 $now = dol_now();
535
536 $this->db->begin();
537
538 // Define new ref
539 if (!$error && (preg_match('/^[\‍(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
540 $num = $this->getNextNumRef();
541 } else {
542 $num = $this->ref;
543 }
544 $this->newref = $num;
545
546 if (!empty($num)) {
547 // Validate
548 $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
549 $sql .= " SET ref = '" . $this->db->escape($num) . "',";
550 $sql .= " status = " . self::STATUS_VALIDATED;
551 if (!empty($this->fields['date_validation'])) {
552 $sql .= ", date_validation = '" . $this->db->idate($now) . "'";
553 }
554 if (!empty($this->fields['fk_user_valid'])) { // @phan-suppress-current-line PhanTypeMismatchProperty
555 $sql .= ", fk_user_valid = " . ((int) $user->id);
556 }
557 $sql .= " WHERE rowid = " . ((int) $this->id);
558
559 dol_syslog(get_class($this) . "::validate()", LOG_DEBUG);
560 $resql = $this->db->query($sql);
561 if (!$resql) {
562 dol_print_error($this->db);
563 $this->error = $this->db->lasterror();
564 $error++;
565 }
566
567 if (!$error && !$notrigger) {
568 // Call trigger
569 $result = $this->call_trigger('HRM_POSITION_VALIDATE', $user);
570 if ($result < 0) {
571 $error++;
572 }
573 // End call triggers
574 }
575 }
576
577 if (!$error) {
578 $this->oldref = $this->ref;
579
580 // Rename directory if dir was a temporary ref
581 if (preg_match('/^[\‍(]?PROV/i', $this->ref)) {
582 // Now we rename also files into index
583 $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) . "'";
584 $sql .= " WHERE filename LIKE '" . $this->db->escape($this->ref) . "%' AND filepath = 'position/" . $this->db->escape($this->ref) . "' and entity = " . $conf->entity;
585 $resql = $this->db->query($sql);
586 if (!$resql) {
587 $error++;
588 $this->error = $this->db->lasterror();
589 }
590 $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'position/".$this->db->escape($this->newref)."'";
591 $sql .= " WHERE filepath = 'position/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
592 $resql = $this->db->query($sql);
593 if (!$resql) {
594 $error++;
595 $this->error = $this->db->lasterror();
596 }
597
598 // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
599 $oldref = dol_sanitizeFileName($this->ref);
600 $newref = dol_sanitizeFileName($num);
601 $dirsource = $conf->hrm->dir_output . '/position/' . $oldref;
602 $dirdest = $conf->hrm->dir_output . '/position/' . $newref;
603 if (!$error && file_exists($dirsource)) {
604 dol_syslog(get_class($this) . "::validate() rename dir " . $dirsource . " into " . $dirdest);
605
606 if (@rename($dirsource, $dirdest)) {
607 dol_syslog("Rename ok");
608 // Rename docs starting with $oldref with $newref
609 $listoffiles = dol_dir_list($conf->hrm->dir_output . '/position/' . $newref, 'files', 1, '^' . preg_quote($oldref, '/'));
610 foreach ($listoffiles as $fileentry) {
611 $dirsource = $fileentry['name'];
612 $dirdest = preg_replace('/^' . preg_quote($oldref, '/') . '/', $newref, $dirsource);
613 $dirsource = $fileentry['path'] . '/' . $dirsource;
614 $dirdest = $fileentry['path'] . '/' . $dirdest;
615 @rename($dirsource, $dirdest);
616 }
617 }
618 }
619 }
620 }
621
622 // Set new ref and current status
623 if (!$error) {
624 $this->ref = $num;
625 $this->status = self::STATUS_VALIDATED;
626 }
627
628 if (!$error) {
629 $this->db->commit();
630 return 1;
631 } else {
632 $this->db->rollback();
633 return -1;
634 }
635 }
636
637
645 public function setDraft($user, $notrigger = 0)
646 {
647 // Protection
648 if ($this->status <= self::STATUS_DRAFT) {
649 return 0;
650 }
651
652 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
653 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
654 {
655 $this->error='Permission denied';
656 return -1;
657 }*/
658
659 return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'POSITION_UNVALIDATE');
660 }
661
669 public function cancel($user, $notrigger = 0)
670 {
671 // Protection
672 if ($this->status != self::STATUS_VALIDATED) {
673 return 0;
674 }
675
676 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
677 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
678 {
679 $this->error='Permission denied';
680 return -1;
681 }*/
682
683 return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'POSITION_CANCEL');
684 }
685
693 public function reopen($user, $notrigger = 0)
694 {
695 // Protection
696 if ($this->status != self::STATUS_CANCELED) {
697 return 0;
698 }
699
700 /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
701 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
702 {
703 $this->error='Permission denied';
704 return -1;
705 }*/
706
707 return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'POSITION_REOPEN');
708 }
709
720 public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
721 {
722 global $conf, $langs, $hookmanager;
723
724 if (!empty($conf->dol_no_mouse_hover)) {
725 $notooltip = 1; // Force disable tooltips
726 }
727
728 $result = '';
729
730 $label = img_picto('', $this->picto) . ' <u>' . $langs->trans("Position") . '</u>';
731 if (isset($this->status)) {
732 $label .= ' ' . $this->getLibStatut(5);
733 }
734 $label .= '<br>';
735 $label .= '<b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
736
737 $url = dol_buildpath('/hrm/position_card.php', 1) . '?id=' . $this->id;
738
739 if ($option != 'nolink') {
740 // Add param to save lastsearch_values or not
741 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
742 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
743 $add_save_lastsearch_values = 1;
744 }
745 if ($add_save_lastsearch_values) {
746 $url .= '&save_lastsearch_values=1';
747 }
748 }
749
750 $linkclose = '';
751 if (empty($notooltip)) {
752 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
753 $label = $langs->trans("ShowPosition");
754 $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"';
755 }
756 $linkclose .= ' title="' . dol_escape_htmltag($label, 1) . '"';
757 $linkclose .= ' class="classfortooltip' . ($morecss ? ' ' . $morecss : '') . '"';
758 } else {
759 $linkclose = ($morecss ? ' class="' . $morecss . '"' : '');
760 }
761
762 if ($option == 'nolink') {
763 $linkstart = '<span';
764 } else {
765 $linkstart = '<a href="' . $url . '"';
766 }
767 $linkstart .= $linkclose . '>';
768 if ($option == 'nolink') {
769 $linkend = '</span>';
770 } else {
771 $linkend = '</a>';
772 }
773
774 $result .= $linkstart;
775
776 if (empty($this->showphoto_on_popup)) {
777 if ($withpicto) {
778 $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);
779 }
780 } else {
781 if ($withpicto) {
782 require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
783
784 list($class, $module) = explode('@', $this->picto);
785 $upload_dir = $conf->$module->multidir_output[$conf->entity] . "/$class/" . dol_sanitizeFileName($this->ref);
786 $filearray = dol_dir_list($upload_dir, "files");
787 $filename = $filearray[0]['name'];
788 if (!empty($filename)) {
789 $pospoint = strpos($filearray[0]['name'], '.');
790
791 $pathtophoto = $class . '/' . $this->ref . '/thumbs/' . substr($filename, 0, $pospoint) . '_mini' . substr($filename, $pospoint);
792 if (!getDolGlobalString(strtoupper($module . '_' . $class) . '_FORMATLISTPHOTOSASUSERS')) {
793 $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>';
794 } else {
795 $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>';
796 }
797
798 $result .= '</div>';
799 } else {
800 $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);
801 }
802 }
803 }
804
805 if ($withpicto != 2) {
806 $result .= $this->ref;
807 }
808
809 $result .= $linkend;
810 //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
811
812 global $action, $hookmanager;
813 $hookmanager->initHooks(array('positiondao'));
814 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
815 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
816 if ($reshook > 0) {
817 $result = $hookmanager->resPrint;
818 } else {
819 $result .= $hookmanager->resPrint;
820 }
821
822 return $result;
823 }
824
831 public function getLibStatut($mode = 0)
832 {
833 return $this->LibStatut($this->status, $mode);
834 }
835
836 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
837
845 public function LibStatut($status, $mode = 0)
846 {
847 // phpcs:enable
848 if (is_null($status)) {
849 return '';
850 }
851
852 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
853 global $langs;
854 //$langs->load("hrm");
855 $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
856 $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
857 $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
858 $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
859 $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
860 $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
861 }
862
863 $statusType = 'status' . $status;
864 //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
865 if ($status == self::STATUS_CANCELED) {
866 $statusType = 'status6';
867 }
868
869 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
870 }
871
886 public function showInputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = 0, $nonewbutton = 0)
887 {
888 global $langs;
889
890 if ($key == 'fk_user') {
891 $vacantId = $keyprefix.$key.'vacant'.$keysuffix;
892
893 $out = parent::showInputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss);
894 $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>'; ?>
895 <script type="text/javascript">
896 $(document).ready(function () {
897 var checkbox = $('#<?php print $vacantId; ?>');
898 var searchfkuser = $('#<?php print $keyprefix.$key.$keysuffix; ?>');
899 checkbox.click(function () {
900 if (checkbox.prop('checked')) {
901 searchfkuser.val(0).trigger('change');
902 searchfkuser.prop('disabled', 1);
903 } else {
904 searchfkuser.prop('disabled', 0);
905 }
906 });
907 });
908 </script>
909 <?php
910 } else {
911 $out = parent::showInputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss);
912 }
913
914 return $out;
915 }
916
930 public function showOutputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = '')
931 {
932 global $langs;
933
934 if ($key == 'fk_user' && $this->fk_user == 0) {
935 return $langs->trans("VacantPosition");
936 }
937 return parent::showOutputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss);
938 }
939
940
947 public function info($id)
948 {
949 $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
950 $sql .= ' fk_user_creat, fk_user_modif';
951 $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
952 $sql .= ' WHERE t.rowid = ' . ((int) $id);
953 $result = $this->db->query($sql);
954 if ($result) {
955 if ($this->db->num_rows($result)) {
956 $obj = $this->db->fetch_object($result);
957
958 $this->id = $obj->rowid;
959
960 $this->user_creation_id = $obj->fk_user_creat;
961 $this->user_modification_id = $obj->fk_user_modif;
962 $this->date_creation = $this->db->jdate($obj->datec);
963 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
964 }
965
966 $this->db->free($result);
967 } else {
968 dol_print_error($this->db);
969 }
970 }
971
978 public function initAsSpecimen()
979 {
980 // Set here init that are not commonf fields
981 // $this->property1 = ...
982 // $this->property2 = ...
983
984 return $this->initAsSpecimenCommon();
985 }
986
992 public function getLinesArray()
993 {
994 $this->lines = array();
995
996 $objectline = new PositionLine($this->db);
997 $result = $objectline->fetchAll('ASC', 'position', 0, 0, '(fk_position:=:'.((int) $this->id).')');
998
999 if (is_numeric($result)) {
1000 $this->setErrorsFromObject($objectline);
1001 return $result;
1002 } else {
1003 $this->lines = $result;
1004 return $this->lines;
1005 }
1006 }
1007
1013 public function getNextNumRef()
1014 {
1015 global $langs, $conf;
1016 $langs->load("hrm");
1017
1018 if (!getDolGlobalString('hrm_POSITION_ADDON')) {
1019 $conf->global->hrm_POSITION_ADDON = 'mod_position_standard';
1020 }
1021
1022 if (getDolGlobalString('hrm_POSITION_ADDON')) {
1023 $mybool = false;
1024
1025 $file = getDolGlobalString('hrm_POSITION_ADDON') . ".php";
1026 $classname = getDolGlobalString('hrm_POSITION_ADDON');
1027
1028 // Include file with class
1029 $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
1030 foreach ($dirmodels as $reldir) {
1031 $dir = dol_buildpath($reldir . "core/modules/hrm/");
1032
1033 // Load file with numbering class (if found)
1034 $mybool = ((bool) @include_once $dir.$file) || $mybool;
1035 }
1036
1037 if (!$mybool) {
1038 dol_print_error(null, "Failed to include file " . $file);
1039 return '';
1040 }
1041
1042 if (class_exists($classname)) {
1043 $obj = new $classname();
1044 '@phan-var-force ModeleNumRefEvaluation $obj';
1045 $numref = $obj->getNextValue($this);
1046
1047 if ($numref != '' && $numref != '-1') {
1048 return $numref;
1049 } else {
1050 $this->error = $obj->error;
1051 //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
1052 return "";
1053 }
1054 } else {
1055 print $langs->trans("Error") . " " . $langs->trans("ClassNotFound") . ' ' . $classname;
1056 return "";
1057 }
1058 } else {
1059 print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1060 return "";
1061 }
1062 }
1063
1070 public function getForUser($userid)
1071 {
1072 $TPosition = array();
1073
1074 $TPosition = $this->fetchAll('ASC', 't.rowid', 0, 0, '(fk_user:=:'.((int) $userid).')');
1075
1076 return $TPosition;
1077 }
1078
1090 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1091 {
1092 global $conf, $langs;
1093
1094 $result = 0;
1095 $includedocgeneration = 0;
1096
1097 $langs->load("hrm");
1098
1099 if (!dol_strlen($modele)) {
1100 $modele = 'standard_position';
1101
1102 if (!empty($this->model_pdf)) {
1103 $modele = $this->model_pdf;
1104 } elseif (getDolGlobalString('POSITION_ADDON_PDF')) {
1105 $modele = getDolGlobalString('POSITION_ADDON_PDF');
1106 }
1107 }
1108
1109 $modelpath = "core/modules/hrm/doc/";
1110
1111 if ($includedocgeneration && !empty($modele)) {
1112 $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1113 }
1114
1115 return $result;
1116 }
1117
1125 public function getKanbanView($option = '', $arraydata = null)
1126 {
1127 global $selected, $langs;
1128
1129 $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1130
1131 $return = '<div class="box-flex-item box-flex-grow-zero">';
1132 $return .= '<div class="info-box info-box-sm">';
1133 $return .= '<span class="info-box-icon bg-infobox-action">';
1134 $return .= img_picto('', $this->picto);
1135 $return .= '</span>';
1136 $return .= '<div class="info-box-content">';
1137 $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).'</span>';
1138 $return .= '<input class="fright" id="cb'.$this->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
1139 if (!empty($arraydata['user'])) {
1140 $return .= '<br><span class="info-box-label ">'.$arraydata['user'].'</span>';
1141 }
1142 if (!empty($arraydata['job'])) {
1143 //$return .= '<br><span class="info-box-label opacitymedium">'.$langs->trans("JobProfile").'</span> : ';
1144 $return .= '<br><span class="info-box-label ">'.$arraydata['job'].'</span>';
1145 }
1146 if (property_exists($this, 'date_start') && property_exists($this, 'date_end')) {
1147 $return .= '<br><div class ="nothing"><span class="info-box-label ">'.dol_print_date($this->db->jdate($this->date_start), 'day').'</span>';
1148 $return .= ' - <span class="info-box-label ">'.dol_print_date($this->db->jdate($this->date_end), 'day').'</span></div>';
1149 }
1150 $return .= '</div>';
1151 $return .= '</div>';
1152 $return .= '</div>';
1153 return $return;
1154 }
1155}
1156
1157
1158require_once DOL_DOCUMENT_ROOT . '/core/class/commonobjectline.class.php';
1159
1164{
1165 // To complete with content of an object PositionLine
1166 // We should have a field rowid , fk_position and position
1167
1173 public function __construct(DoliDB $db)
1174 {
1175 $this->db = $db;
1176
1177 $this->isextrafieldmanaged = 0;
1178 }
1179}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:66
$object ref
Definition info.php:89
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 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:171
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.
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
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 a 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...
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:149