Passed
Pull Request — dev (#6)
by Rafael
79:24 queued 24:08
created

Position::validate()   F

Complexity

Conditions 22
Paths 2801

Size

Total Lines 122
Code Lines 71

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 22
eloc 71
nc 2801
nop 2
dl 0
loc 122
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/* Copyright (C) 2017       Laurent Destailleur         <[email protected]>
4
 * Copyright (C) 2021       Gauthier VERDOL             <[email protected]>
5
 * Copyright (C) 2021       Greg Rastklan               <[email protected]>
6
 * Copyright (C) 2021       Jean-Pascal BOUDET          <[email protected]>
7
 * Copyright (C) 2021       Grégory BLEMAND             <[email protected]>
8
 * Copyright (C) 2024       Frédéric France             <[email protected]>
9
 * Copyright (C) 2024		MDW							<[email protected]>
10
 * Copyright (C) 2024       Rafael San José             <[email protected]>
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 3 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
24
 */
25
26
namespace Dolibarr\Code\Hrm\Classes;
27
28
use Dolibarr\Core\Base\CommonObject;
29
use DoliDB;
30
31
/**
32
 * \file        class/position.class.php
33
 * \ingroup     hrm
34
 * \brief       This file is a CRUD class file for Position (Create/Read/Update/Delete)
35
 */
36
37
// Put here all includes required by your class file
38
39
/**
40
 * Class for Position
41
 */
42
class Position extends CommonObject
43
{
44
    /**
45
     * @var string ID of module.
46
     */
47
    public $module = 'hrm';
48
49
    /**
50
     * @var string ID to identify managed object.
51
     */
52
    public $element = 'position';
53
54
    /**
55
     * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management.
56
     */
57
    public $table_element = 'hrm_job_user';
58
59
    /**
60
     * @var string String with name of icon for position. Must be the part after the 'object_' into object_position.png
61
     */
62
    public $picto = 'user-cog';
63
64
65
    const STATUS_DRAFT = 0;
66
    const STATUS_VALIDATED = 1;
67
    const STATUS_CANCELED = 9;
68
69
70
    /**
71
     *  'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter]]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'text:none', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password')
72
     *         Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)"
73
     *  'label' the translation key.
74
     *  'picto' is code of a picto to show before value in forms
75
     *  'enabled' is a condition when the field must be managed (Example: 1 or 'getDolGlobalString("MY_SETUP_PARAM")')
76
     *  'position' is the sort order of field.
77
     *  'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0).
78
     *  'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing)
79
     *  'noteditable' says if field is not editable (1 or 0)
80
     *  'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created.
81
     *  'index' if we want an index in database.
82
     *  'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommended to name the field fk_...).
83
     *  'searchall' is 1 if we want to search in this field when making a search from the quick search button.
84
     *  'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8).
85
     *  'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'cssview'=>'wordbreak', 'csslist'=>'tdoverflowmax200'
86
     *  'help' is a 'TranslationString' to use to show a tooltip on field. You can also use 'TranslationString:keyfortooltiponlick' for a tooltip on click.
87
     *  'showoncombobox' if value of the field must be visible into the label of the combobox that list record
88
     *  'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code.
89
     *  'arrayofkeyval' to set a list of values if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel"). Note that type can be 'integer' or 'varchar'
90
     *  'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1.
91
     *  'comment' is not used. You can store here any text of your choice. It is not used by application.
92
     *
93
     *  Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor.
94
     */
95
96
    // BEGIN MODULEBUILDER PROPERTIES
97
    /**
98
     * @var array<string,array{type:string,label:string,enabled:int<0,2>|string,position:int,notnull?:int,visible:int,noteditable?:int,default?:string,index?:int,foreignkey?:string,searchall?:int,isameasure?:int,css?:string,csslist?:string,help?:string,showoncombobox?:int,disabled?:int,arrayofkeyval?:array<int,string>,comment?:string}>  Array with all fields and their property. Do not use it as a static var. It may be modified by constructor.
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<string,array{type:...ring>,comment?:string}> at position 16 could not be parsed: Expected '}' at position 16, but found 'int'.
Loading history...
99
     */
100
    public $fields = array(
101
        'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'position' => 1, 'notnull' => 1, 'visible' => 2, 'index' => 1, 'css' => 'left', 'comment' => "Id"),
102
        //'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"),
103
        'date_creation' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'position' => 500, 'notnull' => 1, 'visible' => -2,),
104
        'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'position' => 501, 'notnull' => 0, 'visible' => -2,),
105
        'fk_contrat' => array('type' => 'integer:Contrat:contrat/class/contrat.class.php', 'label' => 'fk_contrat', 'enabled' => 'isModEnabled("contract")', 'position' => 50, 'notnull' => 0, 'visible' => 0,),
106
        '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'),
107
        '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'),
108
        'date_start' => array('type' => 'date', 'label' => 'DateStart', 'enabled' => 1, 'position' => 101, 'notnull' => 1, 'visible' => 1,),
109
        'date_end' => array('type' => 'date', 'label' => 'DateEnd', 'enabled' => 1, 'position' => 102, 'notnull' => 0, 'visible' => 1,),
110
        'description' => array('type' => 'text', 'label' => 'Description', 'enabled' => 1, 'position' => 120, 'notnull' => 0, 'visible' => 3,),
111
        'abort_comment' => array('type' => 'varchar(255)', 'label' => 'AbandonmentComment', 'enabled' => 'getDolGlobalInt("HRM_JOB_POSITON_ENDING_COMMENT")', 'position' => 502, 'notnull' => 0, 'visible' => 1,),
112
        'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'position' => 151, 'notnull' => 0, 'visible' => 0,),
113
        'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'position' => 152, 'notnull' => 0, 'visible' => 0,),
114
        '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',),
115
        'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'position' => 511, 'notnull' => -1, 'visible' => -2,),
116
    );
117
    public $rowid;
118
    public $ref;
119
    public $description;
120
    public $date_creation;
121
    public $fk_contrat;
122
    public $fk_user;
123
    public $fk_job;
124
    public $date_start;
125
    public $date_end;
126
    public $abort_comment;
127
    public $note_public;
128
    public $note_private;
129
    public $fk_user_creat;
130
    public $fk_user_modif;
131
132
133
    // END MODULEBUILDER PROPERTIES
134
135
136
    // If this object has a subtable with lines
137
138
    // /**
139
    //  * @var string    Name of subtable line
140
    //  */
141
    // public $table_element_line = 'hrm_job_userline';
142
143
    // /**
144
    //  * @var string    Field with ID of parent key if this object has a parent
145
    //  */
146
    // public $fk_element = 'fk_position';
147
148
    // /**
149
    //  * @var string    Name of subtable class that manage subtable lines
150
    //  */
151
    // public $class_element_line = 'Positionline';
152
153
    // /**
154
    //  * @var array    List of child tables. To test if we can delete object.
155
    //  */
156
    // protected $childtables = array();
157
158
    // /**
159
    //  * @var array    List of child tables. To know object to delete on cascade.
160
    //  *               If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will
161
    //  *               call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object
162
    //  */
163
    // protected $childtablesoncascade = array('hrm_job_userdet');
164
165
    // /**
166
    //  * @var PositionLine[]     Array of subtable lines
167
    //  */
168
    // public $lines = array();
169
170
171
    /**
172
     * Constructor
173
     *
174
     * @param DoliDB $db Database handler
175
     */
176
    public function __construct(DoliDB $db)
177
    {
178
        global $conf, $langs;
179
180
        $this->db = $db;
181
182
        $this->ismultientitymanaged = 0;
183
        $this->isextrafieldmanaged = 0;
184
185
        if (!getDolGlobalString('MAIN_SHOW_TECHNICAL_ID') && isset($this->fields['rowid'])) {
186
            //$this->fields['rowid']['visible'] = 0;
187
        }
188
        if (!isModEnabled('multicompany') && isset($this->fields['entity'])) {
189
            $this->fields['entity']['enabled'] = 0;
190
        }
191
192
        // Example to show how to set values of fields definition dynamically
193
        /*if ($user->rights->hrm->position->read) {
194
            $this->fields['myfield']['visible'] = 1;
195
            $this->fields['myfield']['noteditable'] = 0;
196
        }*/
197
198
        // Unset fields that are disabled
199
        foreach ($this->fields as $key => $val) {
200
            if (isset($val['enabled']) && empty($val['enabled'])) {
201
                unset($this->fields[$key]);
202
            }
203
        }
204
205
        // Translate some data of arrayofkeyval
206
        if (is_object($langs)) {
207
            foreach ($this->fields as $key => $val) {
208
                if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
209
                    foreach ($val['arrayofkeyval'] as $key2 => $val2) {
210
                        $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2);
211
                    }
212
                }
213
            }
214
        }
215
    }
216
217
    /**
218
     * Create object into database
219
     *
220
     * @param User  $user       User that creates
221
     * @param int   $notrigger  0=launch triggers after, 1=disable triggers
222
     * @return int              Return integer <0 if KO, Id of created object if OK
223
     */
224
    public function create(User $user, $notrigger = 0)
225
    {
226
        $resultcreate = $this->createCommon($user, $notrigger);
227
228
        //$resultvalidate = $this->validate($user, $notrigger);
229
230
        return $resultcreate;
231
    }
232
233
    /**
234
     * Clone an object into another one
235
     *
236
     * @param User $user User that creates
237
     * @param int $fromid Id of object to clone
238
     * @return    mixed                New object created, <0 if KO
239
     */
240
    public function createFromClone(User $user, $fromid)
241
    {
242
        global $langs, $extrafields;
243
        $error = 0;
244
245
        dol_syslog(__METHOD__, LOG_DEBUG);
246
247
        $object = new self($this->db);
248
249
        $this->db->begin();
250
251
        // Load source object
252
        $result = $object->fetchCommon($fromid);
253
        if ($result > 0 && !empty($object->table_element_line)) {
254
            $object->fetchLines();
255
        }
256
257
        // get lines so they will be clone
258
        //foreach($this->lines as $line)
259
        //  $line->fetch_optionals();
260
261
        // Reset some properties
262
        unset($object->id);
263
        unset($object->fk_user_creat);
264
        unset($object->import_key);
265
266
        // Clear fields
267
        if (property_exists($object, 'ref')) {
268
            $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_" . $object->ref : $this->fields['ref']['default'];
269
        }
270
        if (property_exists($object, 'label')) {
271
            $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf") . " " . $object->label : $this->fields['label']['default'];
272
        }
273
        if (property_exists($object, 'status')) {
274
            $object->status = self::STATUS_DRAFT;
275
        }
276
        if (property_exists($object, 'date_creation')) {
277
            $object->date_creation = dol_now();
278
        }
279
        if (property_exists($object, 'date_modification')) {
280
            $object->date_modification = null;
281
        }
282
        // ...
283
        // Clear extrafields that are unique
284
        if (is_array($object->array_options) && count($object->array_options) > 0) {
285
            $extrafields->fetch_name_optionals_label($this->table_element);
286
            foreach ($object->array_options as $key => $option) {
287
                $shortkey = preg_replace('/options_/', '', $key);
288
                if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) {
289
                    //var_dump($key); var_dump($clonedObj->array_options[$key]); exit;
290
                    unset($object->array_options[$key]);
291
                }
292
            }
293
        }
294
295
        // Create clone
296
        $object->context['createfromclone'] = 'createfromclone';
297
        $result = $object->createCommon($user);
298
        if ($result < 0) {
299
            $error++;
300
            $this->setErrorsFromObject($object);
301
        }
302
303
        if (!$error) {
304
            // copy internal contacts
305
            if ($this->copy_linked_contact($object, 'internal') < 0) {
306
                $error++;
307
            }
308
        }
309
310
        if (!$error) {
311
            // copy external contacts if same company
312
            if (property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) {
313
                if ($this->copy_linked_contact($object, 'external') < 0) {
314
                    $error++;
315
                }
316
            }
317
        }
318
319
        unset($object->context['createfromclone']);
320
321
        // End
322
        if (!$error) {
323
            $this->db->commit();
324
            return $object;
325
        } else {
326
            $this->db->rollback();
327
            return -1;
328
        }
329
    }
330
331
    /**
332
     * Load object in memory from the database
333
     *
334
     * @param int $id Id object
335
     * @param string $ref Ref
336
     * @return int         Return integer <0 if KO, 0 if not found, >0 if OK
337
     */
338
    public function fetch($id, $ref = null)
339
    {
340
        $result = $this->fetchCommon($id, $ref);
341
        if ($result > 0 && !empty($this->table_element_line)) {
342
            $this->fetchLines();
343
        }
344
        return $result;
345
    }
346
347
    /**
348
     * Load object lines in memory from the database
349
     *
350
     * @return int         Return integer <0 if KO, 0 if not found, >0 if OK
351
     */
352
    public function fetchLines()
353
    {
354
        $this->lines = array();
355
356
        $result = $this->fetchLinesCommon();
357
        return $result;
358
    }
359
360
361
    /**
362
     * Load list of objects in memory from the database.
363
     *
364
     * @param   string      $sortorder      Sort Order
365
     * @param   string      $sortfield      Sort field
366
     * @param   int         $limit          limit
367
     * @param   int         $offset         Offset
368
     * @param   string      $filter         Filter as an Universal Search string.
369
     *                                      Example: '((client:=:1) OR ((client:>=:2) AND (client:<=:3))) AND (client:!=:8) AND (nom:like:'a%')'
370
     * @param   string      $filtermode     No more used
371
     * @return  array|int                   int <0 if KO, array of pages if OK
372
     */
373
    public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = '', $filtermode = 'AND')
374
    {
375
        dol_syslog(__METHOD__, LOG_DEBUG);
376
377
        $records = array();
378
379
        $sql = 'SELECT ';
380
        $sql .= $this->getFieldList('t');
381
        $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
382
        if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) {
383
            $sql .= ' WHERE t.entity IN (' . getEntity($this->element) . ')';
384
        } else {
385
            $sql .= ' WHERE 1 = 1';
386
        }
387
388
        // Manage filter
389
        $errormessage = '';
390
        $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage);
391
        if ($errormessage) {
392
            $this->errors[] = $errormessage;
393
            dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR);
394
            return -1;
395
        }
396
397
        if (!empty($sortfield)) {
398
            $sql .= $this->db->order($sortfield, $sortorder);
399
        }
400
        if (!empty($limit)) {
401
            $sql .= ' ' . $this->db->plimit($limit, $offset);
402
        }
403
404
        $resql = $this->db->query($sql);
405
        if ($resql) {
406
            $num = $this->db->num_rows($resql);
407
            $i = 0;
408
            while ($i < ($limit ? min($limit, $num) : $num)) {
409
                $obj = $this->db->fetch_object($resql);
410
411
                $record = new self($this->db);
412
                $record->setVarsFromFetchObj($obj);
413
414
                $records[$record->id] = $record;
415
416
                $i++;
417
            }
418
            $this->db->free($resql);
419
420
            return $records;
421
        } else {
422
            $this->errors[] = 'Error ' . $this->db->lasterror();
423
            dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR);
424
425
            return -1;
426
        }
427
    }
428
429
    /**
430
     * Update object into database
431
     *
432
     * @param User  $user       User that modifies
433
     * @param int   $notrigger  0=launch triggers after, 1=disable triggers
434
     * @return int              Return integer <0 if KO, >0 if OK
435
     */
436
    public function update(User $user, $notrigger = 0)
437
    {
438
        return $this->updateCommon($user, $notrigger);
439
    }
440
441
    /**
442
     * Delete object in database
443
     *
444
     * @param User  $user       User that deletes
445
     * @param int   $notrigger  0=launch triggers after, 1=disable triggers
446
     * @return int              Return integer <0 if KO, >0 if OK
447
     */
448
    public function delete(User $user, $notrigger = 0)
449
    {
450
        return $this->deleteCommon($user, $notrigger);
451
        //return $this->deleteCommon($user, $notrigger, 1);
452
    }
453
454
    /**
455
     *  Delete a line of object in database
456
     *
457
     * @param User  $user       User that delete
458
     * @param int   $idline     Id of line to delete
459
     * @param int   $notrigger  0=launch triggers after, 1=disable triggers
460
     * @return int              Return >0 if OK, <0 if KO
461
     */
462
    public function deleteLine(User $user, $idline, $notrigger = 0)
463
    {
464
        if ($this->status < 0) {
465
            $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus';
466
            return -2;
467
        }
468
469
        return $this->deleteLineCommon($user, $idline, $notrigger);
470
    }
471
472
473
    /**
474
     *    Validate object
475
     *
476
     * @param User $user User making status change
477
     * @param int $notrigger 1=Does not execute triggers, 0= execute triggers
478
     * @return    int                        Return integer <=0 if OK, 0=Nothing done, >0 if KO
479
     */
480
    public function validate($user, $notrigger = 0)
481
    {
482
        global $conf, $langs;
483
484
        require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/files.lib.php';
485
486
        $error = 0;
487
488
        // Protection
489
        if ($this->status == self::STATUS_VALIDATED) {
490
            dol_syslog(get_class($this) . "::validate action abandoned: already validated", LOG_WARNING);
491
            return 0;
492
        }
493
494
        /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->position->write))
495
         || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->position->position_advance->validate))))
496
         {
497
         $this->error='NotEnoughPermissions';
498
         dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR);
499
         return -1;
500
         }*/
501
502
        $now = dol_now();
503
504
        $this->db->begin();
505
506
        // Define new ref
507
        if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life
508
            $num = $this->getNextNumRef();
509
        } else {
510
            $num = $this->ref;
511
        }
512
        $this->newref = $num;
513
514
        if (!empty($num)) {
515
            // Validate
516
            $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
517
            $sql .= " SET ref = '" . $this->db->escape($num) . "',";
518
            $sql .= " status = " . self::STATUS_VALIDATED;
519
            if (!empty($this->fields['date_validation'])) {
520
                $sql .= ", date_validation = '" . $this->db->idate($now) . "'";
521
            }
522
            if (!empty($this->fields['fk_user_valid'])) {
523
                $sql .= ", fk_user_valid = " . ((int) $user->id);
524
            }
525
            $sql .= " WHERE rowid = " . ((int) $this->id);
526
527
            dol_syslog(get_class($this) . "::validate()", LOG_DEBUG);
528
            $resql = $this->db->query($sql);
529
            if (!$resql) {
530
                dol_print_error($this->db);
531
                $this->error = $this->db->lasterror();
532
                $error++;
533
            }
534
535
            if (!$error && !$notrigger) {
536
                // Call trigger
537
                $result = $this->call_trigger('HRM_POSITION_VALIDATE', $user);
538
                if ($result < 0) {
539
                    $error++;
540
                }
541
                // End call triggers
542
            }
543
        }
544
545
        if (!$error) {
546
            $this->oldref = $this->ref;
547
548
            // Rename directory if dir was a temporary ref
549
            if (preg_match('/^[\(]?PROV/i', $this->ref)) {
550
                // Now we rename also files into index
551
                $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) . "'";
552
                $sql .= " WHERE filename LIKE '" . $this->db->escape($this->ref) . "%' AND 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
                $sql = 'UPDATE ' . MAIN_DB_PREFIX . "ecm_files set filepath = 'position/" . $this->db->escape($this->newref) . "'";
559
                $sql .= " WHERE filepath = 'position/" . $this->db->escape($this->ref) . "' and entity = " . $conf->entity;
560
                $resql = $this->db->query($sql);
561
                if (!$resql) {
562
                    $error++;
563
                    $this->error = $this->db->lasterror();
564
                }
565
566
                // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
567
                $oldref = dol_sanitizeFileName($this->ref);
568
                $newref = dol_sanitizeFileName($num);
569
                $dirsource = $conf->hrm->dir_output . '/position/' . $oldref;
570
                $dirdest = $conf->hrm->dir_output . '/position/' . $newref;
571
                if (!$error && file_exists($dirsource)) {
572
                    dol_syslog(get_class($this) . "::validate() rename dir " . $dirsource . " into " . $dirdest);
573
574
                    if (@rename($dirsource, $dirdest)) {
575
                        dol_syslog("Rename ok");
576
                        // Rename docs starting with $oldref with $newref
577
                        $listoffiles = dol_dir_list($conf->hrm->dir_output . '/position/' . $newref, 'files', 1, '^' . preg_quote($oldref, '/'));
578
                        foreach ($listoffiles as $fileentry) {
579
                            $dirsource = $fileentry['name'];
580
                            $dirdest = preg_replace('/^' . preg_quote($oldref, '/') . '/', $newref, $dirsource);
581
                            $dirsource = $fileentry['path'] . '/' . $dirsource;
582
                            $dirdest = $fileentry['path'] . '/' . $dirdest;
583
                            @rename($dirsource, $dirdest);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for rename(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

583
                            /** @scrutinizer ignore-unhandled */ @rename($dirsource, $dirdest);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
584
                        }
585
                    }
586
                }
587
            }
588
        }
589
590
        // Set new ref and current status
591
        if (!$error) {
592
            $this->ref = $num;
593
            $this->status = self::STATUS_VALIDATED;
594
        }
595
596
        if (!$error) {
597
            $this->db->commit();
598
            return 1;
599
        } else {
600
            $this->db->rollback();
601
            return -1;
602
        }
603
    }
604
605
606
    /**
607
     *    Set draft status
608
     *
609
     * @param User $user Object user that modify
610
     * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers
611
     * @return    int                        Return integer <0 if KO, >0 if OK
612
     */
613
    public function setDraft($user, $notrigger = 0)
614
    {
615
        // Protection
616
        if ($this->status <= self::STATUS_DRAFT) {
617
            return 0;
618
        }
619
620
        /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
621
         || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
622
         {
623
         $this->error='Permission denied';
624
         return -1;
625
         }*/
626
627
        return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'POSITION_UNVALIDATE');
628
    }
629
630
    /**
631
     *    Set cancel status
632
     *
633
     * @param User $user Object user that modify
634
     * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers
635
     * @return    int                        Return integer <0 if KO, 0=Nothing done, >0 if OK
636
     */
637
    public function cancel($user, $notrigger = 0)
638
    {
639
        // Protection
640
        if ($this->status != self::STATUS_VALIDATED) {
641
            return 0;
642
        }
643
644
        /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
645
         || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
646
         {
647
         $this->error='Permission denied';
648
         return -1;
649
         }*/
650
651
        return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'POSITION_CANCEL');
652
    }
653
654
    /**
655
     *    Set back to validated status
656
     *
657
     * @param User $user Object user that modify
658
     * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers
659
     * @return    int                        Return integer <0 if KO, 0=Nothing done, >0 if OK
660
     */
661
    public function reopen($user, $notrigger = 0)
662
    {
663
        // Protection
664
        if ($this->status != self::STATUS_CANCELED) {
665
            return 0;
666
        }
667
668
        /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->write))
669
         || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->hrm->hrm_advance->validate))))
670
         {
671
         $this->error='Permission denied';
672
         return -1;
673
         }*/
674
675
        return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'POSITION_REOPEN');
676
    }
677
678
    /**
679
     *  Return a link to the object card (with optionally the picto)
680
     *
681
     * @param   int         $withpicto              Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto)
682
     * @param   string      $option                 On what the link point to ('nolink', ...)
683
     * @param   int         $notooltip              1=Disable tooltip
684
     * @param   string      $morecss                Add more css on link
685
     * @param   int         $save_lastsearch_value  -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
686
     * @return  string                              String with URL
687
     */
688
    public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
689
    {
690
        global $conf, $langs, $hookmanager;
691
692
        if (!empty($conf->dol_no_mouse_hover)) {
693
            $notooltip = 1; // Force disable tooltips
694
        }
695
696
        $result = '';
697
698
        $label = img_picto('', $this->picto) . ' <u>' . $langs->trans("Position") . '</u>';
699
        if (isset($this->status)) {
700
            $label .= ' ' . $this->getLibStatut(5);
701
        }
702
        $label .= '<br>';
703
        $label .= '<b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
704
705
        $url = dol_buildpath('/hrm/position_card.php', 1) . '?id=' . $this->id;
706
707
        if ($option != 'nolink') {
708
            // Add param to save lastsearch_values or not
709
            $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
710
            if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
711
                $add_save_lastsearch_values = 1;
712
            }
713
            if ($add_save_lastsearch_values) {
714
                $url .= '&save_lastsearch_values=1';
715
            }
716
        }
717
718
        $linkclose = '';
719
        if (empty($notooltip)) {
720
            if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
721
                $label = $langs->trans("ShowPosition");
722
                $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"';
723
            }
724
            $linkclose .= ' title="' . dol_escape_htmltag($label, 1) . '"';
725
            $linkclose .= ' class="classfortooltip' . ($morecss ? ' ' . $morecss : '') . '"';
726
        } else {
727
            $linkclose = ($morecss ? ' class="' . $morecss . '"' : '');
728
        }
729
730
        if ($option == 'nolink') {
731
            $linkstart = '<span';
732
        } else {
733
            $linkstart = '<a href="' . $url . '"';
734
        }
735
        $linkstart .= $linkclose . '>';
736
        if ($option == 'nolink') {
737
            $linkend = '</span>';
738
        } else {
739
            $linkend = '</a>';
740
        }
741
742
        $result .= $linkstart;
743
744
        if (empty($this->showphoto_on_popup)) {
745
            if ($withpicto) {
746
                $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);
747
            }
748
        } else {
749
            if ($withpicto) {
750
                require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/files.lib.php';
751
752
                list($class, $module) = explode('@', $this->picto);
753
                $upload_dir = $conf->$module->multidir_output[$conf->entity] . "/$class/" . dol_sanitizeFileName($this->ref);
754
                $filearray = dol_dir_list($upload_dir, "files");
755
                $filename = $filearray[0]['name'];
756
                if (!empty($filename)) {
757
                    $pospoint = strpos($filearray[0]['name'], '.');
758
759
                    $pathtophoto = $class . '/' . $this->ref . '/thumbs/' . substr($filename, 0, $pospoint) . '_mini' . substr($filename, $pospoint);
760
                    if (!getDolGlobalString(strtoupper($module . '_' . $class) . '_FORMATLISTPHOTOSASUSERS')) {
761
                        $result .= '<div class="floatleft inline-block valignmiddle divphotoref"><div class="photoref"><img class="photo' . $module . '" alt="No photo" border="0" src="' . constant('BASE_URL') . '/viewimage.php?modulepart=' . $module . '&entity=' . $conf->entity . '&file=' . urlencode($pathtophoto) . '"></div></div>';
762
                    } else {
763
                        $result .= '<div class="floatleft inline-block valignmiddle divphotoref"><img class="photouserphoto userphoto" alt="No photo" border="0" src="' . constant('BASE_URL') . '/viewimage.php?modulepart=' . $module . '&entity=' . $conf->entity . '&file=' . urlencode($pathtophoto) . '"></div>';
764
                    }
765
766
                    $result .= '</div>';
767
                } else {
768
                    $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);
769
                }
770
            }
771
        }
772
773
        if ($withpicto != 2) {
774
            $result .= $this->ref;
775
        }
776
777
        $result .= $linkend;
778
        //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
779
780
        global $action, $hookmanager;
781
        $hookmanager->initHooks(array('positiondao'));
782
        $parameters = array('id' => $this->id, 'getnomurl' => &$result);
783
        $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
784
        if ($reshook > 0) {
785
            $result = $hookmanager->resPrint;
786
        } else {
787
            $result .= $hookmanager->resPrint;
788
        }
789
790
        return $result;
791
    }
792
793
    /**
794
     *  Return the label of the status
795
     *
796
     * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
797
     * @return    string                   Label of status
798
     */
799
    public function getLibStatut($mode = 0)
800
    {
801
        return $this->LibStatut($this->status, $mode);
802
    }
803
804
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
805
806
    /**
807
     *  Return the status
808
     *
809
     * @param int $status Id status
810
     * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
811
     * @return string                   Label of status
812
     */
813
    public function LibStatut($status, $mode = 0)
814
    {
815
		// phpcs:enable
816
        if (is_null($status)) {
817
            return '';
818
        }
819
820
        if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
821
            global $langs;
822
            //$langs->load("hrm");
823
            $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
824
            $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
825
            $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
826
            $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft');
827
            $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled');
828
            $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled');
829
        }
830
831
        $statusType = 'status' . $status;
832
        //if ($status == self::STATUS_VALIDATED) $statusType = 'status1';
833
        if ($status == self::STATUS_CANCELED) {
834
            $statusType = 'status6';
835
        }
836
837
        return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
838
    }
839
840
    /**
841
     * Return HTML string to put an input field into a page
842
     * Code very similar with showInputField of extra fields
843
     *
844
     * @param ?array{type:string,label:string,enabled:int|string,position:int,notnull?:int,visible:int,noteditable?:int,default?:string,index?:int,foreignkey?:string,searchall?:int,isameasure?:int,css?:string,csslist?:string,help?:string,showoncombobox?:int,disabled?:int,arrayofkeyval?:array<int,string>,comment?:string}   $val    Array of properties for field to show
845
     * @param  string       $key           Key of attribute
846
     * @param  string       $value         Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value)
847
     * @param  string       $moreparam     To add more parameters on html input tag
848
     * @param  string       $keysuffix     Prefix string to add into name and id of field (can be used to avoid duplicate names)
849
     * @param  string       $keyprefix     Suffix string to add into name and id of field (can be used to avoid duplicate names)
850
     * @param  string|int   $morecss       Value for css to define style/length of field. May also be a numeric.
851
     * @param  int<0,1>     $nonewbutton   Do not show new button
852
     * @return string
853
     */
854
    public function showInputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = 0, $nonewbutton = 0)
855
    {
856
        global $langs;
857
858
        if ($key == 'fk_user') {
859
            $vacantId = $keyprefix . $key . 'vacant' . $keysuffix;
860
861
            $out = parent::showInputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss);
862
            $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>'; ?>
863
            <script type="text/javascript">
864
                $(document).ready(function () {
865
                    var checkbox = $('#<?php print $vacantId; ?>');
866
                    var searchfkuser = $('#<?php print $keyprefix . $key . $keysuffix; ?>');
867
                    checkbox.click(function () {
868
                        if (checkbox.prop('checked')) {
869
                            searchfkuser.val(0).trigger('change');
870
                            searchfkuser.prop('disabled', 1);
871
                        } else {
872
                            searchfkuser.prop('disabled', 0);
873
                        }
874
                    });
875
                });
876
            </script>
877
            <?php
878
        } else {
879
            $out = parent::showInputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss);
880
        }
881
882
        return $out;
883
    }
884
885
    /**
886
     * Return HTML string to show a field into a page
887
     * Code very similar with showOutputField of extra fields
888
     *
889
     * @param  array   $val            Array of properties of field to show
890
     * @param  string  $key            Key of attribute
891
     * @param  string  $value          Preselected value to show (for date type it must be in timestamp format, for amount or price it must be a php numeric value)
892
     * @param  string  $moreparam      To add more parameters on html input tag
893
     * @param  string  $keysuffix      Prefix string to add into name and id of field (can be used to avoid duplicate names)
894
     * @param  string  $keyprefix      Suffix string to add into name and id of field (can be used to avoid duplicate names)
895
     * @param  mixed   $morecss        Value for css to define size. May also be a numeric.
896
     * @return string
897
     */
898
    public function showOutputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = '')
899
    {
900
        global $langs;
901
902
        if ($key == 'fk_user' && $this->fk_user == 0) {
903
            return $langs->trans("VacantPosition");
904
        }
905
        return parent::showOutputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss);
906
    }
907
908
909
    /**
910
     *    Load the info information in the object
911
     *
912
     * @param int $id Id of object
913
     * @return    void
914
     */
915
    public function info($id)
916
    {
917
        $sql = 'SELECT rowid, date_creation as datec, tms as datem,';
918
        $sql .= ' fk_user_creat, fk_user_modif';
919
        $sql .= ' FROM ' . MAIN_DB_PREFIX . $this->table_element . ' as t';
920
        $sql .= ' WHERE t.rowid = ' . ((int) $id);
921
        $result = $this->db->query($sql);
922
        if ($result) {
923
            if ($this->db->num_rows($result)) {
924
                $obj = $this->db->fetch_object($result);
925
926
                $this->id = $obj->rowid;
927
928
                $this->user_creation_id = $obj->fk_user_creat;
929
                $this->user_modification_id = $obj->fk_user_modif;
930
                $this->date_creation     = $this->db->jdate($obj->datec);
931
                $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
932
            }
933
934
            $this->db->free($result);
935
        } else {
936
            dol_print_error($this->db);
937
        }
938
    }
939
940
    /**
941
     * Initialise object with example values
942
     * Id must be 0 if object instance is a specimen
943
     *
944
     * @return int
945
     */
946
    public function initAsSpecimen()
947
    {
948
        // Set here init that are not commonf fields
949
        // $this->property1 = ...
950
        // $this->property2 = ...
951
952
        return $this->initAsSpecimenCommon();
953
    }
954
955
    /**
956
     *    Create an array of lines
957
     *
958
     * @return array|int        array of lines if OK, <0 if KO
959
     */
960
    public function getLinesArray()
961
    {
962
        $this->lines = array();
963
964
        $objectline = new PositionLine($this->db);
965
        $result = $objectline->fetchAll('ASC', 'position', 0, 0, '(fk_position:=:' . ((int) $this->id) . ')');
966
967
        if (is_numeric($result)) {
968
            $this->setErrorsFromObject($objectline);
969
            return $result;
970
        } else {
971
            $this->lines = $result;
972
            return $this->lines;
973
        }
974
    }
975
976
    /**
977
     *  Returns the reference to the following non used object depending on the active numbering module.
978
     *
979
     * @return string            Object free reference
980
     */
981
    public function getNextNumRef()
982
    {
983
        global $langs, $conf;
984
        $langs->load("hrm");
985
986
        if (!getDolGlobalString('hrm_POSITION_ADDON')) {
987
            $conf->global->hrm_POSITION_ADDON = 'mod_position_standard';
988
        }
989
990
        if (getDolGlobalString('hrm_POSITION_ADDON')) {
991
            $mybool = false;
992
993
            $file = getDolGlobalString('hrm_POSITION_ADDON') . ".php";
994
            $classname = getDolGlobalString('hrm_POSITION_ADDON');
995
996
            // Include file with class
997
            $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
998
            foreach ($dirmodels as $reldir) {
999
                $dir = dol_buildpath($reldir . "core/modules/hrm/");
1000
1001
                // Load file with numbering class (if found)
1002
                $mybool = ((bool) @include_once $dir . $file) || $mybool;
1003
            }
1004
1005
            if ($mybool === false) {
1006
                dol_print_error(null, "Failed to include file " . $file);
1007
                return '';
1008
            }
1009
1010
            if (class_exists($classname)) {
1011
                $obj = new $classname();
1012
                $numref = $obj->getNextValue($this);
1013
1014
                if ($numref != '' && $numref != '-1') {
1015
                    return $numref;
1016
                } else {
1017
                    $this->error = $obj->error;
1018
                    //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error);
1019
                    return "";
1020
                }
1021
            } else {
1022
                print $langs->trans("Error") . " " . $langs->trans("ClassNotFound") . ' ' . $classname;
1023
                return "";
1024
            }
1025
        } else {
1026
            print $langs->trans("ErrorNumberingModuleNotSetup", $this->element);
1027
            return "";
1028
        }
1029
    }
1030
1031
    /**
1032
     * getForUser
1033
     *
1034
     * @param int $userid id of user we need to get position list
1035
     * @return array|int of positions of user with for each of them the job fetched into that array
1036
     */
1037
    public function getForUser($userid)
1038
    {
1039
        $TPosition = array();
1040
1041
        $TPosition = $this->fetchAll('ASC', 't.rowid', 0, 0, '(fk_user:=:' . ((int) $userid) . ')');
1042
1043
        return $TPosition;
1044
    }
1045
1046
    /**
1047
     * Create a document onto disk according to template module.
1048
     *
1049
     * @param string $modele Force template to use ('' to not force)
1050
     * @param Translate $outputlangs object lang a utiliser pour traduction
1051
     * @param int $hidedetails Hide details of lines
1052
     * @param int $hidedesc Hide description
1053
     * @param int $hideref Hide ref
1054
     * @param null|array $moreparams Array to provide more information
1055
     * @return     int                        0 if KO, 1 if OK
1056
     */
1057
    public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
1058
    {
1059
        global $conf, $langs;
1060
1061
        $result = 0;
1062
        $includedocgeneration = 0;
1063
1064
        $langs->load("hrm");
1065
1066
        if (!dol_strlen($modele)) {
1067
            $modele = 'standard_position';
1068
1069
            if (!empty($this->model_pdf)) {
1070
                $modele = $this->model_pdf;
1071
            } elseif (getDolGlobalString('POSITION_ADDON_PDF')) {
1072
                $modele = getDolGlobalString('POSITION_ADDON_PDF');
1073
            }
1074
        }
1075
1076
        $modelpath = "core/modules/hrm/doc/";
1077
1078
        if ($includedocgeneration && !empty($modele)) {
1079
            $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1080
        }
1081
1082
        return $result;
1083
    }
1084
1085
    /**
1086
     *  Return clicable link of object (with eventually picto)
1087
     *
1088
     *  @param      string      $option                 Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link)
1089
     *  @param      array       $arraydata              Array of data
1090
     *  @return     string      HTML Code for Kanban thumb.
1091
     */
1092
    public function getKanbanView($option = '', $arraydata = null)
1093
    {
1094
        global $selected, $langs;
1095
1096
        $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
1097
1098
        $return = '<div class="box-flex-item box-flex-grow-zero">';
1099
        $return .= '<div class="info-box info-box-sm">';
1100
        $return .= '<span class="info-box-icon bg-infobox-action">';
1101
        $return .= img_picto('', $this->picto);
1102
        $return .= '</span>';
1103
        $return .= '<div class="info-box-content">';
1104
        $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . (method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref) . '</span>';
1105
        $return .= '<input class="fright" id="cb' . $this->id . '" class="flat checkforselect" type="checkbox" name="toselect[]" value="' . $this->id . '"' . ($selected ? ' checked="checked"' : '') . '>';
1106
        if (!empty($arraydata['user'])) {
1107
            $return .= '<br><span class="info-box-label ">' . $arraydata['user'] . '</span>';
1108
        }
1109
        if (!empty($arraydata['job'])) {
1110
            //$return .= '<br><span class="info-box-label opacitymedium">'.$langs->trans("JobProfile").'</span> : ';
1111
            $return .= '<br><span class="info-box-label ">' . $arraydata['job'] . '</span>';
1112
        }
1113
        if (property_exists($this, 'date_start') && property_exists($this, 'date_end')) {
1114
            $return .= '<br><div class ="nothing"><span class="info-box-label ">' . dol_print_date($this->db->jdate($this->date_start), 'day') . '</span>';
1115
            $return .= ' - <span class="info-box-label ">' . dol_print_date($this->db->jdate($this->date_end), 'day') . '</span></div>';
1116
        }
1117
        $return .= '</div>';
1118
        $return .= '</div>';
1119
        $return .= '</div>';
1120
        return $return;
1121
    }
1122
}
1123