Completed
Branch develop (ed9822)
by
unknown
23:49
created

Task::hasTimeSpent()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 28
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 17
nc 6
nop 0
dl 0
loc 28
rs 8.5806
c 0
b 0
f 0
1
<?php
2
/* Copyright (C) 2008-2014	Laurent Destailleur	<[email protected]>
3
 * Copyright (C) 2010-2012	Regis Houssin		<[email protected]>
4
 * Copyright (C) 2014       Marcos García       <[email protected]>
5
 *
6
 * This program is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation; either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
/**
21
 *      \file       htdocs/projet/class/task.class.php
22
 *      \ingroup    project
23
 *      \brief      This file is a CRUD class file for Task (Create/Read/Update/Delete)
24
 */
25
26
require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
27
28
29
/**
30
 * 	Class to manage tasks
31
 */
32
class Task extends CommonObject
33
{
34
    public $element='project_task';		//!< Id that identify managed objects
35
    public $table_element='projet_task';	//!< Name of table without prefix where object is stored
36
    public $fk_element='fk_task';
37
    public $picto = 'task';
38
    protected $childtables=array('projet_task_time');    // To test if we can delete object
39
    
40
    var $fk_task_parent;
41
    var $label;
42
    var $description;
43
    var $duration_effective;		// total of time spent on this task
44
    var $planned_workload;
45
    var $date_c;
46
    var $date_start;
47
    var $date_end;
48
    var $progress;
49
    var $fk_statut;
50
    var $priority;
51
    var $fk_user_creat;
52
    var $fk_user_valid;
53
	var $rang;
54
55
	var $timespent_min_date;
56
	var $timespent_max_date;
57
	var $timespent_total_duration;
58
	var $timespent_total_amount;
59
	var $timespent_nblinesnull;
60
	var $timespent_nblines;
61
	// For detail of lines of timespent record, there is the property ->lines in common
62
	
63
	// Var used to call method addTimeSpent(). Bad practice.
64
    var $timespent_id;
65
    var $timespent_duration;
66
    var $timespent_old_duration;
67
    var $timespent_date;
68
    var $timespent_datehour;		// More accurate start date (same than timespent_date but includes hours, minutes and seconds)
69
    var $timespent_withhour;		// 1 = we entered also start hours for timesheet line
70
    var $timespent_fk_user;
71
    var $timespent_note;
72
73
    public $oldcopy;
74
75
76
    /**
77
     *  Constructor
78
     *
79
     *  @param      DoliDB		$db      Database handler
80
     */
81
    function __construct($db)
82
    {
83
        $this->db = $db;
84
    }
85
86
87
    /**
88
     *  Create into database
89
     *
90
     *  @param	User	$user        	User that create
91
     *  @param 	int		$notrigger	    0=launch triggers after, 1=disable triggers
92
     *  @return int 		        	<0 if KO, Id of created object if OK
93
     */
94
    function create($user, $notrigger=0)
95
    {
96
        global $conf, $langs;
97
98
        $error=0;
99
100
        // Clean parameters
101
        $this->label = trim($this->label);
102
        $this->description = trim($this->description);
103
104
        // Check parameters
105
        // Put here code to add control on parameters values
106
107
        // Insert request
108
        $sql = "INSERT INTO ".MAIN_DB_PREFIX."projet_task (";
109
        $sql.= "fk_projet";
110
		$sql.= ", ref";
111
        $sql.= ", fk_task_parent";
112
        $sql.= ", label";
113
        $sql.= ", description";
114
        $sql.= ", datec";
115
        $sql.= ", fk_user_creat";
116
        $sql.= ", dateo";
117
        $sql.= ", datee";
118
        $sql.= ", planned_workload";
119
        $sql.= ", progress";
120
        $sql.= ") VALUES (";
121
        $sql.= $this->fk_project;
122
		$sql.= ", ".(!empty($this->ref)?"'".$this->db->escape($this->ref)."'":'null');
123
        $sql.= ", ".$this->fk_task_parent;
124
        $sql.= ", '".$this->db->escape($this->label)."'";
125
        $sql.= ", '".$this->db->escape($this->description)."'";
126
        $sql.= ", '".$this->db->idate($this->date_c)."'";
127
        $sql.= ", ".$user->id;
128
        $sql.= ", ".($this->date_start!=''?"'".$this->db->idate($this->date_start)."'":'null');
129
        $sql.= ", ".($this->date_end!=''?"'".$this->db->idate($this->date_end)."'":'null');
130
        $sql.= ", ".($this->planned_workload!=''?$this->planned_workload:0);
131
        $sql.= ", ".($this->progress!=''?$this->progress:0);
132
        $sql.= ")";
133
134
        $this->db->begin();
135
136
        dol_syslog(get_class($this)."::create", LOG_DEBUG);
137
        $resql=$this->db->query($sql);
138
        if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
139
140
        if (! $error)
141
        {
142
            $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."projet_task");
143
144
            if (! $notrigger)
145
            {
146
                // Call trigger
147
                $result=$this->call_trigger('TASK_CREATE',$user);
148
                if ($result < 0) { $error++; }
149
                // End call triggers
150
            }
151
        }
152
153
        // Update extrafield
154
        if (! $error)
155
        {
156
        	if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
157
        	{
158
        		$result=$this->insertExtraFields();
159
        		if ($result < 0)
160
        		{
161
        			$error++;
162
        		}
163
        	}
164
        }
165
166
        // Commit or rollback
167
        if ($error)
168
        {
169
            foreach($this->errors as $errmsg)
170
            {
171
                dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR);
172
                $this->error.=($this->error?', '.$errmsg:$errmsg);
173
            }
174
            $this->db->rollback();
175
            return -1*$error;
176
        }
177
        else
178
        {
179
            $this->db->commit();
180
            return $this->id;
181
        }
182
    }
183
184
185
    /**
186
     *  Load object in memory from database
187
     *
188
     *  @param	int		$id			Id object
189
     *  @param	int		$ref		ref object
190
     *  @return int 		        <0 if KO, 0 if not found, >0 if OK
191
     */
192
    function fetch($id,$ref='')
193
    {
194
        global $langs;
195
196
        $sql = "SELECT";
197
        $sql.= " t.rowid,";
198
		$sql.= " t.ref,";
199
        $sql.= " t.fk_projet,";
200
        $sql.= " t.fk_task_parent,";
201
        $sql.= " t.label,";
202
        $sql.= " t.description,";
203
        $sql.= " t.duration_effective,";
204
        $sql.= " t.planned_workload,";
205
        $sql.= " t.datec,";
206
        $sql.= " t.dateo,";
207
        $sql.= " t.datee,";
208
        $sql.= " t.fk_user_creat,";
209
        $sql.= " t.fk_user_valid,";
210
        $sql.= " t.fk_statut,";
211
        $sql.= " t.progress,";
212
        $sql.= " t.priority,";
213
        $sql.= " t.note_private,";
214
		$sql.= " t.note_public,";
215
		$sql.= " t.rang";
216
        $sql.= " FROM ".MAIN_DB_PREFIX."projet_task as t";
217
        $sql.= " WHERE ";
218
        if (!empty($ref)) {
219
        	$sql.="t.ref = '".$this->db->escape($ref)."'";
220
        }else {
221
        	$sql.="t.rowid = ".$id;
222
        }
223
224
        dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
225
        $resql=$this->db->query($sql);
226
        if ($resql)
227
        {
228
            $num_rows = $this->db->num_rows($resql);
229
            
230
            if ($num_rows)
231
            {
232
                $obj = $this->db->fetch_object($resql);
233
234
                $this->id					= $obj->rowid;
235
				$this->ref					= $obj->ref;
236
                $this->fk_project			= $obj->fk_projet;
237
                $this->fk_task_parent		= $obj->fk_task_parent;
238
                $this->label				= $obj->label;
239
                $this->description			= $obj->description;
240
                $this->duration_effective	= $obj->duration_effective;
241
                $this->planned_workload		= $obj->planned_workload;
242
                $this->date_c				= $this->db->jdate($obj->datec);
243
                $this->date_start			= $this->db->jdate($obj->dateo);
244
                $this->date_end				= $this->db->jdate($obj->datee);
245
                $this->fk_user_creat		= $obj->fk_user_creat;
246
                $this->fk_user_valid		= $obj->fk_user_valid;
247
                $this->fk_statut			= $obj->fk_statut;
248
                $this->progress				= $obj->progress;
249
                $this->priority				= $obj->priority;
250
                $this->note_private			= $obj->note_private;
251
                $this->note_public			= $obj->note_public;
252
				$this->rang					= $obj->rang;
253
            }
254
255
            $this->db->free($resql);
256
257
            if ($num_rows) return 1;
258
            else return 0;
259
        }
260
        else
261
        {
262
            $this->error="Error ".$this->db->lasterror();
263
            return -1;
264
        }
265
    }
266
267
268
    /**
269
     *  Update database
270
     *
271
     *  @param	User	$user        	User that modify
272
     *  @param  int		$notrigger	    0=launch triggers after, 1=disable triggers
273
     *  @return int			         	<=0 if KO, >0 if OK
274
     */
275
    function update($user=null, $notrigger=0)
276
    {
277
        global $conf, $langs;
278
        $error=0;
279
280
        // Clean parameters
281
        if (isset($this->fk_project)) $this->fk_project=trim($this->fk_project);
0 ignored issues
show
Documentation Bug introduced by
The property $fk_project was declared of type integer, but trim($this->fk_project) is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
282
		if (isset($this->ref)) $this->ref=trim($this->ref);
283
        if (isset($this->fk_task_parent)) $this->fk_task_parent=trim($this->fk_task_parent);
284
        if (isset($this->label)) $this->label=trim($this->label);
285
        if (isset($this->description)) $this->description=trim($this->description);
286
        if (isset($this->duration_effective)) $this->duration_effective=trim($this->duration_effective);
287
        if (isset($this->planned_workload)) $this->planned_workload=trim($this->planned_workload);
288
289
        // Check parameters
290
        // Put here code to add control on parameters values
291
292
        // Update request
293
        $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task SET";
294
        $sql.= " fk_projet=".(isset($this->fk_project)?$this->fk_project:"null").",";
295
		$sql.= " ref=".(isset($this->ref)?"'".$this->db->escape($this->ref)."'":"'".$this->id."'").",";
296
        $sql.= " fk_task_parent=".(isset($this->fk_task_parent)?$this->fk_task_parent:"null").",";
297
        $sql.= " label=".(isset($this->label)?"'".$this->db->escape($this->label)."'":"null").",";
298
        $sql.= " description=".(isset($this->description)?"'".$this->db->escape($this->description)."'":"null").",";
299
        $sql.= " duration_effective=".(isset($this->duration_effective)?$this->duration_effective:"null").",";
300
        $sql.= " planned_workload=".((isset($this->planned_workload) && $this->planned_workload != '')?$this->planned_workload:"null").",";
301
        $sql.= " dateo=".($this->date_start!=''?"'".$this->db->idate($this->date_start)."'":'null').",";
302
        $sql.= " datee=".($this->date_end!=''?"'".$this->db->idate($this->date_end)."'":'null').",";
303
        $sql.= " progress=".$this->progress.",";
304
        $sql.= " rang=".((!empty($this->rang))?$this->rang:"0");
305
        $sql.= " WHERE rowid=".$this->id;
306
307
        $this->db->begin();
308
309
        dol_syslog(get_class($this)."::update", LOG_DEBUG);
310
        $resql = $this->db->query($sql);
311
        if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
312
313
        if (! $error)
314
        {
315
            if (! $notrigger)
316
            {
317
                // Call trigger
318
                $result=$this->call_trigger('TASK_MODIFY',$user);
0 ignored issues
show
Bug introduced by
It seems like $user defined by parameter $user on line 275 can be null; however, CommonObject::call_trigger() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
319
                if ($result < 0) { $error++; }
320
                // End call triggers
321
            }
322
        }
323
324
        //Update extrafield
325
        if (!$error) {
326
        	if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
327
        	{
328
        		$result=$this->insertExtraFields();
329
        		if ($result < 0)
330
        		{
331
        			$error++;
332
        		}
333
        	}
334
        }
335
336
        if (! $error && (is_object($this->oldcopy) && $this->oldcopy->ref !== $this->ref))
337
        {
338
            // We remove directory
339
            if ($conf->projet->dir_output)
340
            {
341
                $project = new Project($this->db);
342
                $project->fetch($this->fk_project);
343
344
                $olddir = $conf->projet->dir_output.'/'.dol_sanitizeFileName($project->ref).'/'.dol_sanitizeFileName($this->oldcopy->ref);
345
                $newdir = $conf->projet->dir_output.'/'.dol_sanitizeFileName($project->ref).'/'.dol_sanitizeFileName($this->ref);
346
                if (file_exists($olddir))
347
                {
348
                    include_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
349
                    $res=dol_move($olddir, $newdir);
350
                    if (! $res)
351
                    {
352
                        $langs->load("errors");
353
                        $this->error=$langs->trans('ErrorFailToRenameDir',$olddir,$newdir);
354
                        $error++;
355
                    }
356
                }
357
            }
358
        }
359
360
        // Commit or rollback
361
        if ($error)
362
        {
363
            foreach($this->errors as $errmsg)
364
            {
365
                dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
366
                $this->error.=($this->error?', '.$errmsg:$errmsg);
367
            }
368
            $this->db->rollback();
369
            return -1*$error;
370
        }
371
        else
372
        {
373
            $this->db->commit();
374
            return 1;
375
        }
376
    }
377
378
379
    /**
380
     *	Delete task from database
381
     *
382
     *	@param	User	$user        	User that delete
383
     *  @param  int		$notrigger	    0=launch triggers after, 1=disable triggers
384
     *	@return	int						<0 if KO, >0 if OK
385
     */
386
    function delete($user, $notrigger=0)
387
    {
388
389
        global $conf, $langs;
390
        require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
391
392
        $error=0;
393
394
        $this->db->begin();
395
396
        if ($this->hasChildren() > 0)
397
        {
398
            dol_syslog(get_class($this)."::delete Can't delete record as it has some sub tasks", LOG_WARNING);
399
            $this->error='ErrorRecordHasSubTasks';
400
            $this->db->rollback();
401
            return 0;
402
        }
403
404
        $objectisused = $this->isObjectUsed($this->id);
405
        if (! empty($objectisused))
406
        {
407
            dol_syslog(get_class($this)."::delete Can't delete record as it has some child", LOG_WARNING);
408
            $this->error='ErrorRecordHasChildren';
409
            $this->db->rollback();
410
            return 0;
411
        }
412
        
413
        if (! $error)
414
        {
415
            // Delete linked contacts
416
            $res = $this->delete_linked_contact();
417
            if ($res < 0)
418
            {
419
                $this->error='ErrorFailToDeleteLinkedContact';
420
                //$error++;
421
                $this->db->rollback();
422
                return 0;
423
            }
424
        }
425
426
        if (! $error)
427
        {
428
	        $sql = "DELETE FROM ".MAIN_DB_PREFIX."projet_task_time";
429
	        $sql.= " WHERE fk_task=".$this->id;
430
431
	        $resql = $this->db->query($sql);
432
	        if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
433
        }
434
435
        if (! $error)
436
        {
437
	        $sql = "DELETE FROM ".MAIN_DB_PREFIX."projet_task_extrafields";
438
	        $sql.= " WHERE fk_object=".$this->id;
439
440
	        $resql = $this->db->query($sql);
441
	        if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
442
        }
443
444
        if (! $error)
445
        {
446
	        $sql = "DELETE FROM ".MAIN_DB_PREFIX."projet_task";
447
	        $sql.= " WHERE rowid=".$this->id;
448
449
	        $resql = $this->db->query($sql);
450
	        if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
451
        }
452
453
        if (! $error)
454
        {
455
            if (! $notrigger)
456
            {
457
                // Call trigger
458
                $result=$this->call_trigger('TASK_DELETE',$user);
459
                if ($result < 0) { $error++; }
460
                // End call triggers
461
            }
462
        }
463
464
        // Commit or rollback
465
        if ($error)
466
        {
467
            foreach($this->errors as $errmsg)
468
            {
469
                dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
470
                $this->error.=($this->error?', '.$errmsg:$errmsg);
471
            }
472
            $this->db->rollback();
473
            return -1*$error;
474
        }
475
        else
476
		{
477
			//Delete associated link file
478
	        if ($conf->projet->dir_output)
479
	        {
480
	        	$projectstatic=new Project($this->db);
481
	        	$projectstatic->fetch($this->fk_project);
482
483
	            $dir = $conf->projet->dir_output . "/" . dol_sanitizeFileName($projectstatic->ref) . '/' . dol_sanitizeFileName($this->id);
484
	            dol_syslog(get_class($this)."::delete dir=".$dir, LOG_DEBUG);
485
	            if (file_exists($dir))
486
	            {
487
	            	require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php';
488
	                $res = @dol_delete_dir_recursive($dir);
489
	                if (!$res)
490
	                {
491
	                    $this->error = 'ErrorFailToDeleteDir';
492
	                    $this->db->rollback();
493
	                    return 0;
494
	                }
495
	            }
496
	        }
497
498
            $this->db->commit();
499
500
	        return 1;
501
        }
502
    }
503
504
    /**
505
     *	Return nb of children
506
     *
507
     *	@return	int		<0 if KO, 0 if no children, >0 if OK
508
     */
509
    function hasChildren()
510
    {
511
    	$error=0;
512
        $ret=0;
513
514
        $sql = "SELECT COUNT(*) as nb";
515
        $sql.= " FROM ".MAIN_DB_PREFIX."projet_task";
516
        $sql.= " WHERE fk_task_parent=".$this->id;
517
518
        dol_syslog(get_class($this)."::hasChildren", LOG_DEBUG);
519
        $resql = $this->db->query($sql);
520
        if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
521
        else
522
        {
523
            $obj=$this->db->fetch_object($resql);
524
            if ($obj) $ret=$obj->nb;
525
            $this->db->free($resql);
526
        }
527
528
        if (! $error)
529
        {
530
            return $ret;
531
        }
532
        else
533
        {
534
            return -1;
535
        }
536
    }
537
    
538
	/**
539
     *	Return nb of time spent
540
     *
541
     *	@return	int		<0 if KO, 0 if no children, >0 if OK
542
     */
543
    function hasTimeSpent()
544
    {
545
    	$error=0;
546
        $ret=0;
547
548
        $sql = "SELECT COUNT(*) as nb";
549
        $sql.= " FROM ".MAIN_DB_PREFIX."projet_task_time";
550
        $sql.= " WHERE fk_task=".$this->id;
551
552
        dol_syslog(get_class($this)."::hasTimeSpent", LOG_DEBUG);
553
        $resql = $this->db->query($sql);
554
        if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
555
        else
556
        {
557
            $obj=$this->db->fetch_object($resql);
558
            if ($obj) $ret=$obj->nb;
559
            $this->db->free($resql);
560
        }
561
562
        if (! $error)
563
        {
564
            return $ret;
565
        }
566
        else
567
        {
568
            return -1;
569
        }
570
    }
571
572
573
    /**
574
     *	Return clicable name (with picto eventually)
575
     *
576
     *	@param	int		$withpicto		0=No picto, 1=Include picto into link, 2=Only picto
577
     *	@param	string	$option			'withproject' or ''
578
     *  @param	string	$mode			Mode 'task', 'time', 'contact', 'note', document' define page to link to.
579
     * 	@param	int		$addlabel		0=Default, 1=Add label into string, >1=Add first chars into string
580
     *  @param	string	$sep			Separator between ref and label if option addlabel is set
581
     *  @param	int   	$notooltip		1=Disable tooltip
582
     *	@return	string					Chaine avec URL
583
     */
584
    function getNomUrl($withpicto=0,$option='',$mode='task', $addlabel=0, $sep=' - ', $notooltip=0)
585
    {
586
        global $conf, $langs, $user;
587
588
        if (! empty($conf->dol_no_mouse_hover)) $notooltip=1;   // Force disable tooltips
589
        
590
        $result='';
591
        $label = '<u>' . $langs->trans("ShowTask") . '</u>';
592
        if (! empty($this->ref))
593
            $label .= '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
594
        if (! empty($this->label))
595
            $label .= '<br><b>' . $langs->trans('LabelTask') . ':</b> ' . $this->label;
596
        if ($this->date_start || $this->date_end)
597
        {
598
        	$label .= "<br>".get_date_range($this->date_start,$this->date_end,'',$langs,0);
599
        }
600
        
601
        $url = DOL_URL_ROOT.'/projet/tasks/'.$mode.'.php?id='.$this->id.($option=='withproject'?'&withproject=1':'');
602
603
        $linkclose = '';
604
        if (empty($notooltip))
605
        {
606
            if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
607
            {
608
                $label=$langs->trans("ShowTask");
609
                $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"';
610
            }
611
            $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"';
612
            $linkclose.=' class="classfortooltip"';
613
        }
614
        
615
        $linkstart = '<a href="'.$url.'"';
616
        $linkstart.=$linkclose.'>';
617
        $linkend='</a>';
618
        
619
        $picto='projecttask';
620
621
        if ($withpicto) $result.=($linkstart.img_object(($notooltip?'':$label), $picto, ($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).$linkend);
622
        if ($withpicto && $withpicto != 2) $result.=' ';
623
        if ($withpicto != 2) $result.=$linkstart.$this->ref.$linkend . (($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
624
        return $result;
625
    }
626
627
    /**
628
     *  Initialise an instance with random values.
629
     *  Used to build previews or test instances.
630
     *	id must be 0 if object instance is a specimen.
631
     *
632
     *  @return	void
633
     */
634
    function initAsSpecimen()
635
    {
636
        $this->id=0;
637
638
        $this->fk_projet='';
639
		$this->ref='TK01';
640
        $this->fk_task_parent='';
641
        $this->label='Specimen task TK01';
642
        $this->duration_effective='';
643
        $this->fk_user_creat='';
644
        $this->progress='25';
645
        $this->fk_statut='';
646
        $this->note='This is a specimen task not';
647
    }
648
649
    /**
650
     * Return list of tasks for all projects or for one particular project
651
     * Sort order is on project, then on position of task, and last on start date of first level task
652
     *
653
     * @param	User	$usert				Object user to limit tasks affected to a particular user
654
     * @param	User	$userp				Object user to limit projects of a particular user and public projects
655
     * @param	int		$projectid			Project id
656
     * @param	int		$socid				Third party id
657
     * @param	int		$mode				0=Return list of tasks and their projects, 1=Return projects and tasks if exists
658
     * @param	string	$filteronprojref	Filter on project ref
659
     * @param	string	$filteronprojstatus	Filter on project status
660
     * @param	string	$morewherefilter	Add more filter into where SQL request (must start with ' AND ...')
661
     * @param	string	$filteronprojuser	Filter on user that is a contact of project
662
     * @param	string	$filterontaskuser	Filter on user assigned to task
663
     * @return 	array						Array of tasks
664
     */
665
    function getTasksArray($usert=0, $userp=0, $projectid=0, $socid=0, $mode=0, $filteronprojref='', $filteronprojstatus=-1, $morewherefilter='',$filteronprojuser=0,$filterontaskuser=0)
666
    {
667
        global $conf;
668
669
        $tasks = array();
670
671
        //print $usert.'-'.$userp.'-'.$projectid.'-'.$socid.'-'.$mode.'<br>';
672
673
        // List of tasks (does not care about permissions. Filtering will be done later)
674
        $sql = "SELECT p.rowid as projectid, p.ref, p.title as plabel, p.public, p.fk_statut as projectstatus,";
675
        $sql.= " t.rowid as taskid, t.ref as taskref, t.label, t.description, t.fk_task_parent, t.duration_effective, t.progress, t.fk_statut as status,";
676
        $sql.= " t.dateo as date_start, t.datee as date_end, t.planned_workload, t.rang,";
677
        $sql.= " s.rowid as thirdparty_id, s.nom as thirdparty_name";
678
        $sql.= " FROM ".MAIN_DB_PREFIX."projet as p";
679
        $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON p.fk_soc = s.rowid";
680
        if ($mode == 0)
681
        {
682
            if ($filteronprojuser > 0)
683
            {
684
                $sql.= ", ".MAIN_DB_PREFIX."element_contact as ec";
685
                $sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc";
686
            }
687
            $sql.= ", ".MAIN_DB_PREFIX."projet_task as t";
688
            if ($filterontaskuser > 0)
689
            {
690
                $sql.= ", ".MAIN_DB_PREFIX."element_contact as ec2";
691
                $sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc2";
692
            }
693
            $sql.= " WHERE p.entity IN (".getEntity('project',1).")";
694
            $sql.= " AND t.fk_projet = p.rowid";
695
        }
696
        elseif ($mode == 1)
697
        {
698
            if ($filteronprojuser > 0)
699
            {
700
                $sql.= ", ".MAIN_DB_PREFIX."element_contact as ec";
701
                $sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc";
702
            }
703
            if ($filterontaskuser > 0)
704
            {
705
                $sql.= ", ".MAIN_DB_PREFIX."projet_task as t";
706
                $sql.= ", ".MAIN_DB_PREFIX."element_contact as ec2";
707
                $sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc2";
708
            }
709
            else 
710
            {
711
                $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t on t.fk_projet = p.rowid";
712
            }
713
            $sql.= " WHERE p.entity IN (".getEntity('project',1).")";
714
        }
715
        else return 'BadValueForParameterMode';
716
717
        if ($filteronprojuser > 0)
718
        {
719
            $sql.= " AND p.rowid = ec.element_id";
720
            $sql.= " AND ctc.rowid = ec.fk_c_type_contact";
721
            $sql.= " AND ctc.element = 'project'";
722
            $sql.= " AND ec.fk_socpeople = ".$filteronprojuser;
723
            $sql.= " AND ec.statut = 4";
724
            $sql.= " AND ctc.source = 'internal'";
725
        }
726
        if ($filterontaskuser > 0)
727
        {
728
            $sql.= " AND t.fk_projet = p.rowid";
729
            $sql.= " AND p.rowid = ec2.element_id";
730
            $sql.= " AND ctc2.rowid = ec2.fk_c_type_contact";
731
            $sql.= " AND ctc2.element = 'project_task'";
732
            $sql.= " AND ec2.fk_socpeople = ".$filterontaskuser;
733
            $sql.= " AND ec2.statut = 4";
734
            $sql.= " AND ctc2.source = 'internal'";
735
        }
736
        if ($socid)	$sql.= " AND p.fk_soc = ".$socid;
737
        if ($projectid) $sql.= " AND p.rowid in (".$projectid.")";
738
        if ($filteronprojref) $sql.= " AND p.ref LIKE '%".$filteronprojref."%'";
739
        if ($filteronprojstatus > -1) $sql.= " AND p.fk_statut = ".$filteronprojstatus;
740
        if ($morewherefilter) $sql.=$morewherefilter;
741
        $sql.= " ORDER BY p.ref, t.rang, t.dateo";
742
743
        //print $sql;exit;
744
        dol_syslog(get_class($this)."::getTasksArray", LOG_DEBUG);
745
        $resql = $this->db->query($sql);
746
        if ($resql)
747
        {
748
            $num = $this->db->num_rows($resql);
749
            $i = 0;
750
            // Loop on each record found, so each couple (project id, task id)
751
            while ($i < $num)
752
            {
753
                $error=0;
754
755
                $obj = $this->db->fetch_object($resql);
756
757
                if ((! $obj->public) && (is_object($userp)))	// If not public project and we ask a filter on project owned by a user
758
                {
759
                    if (! $this->getUserRolesForProjectsOrTasks($userp, 0, $obj->projectid, 0))
760
                    {
761
                        $error++;
762
                    }
763
                }
764
                if (is_object($usert))							// If we ask a filter on a user affected to a task
765
                {
766
                    if (! $this->getUserRolesForProjectsOrTasks(0, $usert, $obj->projectid, $obj->taskid))
767
                    {
768
                        $error++;
769
                    }
770
                }
771
772
                if (! $error)
773
                {
774
					$tasks[$i] = new Task($this->db);
775
                    $tasks[$i]->id				= $obj->taskid;
776
					$tasks[$i]->ref				= $obj->taskref;
777
                    $tasks[$i]->fk_project		= $obj->projectid;
778
                    $tasks[$i]->projectref		= $obj->ref;
779
                    $tasks[$i]->projectlabel	= $obj->plabel;
780
                    $tasks[$i]->projectstatus	= $obj->projectstatus;
781
                    $tasks[$i]->label			= $obj->label;
782
                    $tasks[$i]->description		= $obj->description;
783
                    $tasks[$i]->fk_parent		= $obj->fk_task_parent;      // deprecated
784
                    $tasks[$i]->fk_task_parent	= $obj->fk_task_parent;
785
                    $tasks[$i]->duration		= $obj->duration_effective;
786
                    $tasks[$i]->planned_workload= $obj->planned_workload;
787
                    $tasks[$i]->progress		= $obj->progress;
788
                    $tasks[$i]->fk_statut		= $obj->status;
789
                    $tasks[$i]->public			= $obj->public;
790
                    $tasks[$i]->date_start		= $this->db->jdate($obj->date_start);
791
                    $tasks[$i]->date_end		= $this->db->jdate($obj->date_end);
792
                    $tasks[$i]->rang	   		= $obj->rang;
793
                    
794
                    $tasks[$i]->thirdparty_id	= $obj->thirdparty_id;
795
                    $tasks[$i]->thirdparty_name	= $obj->thirdparty_name;
796
                }
797
798
                $i++;
799
            }
800
            $this->db->free($resql);
801
        }
802
        else
803
        {
804
            dol_print_error($this->db);
805
        }
806
807
        return $tasks;
808
    }
809
810
    /**
811
     * Return list of roles for a user for each projects or each tasks (or a particular project or a particular task).
812
     *
813
     * @param	User	$userp			      Return roles on project for this internal user. If set, usert and taskid must not be defined.
814
     * @param	User	$usert			      Return roles on task for this internal user. If set userp must NOT be defined. -1 means no filter.
815
     * @param 	int		$projectid		      Project id list separated with , to filter on project
816
     * @param 	int		$taskid			      Task id to filter on a task
817
     * @param	integer	$filteronprojstatus	  Filter on project status if userp is set. Not used if userp not defined.
818
     * @return 	array					      Array (projectid => 'list of roles for project' or taskid => 'list of roles for task')
819
     */
820
    function getUserRolesForProjectsOrTasks($userp, $usert, $projectid='', $taskid=0, $filteronprojstatus=-1)
821
    {
822
        $arrayroles = array();
823
824
        dol_syslog(get_class($this)."::getUserRolesForProjectsOrTasks userp=".is_object($userp)." usert=".is_object($usert)." projectid=".$projectid." taskid=".$taskid);
825
826
        // We want role of user for a projet or role of user for a task. Both are not possible.
827
        if (empty($userp) && empty($usert))
828
        {
829
            $this->error="CallWithWrongParameters";
830
            return -1;
831
        }
832
        if (! empty($userp) && ! empty($usert))
833
        {
834
            $this->error="CallWithWrongParameters";
835
            return -1;
836
        }
837
838
        /* Liste des taches et role sur les projets ou taches */
839
        $sql = "SELECT pt.rowid as pid, ec.element_id, ctc.code, ctc.source";
840
        if ($userp) $sql.= " FROM ".MAIN_DB_PREFIX."projet as pt";
841
        if ($usert && $filteronprojstatus > -1) $sql.= " FROM ".MAIN_DB_PREFIX."projet as p, ".MAIN_DB_PREFIX."projet_task as pt";
842
        if ($usert && $filteronprojstatus <= -1) $sql.= " FROM ".MAIN_DB_PREFIX."projet_task as pt";
843
        $sql.= ", ".MAIN_DB_PREFIX."element_contact as ec";
844
        $sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc";
845
        $sql.= " WHERE pt.rowid = ec.element_id";
846
        if ($userp && $filteronprojstatus > -1) $sql.= " AND pt.fk_statut = ".$filteronprojstatus;
847
        if ($usert && $filteronprojstatus > -1) $sql.= " AND pt.fk_projet = p.rowid AND p.fk_statut = ".$filteronprojstatus;
848
        if ($userp) $sql.= " AND ctc.element = 'project'";
849
        if ($usert) $sql.= " AND ctc.element = 'project_task'";
850
        $sql.= " AND ctc.rowid = ec.fk_c_type_contact";
851
        if ($userp) $sql.= " AND ec.fk_socpeople = ".$userp->id;
852
        if ($usert) $sql.= " AND ec.fk_socpeople = ".$usert->id;
853
        $sql.= " AND ec.statut = 4";
854
        $sql.= " AND ctc.source = 'internal'";
855
        if ($projectid)
856
        {
857
            if ($userp) $sql.= " AND pt.rowid in (".$projectid.")";
858
            if ($usert) $sql.= " AND pt.fk_projet in (".$projectid.")";
859
        }
860
        if ($taskid)
861
        {
862
            if ($userp) $sql.= " ERROR SHOULD NOT HAPPENS";
863
            if ($usert) $sql.= " AND pt.rowid = ".$taskid;
864
        }
865
        //print $sql;
866
867
        dol_syslog(get_class($this)."::getUserRolesForProjectsOrTasks execute request", LOG_DEBUG);
868
        $resql = $this->db->query($sql);
869
        if ($resql)
870
        {
871
            $num = $this->db->num_rows($resql);
872
            $i = 0;
873
            while ($i < $num)
874
            {
875
                $obj = $this->db->fetch_object($resql);
876
                if (empty($arrayroles[$obj->pid])) $arrayroles[$obj->pid] = $obj->code;
877
                else $arrayroles[$obj->pid].=','.$obj->code;
878
                $i++;
879
            }
880
            $this->db->free($resql);
881
        }
882
        else
883
        {
884
            dol_print_error($this->db);
885
        }
886
887
        return $arrayroles;
888
    }
889
890
891
    /**
892
     * 	Return list of id of contacts of task
893
     *
894
     *	@param	string	$source		Source
895
     *  @return array				Array of id of contacts
896
     */
897
    function getListContactId($source='internal')
898
    {
899
        $contactAlreadySelected = array();
900
        $tab = $this->liste_contact(-1,$source);
901
        //var_dump($tab);
902
        $num=count($tab);
903
        $i = 0;
904
        while ($i < $num)
905
        {
906
            if ($source == 'thirdparty') $contactAlreadySelected[$i] = $tab[$i]['socid'];
907
            else  $contactAlreadySelected[$i] = $tab[$i]['id'];
908
            $i++;
909
        }
910
        return $contactAlreadySelected;
911
    }
912
913
914
    /**
915
     *  Add time spent
916
     *
917
     *  @param	User	$user           User object
918
     *  @param  int		$notrigger	    0=launch triggers after, 1=disable triggers
919
     *  @return	int                     <=0 if KO, >0 if OK
920
     */
921
    function addTimeSpent($user, $notrigger=0)
922
    {
923
        global $conf,$langs;
924
925
        dol_syslog(get_class($this)."::addTimeSpent", LOG_DEBUG);
926
927
        $ret = 0;
928
929
        // Check parameters
930
        if (! is_object($user))
931
        {
932
        	dol_print_error('',"Method addTimeSpent was called with wrong parameter user");
933
        	return -1;
934
        }
935
936
        // Clean parameters
937
        if (isset($this->timespent_note)) $this->timespent_note = trim($this->timespent_note);
938
		if (empty($this->timespent_datehour)) $this->timespent_datehour = $this->timespent_date;
939
940
        $this->db->begin();
941
942
        $sql = "INSERT INTO ".MAIN_DB_PREFIX."projet_task_time (";
943
        $sql.= "fk_task";
944
        $sql.= ", task_date";
945
        $sql.= ", task_datehour";
946
        $sql.= ", task_date_withhour";
947
        $sql.= ", task_duration";
948
        $sql.= ", fk_user";
949
        $sql.= ", note";
950
        $sql.= ") VALUES (";
951
        $sql.= $this->id;
952
        $sql.= ", '".$this->db->idate($this->timespent_date)."'";
953
        $sql.= ", '".$this->db->idate($this->timespent_datehour)."'";
954
        $sql.= ", ".(empty($this->timespent_withhour)?0:1);
955
        $sql.= ", ".$this->timespent_duration;
956
        $sql.= ", ".$this->timespent_fk_user;
957
        $sql.= ", ".(isset($this->timespent_note)?"'".$this->db->escape($this->timespent_note)."'":"null");
958
        $sql.= ")";
959
960
        $resql=$this->db->query($sql);
961
        if ($resql)
962
        {
963
            $tasktime_id = $this->db->last_insert_id(MAIN_DB_PREFIX."projet_task_time");
964
            $ret = $tasktime_id;
965
			$this->timespent_id = $ret;
966
			
967
            if (! $notrigger)
968
            {
969
                // Call trigger
970
                $result=$this->call_trigger('TASK_TIMESPENT_CREATE',$user);
971
                if ($result < 0) { $ret=-1; }
972
                // End call triggers
973
            }
974
        }
975
        else
976
		{
977
            $this->error=$this->db->lasterror();
978
            $ret = -1;
979
        }
980
981
        if ($ret > 0)
982
        {
983
        	// Recalculate amount of time spent for task and update denormalized field
984
            $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task";
985
            $sql.= " SET duration_effective = (SELECT SUM(task_duration) FROM ".MAIN_DB_PREFIX."projet_task_time as ptt where ptt.fk_task = ".$this->id.")";
986
			if (isset($this->progress)) $sql.= ", progress = " . $this->progress;	// Do not overwrite value if not provided
987
            $sql.= " WHERE rowid = ".$this->id;
988
989
            dol_syslog(get_class($this)."::addTimeSpent", LOG_DEBUG);
990
            if (! $this->db->query($sql) )
991
            {
992
                $this->error=$this->db->lasterror();
993
                $ret = -2;
994
            }
995
996
            $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task_time";
997
            $sql.= " SET thm = (SELECT thm FROM ".MAIN_DB_PREFIX."user WHERE rowid = ".$this->timespent_fk_user.")";	// set average hour rate of user
998
            $sql.= " WHERE rowid = ".$tasktime_id;
0 ignored issues
show
Bug introduced by
The variable $tasktime_id does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
999
1000
            dol_syslog(get_class($this)."::addTimeSpent", LOG_DEBUG);
1001
            if (! $this->db->query($sql) )
1002
            {
1003
                $this->error=$this->db->lasterror();
1004
                $ret = -2;
1005
            }
1006
        }
1007
1008
        if ($ret >0)
1009
        {
1010
        	$this->db->commit();
1011
        }
1012
        else
1013
		{
1014
        	$this->db->rollback();
1015
        }
1016
        return $ret;
1017
    }
1018
1019
    /**
1020
     *  Calculate total of time spent for task
1021
     *
1022
     *  @param  int     $userid     Filter on user id. 0=No filter
1023
     *  @return array		        Array of info for task array('min_date', 'max_date', 'total_duration', 'total_amount', 'nblines', 'nblinesnull')
1024
     */
1025
    function getSummaryOfTimeSpent($userid=0)
1026
    {
1027
        global $langs;
1028
1029
        $id=$this->id;
1030
        if (empty($id)) 
1031
        {
1032
            dol_syslog("getSummaryOfTimeSpent called on a not loaded task", LOG_ERR);
1033
            return -1; 
1034
        }
1035
1036
        $result=array();
1037
1038
        $sql = "SELECT";
1039
        $sql.= " MIN(t.task_datehour) as min_date,";
1040
        $sql.= " MAX(t.task_datehour) as max_date,";
1041
        $sql.= " SUM(t.task_duration) as total_duration,";
1042
        $sql.= " SUM(t.task_duration / 3600 * ".$this->db->ifsql("t.thm IS NULL", 0, "t.thm").") as total_amount,";
1043
        $sql.= " COUNT(t.rowid) as nblines,";
1044
        $sql.= " SUM(".$this->db->ifsql("t.thm IS NULL", 1, 0).") as nblinesnull";
1045
        $sql.= " FROM ".MAIN_DB_PREFIX."projet_task_time as t";
1046
        $sql.= " WHERE t.fk_task = ".$id;
1047
        if ($userid > 0) $sql.=" AND t.fk_user = ".$userid;
1048
        
1049
        dol_syslog(get_class($this)."::getSummaryOfTimeSpent", LOG_DEBUG);
1050
        $resql=$this->db->query($sql);
1051
        if ($resql)
1052
        {
1053
            $obj = $this->db->fetch_object($resql);
1054
1055
            $result['min_date'] = $obj->min_date;               // deprecated. use the ->timespent_xxx instead
1056
            $result['max_date'] = $obj->max_date;               // deprecated. use the ->timespent_xxx instead
1057
            $result['total_duration'] = $obj->total_duration;   // deprecated. use the ->timespent_xxx instead
1058
            
1059
            $this->timespent_min_date=$this->db->jdate($obj->min_date);
1060
            $this->timespent_max_date=$this->db->jdate($obj->max_date);
1061
            $this->timespent_total_duration=$obj->total_duration;
1062
            $this->timespent_total_amount=$obj->total_amount;
1063
            $this->timespent_nblinesnull=($obj->nblinesnull?$obj->nblinesnull:0);
1064
            $this->timespent_nblines=($obj->nblines?$obj->nblines:0);
1065
            
1066
            $this->db->free($resql);
1067
        }
1068
        else
1069
        {
1070
            dol_print_error($this->db);
1071
        }
1072
        return $result;
1073
    }
1074
1075
    /**
1076
     *  Calculate quantity and value of time consumed using the thm (hourly amount value of work for user entering time)
1077
     *
1078
     *	@param		User		$fuser		Filter on a dedicated user
1079
     *  @param		string		$dates		Start date (ex 00:00:00)
1080
     *  @param		string		$datee		End date (ex 23:59:59)
1081
     *  @return 	array	        		Array of info for task array('amount','nbseconds','nblinesnull')
1082
     */
1083
    function getSumOfAmount($fuser='', $dates='', $datee='')
1084
    {
1085
        global $langs;
1086
1087
        if (empty($id)) $id=$this->id;
0 ignored issues
show
Bug introduced by
The variable $id seems only to be defined at a later point. As such the call to empty() seems to always evaluate to true.

This check marks calls to isset(...) or empty(...) that are found before the variable itself is defined. These will always have the same result.

This is likely the result of code being shifted around. Consider removing these calls.

Loading history...
1088
1089
        $result=array();
1090
1091
        $sql = "SELECT";
1092
        $sql.= " SUM(t.task_duration) as nbseconds,";
1093
        $sql.= " SUM(t.task_duration / 3600 * ".$this->db->ifsql("t.thm IS NULL", 0, "t.thm").") as amount, SUM(".$this->db->ifsql("t.thm IS NULL", 1, 0).") as nblinesnull";
1094
        $sql.= " FROM ".MAIN_DB_PREFIX."projet_task_time as t";
1095
        $sql.= " WHERE t.fk_task = ".$id;
1096
        if (is_object($fuser) && $fuser->id > 0)
1097
        {
1098
        	$sql.=" AND fk_user = ".$fuser->id;
1099
        }
1100
    	if ($dates > 0)
1101
		{
1102
			$datefieldname="task_datehour";
1103
			$sql.=" AND (".$datefieldname." >= '".$this->db->idate($dates)."' OR ".$datefieldname." IS NULL)";
1104
		}
1105
    	if ($datee > 0)
1106
		{
1107
			$datefieldname="task_datehour";
1108
			$sql.=" AND (".$datefieldname." <= '".$this->db->idate($datee)."' OR ".$datefieldname." IS NULL)";
1109
		}
1110
		//print $sql;
1111
1112
        dol_syslog(get_class($this)."::getSumOfAmount", LOG_DEBUG);
1113
        $resql=$this->db->query($sql);
1114
        if ($resql)
1115
        {
1116
            $obj = $this->db->fetch_object($resql);
1117
1118
            $result['amount'] = $obj->amount;
1119
            $result['nbseconds'] = $obj->nbseconds;
1120
            $result['nblinesnull'] = $obj->nblinesnull;
1121
1122
            $this->db->free($resql);
1123
            return $result;
1124
        }
1125
        else
1126
		{
1127
            dol_print_error($this->db);
1128
            return $result;
1129
        }
1130
    }
1131
1132
    /**
1133
     *  Load one record of time spent
1134
     *
1135
     *  @param	int		$id 	Id object
1136
     *  @return int		        <0 if KO, >0 if OK
1137
     */
1138
    function fetchTimeSpent($id)
1139
    {
1140
        global $langs;
1141
1142
        $sql = "SELECT";
1143
        $sql.= " t.rowid,";
1144
        $sql.= " t.fk_task,";
1145
        $sql.= " t.task_date,";
1146
        $sql.= " t.task_datehour,";
1147
        $sql.= " t.task_date_withhour,";
1148
        $sql.= " t.task_duration,";
1149
        $sql.= " t.fk_user,";
1150
        $sql.= " t.note";
1151
        $sql.= " FROM ".MAIN_DB_PREFIX."projet_task_time as t";
1152
        $sql.= " WHERE t.rowid = ".$id;
1153
1154
        dol_syslog(get_class($this)."::fetchTimeSpent", LOG_DEBUG);
1155
        $resql=$this->db->query($sql);
1156
        if ($resql)
1157
        {
1158
            if ($this->db->num_rows($resql))
1159
            {
1160
                $obj = $this->db->fetch_object($resql);
1161
1162
                $this->timespent_id			= $obj->rowid;
1163
                $this->id					= $obj->fk_task;
1164
                $this->timespent_date		= $this->db->jdate($obj->task_date);
1165
                $this->timespent_datehour   = $this->db->jdate($obj->task_datehour);
1166
                $this->timespent_withhour   = $obj->task_date_withhour;
1167
                $this->timespent_duration	= $obj->task_duration;
1168
                $this->timespent_fk_user	= $obj->fk_user;
1169
                $this->timespent_note		= $obj->note;
1170
            }
1171
1172
            $this->db->free($resql);
1173
1174
            return 1;
1175
        }
1176
        else
1177
        {
1178
            $this->error="Error ".$this->db->lasterror();
1179
            return -1;
1180
        }
1181
    }
1182
1183
    /**
1184
     *	Update time spent
1185
     *
1186
     *  @param	User	$user           User id
1187
     *  @param  int		$notrigger	    0=launch triggers after, 1=disable triggers
1188
     *  @return	int						<0 if KO, >0 if OK
1189
     */
1190
    function updateTimeSpent($user, $notrigger=0)
1191
    {
1192
    	global $conf,$langs;
1193
1194
        $ret = 0;
1195
1196
        // Clean parameters
1197
        if (empty($this->timespent_datehour)) $this->timespent_datehour = $this->timespent_date;
1198
        if (isset($this->timespent_note)) $this->timespent_note = trim($this->timespent_note);
1199
1200
        $this->db->begin();
1201
1202
        $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task_time SET";
1203
        $sql.= " task_date = '".$this->db->idate($this->timespent_date)."',";
1204
        $sql.= " task_datehour = '".$this->db->idate($this->timespent_datehour)."',";
1205
        $sql.= " task_date_withhour = ".(empty($this->timespent_withhour)?0:1).",";
1206
        $sql.= " task_duration = ".$this->timespent_duration.",";
1207
        $sql.= " fk_user = ".$this->timespent_fk_user.",";
1208
        $sql.= " note = ".(isset($this->timespent_note)?"'".$this->db->escape($this->timespent_note)."'":"null");
1209
        $sql.= " WHERE rowid = ".$this->timespent_id;
1210
1211
        dol_syslog(get_class($this)."::updateTimeSpent", LOG_DEBUG);
1212
        if ($this->db->query($sql) )
1213
        {
1214
            if (! $notrigger)
1215
            {
1216
                // Call trigger
1217
                $result=$this->call_trigger('TASK_TIMESPENT_MODIFY',$user);
1218
                if ($result < 0)
1219
                {
1220
                    $this->db->rollback();
1221
                    $ret = -1;
1222
                }
1223
                else $ret = 1;
1224
                // End call triggers
1225
            }
1226
            else $ret = 1;
1227
        }
1228
        else
1229
        {
1230
            $this->error=$this->db->lasterror();
1231
            $this->db->rollback();
1232
            $ret = -1;
1233
        }
1234
1235
        if ($ret == 1 && ($this->timespent_old_duration != $this->timespent_duration))
1236
        {
1237
            $newDuration = $this->timespent_duration - $this->timespent_old_duration;
1238
1239
            $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task";
1240
            $sql.= " SET duration_effective = (SELECT SUM(task_duration) FROM ".MAIN_DB_PREFIX."projet_task_time as ptt where ptt.fk_task = ".$this->id.")";
1241
            $sql.= " WHERE rowid = ".$this->id;
1242
1243
            dol_syslog(get_class($this)."::updateTimeSpent", LOG_DEBUG);
1244
            if (! $this->db->query($sql) )
1245
            {
1246
                $this->error=$this->db->lasterror();
1247
                $this->db->rollback();
1248
                $ret = -2;
1249
            }
1250
        }
1251
1252
        if ($ret >= 0) $this->db->commit();
1253
        return $ret;
1254
    }
1255
1256
    /**
1257
     *  Delete time spent
1258
     *
1259
     *  @param	User	$user        	User that delete
1260
     *  @param  int		$notrigger	    0=launch triggers after, 1=disable triggers
1261
     *  @return	int						<0 if KO, >0 if OK
1262
     */
1263
    function delTimeSpent($user, $notrigger=0)
1264
    {
1265
        global $conf, $langs;
1266
1267
        $error=0;
1268
1269
        $this->db->begin();
1270
1271
        $sql = "DELETE FROM ".MAIN_DB_PREFIX."projet_task_time";
1272
        $sql.= " WHERE rowid = ".$this->timespent_id;
1273
1274
        dol_syslog(get_class($this)."::delTimeSpent", LOG_DEBUG);
1275
        $resql = $this->db->query($sql);
1276
        if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
1277
1278
        if (! $error)
1279
        {
1280
            if (! $notrigger)
1281
            {
1282
                // Call trigger
1283
                $result=$this->call_trigger('TASK_TIMESPENT_DELETE',$user);
1284
                if ($result < 0) { $error++; }
1285
                // End call triggers
1286
            }
1287
        }
1288
1289
        if (! $error)
1290
        {
1291
            $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task";
1292
            $sql.= " SET duration_effective = duration_effective - '".$this->timespent_duration."'";
1293
            $sql.= " WHERE rowid = ".$this->id;
1294
1295
            dol_syslog(get_class($this)."::delTimeSpent", LOG_DEBUG);
1296
            if ($this->db->query($sql) )
1297
            {
1298
                $result = 0;
1299
            }
1300
            else
1301
            {
1302
                $this->error=$this->db->lasterror();
1303
                $result = -2;
1304
            }
1305
        }
1306
1307
        // Commit or rollback
1308
        if ($error)
1309
        {
1310
            foreach($this->errors as $errmsg)
1311
            {
1312
                dol_syslog(get_class($this)."::delTimeSpent ".$errmsg, LOG_ERR);
1313
                $this->error.=($this->error?', '.$errmsg:$errmsg);
1314
            }
1315
            $this->db->rollback();
1316
            return -1*$error;
1317
        }
1318
        else
1319
        {
1320
            $this->db->commit();
1321
            return 1;
1322
        }
1323
    }
1324
1325
     /**	Load an object from its id and create a new one in database
1326
	 *
1327
	 *	@param	int		$fromid     			Id of object to clone
1328
	 *  @param	int		$project_id				Id of project to attach clone task
1329
	 *  @param	int		$parent_task_id			Id of task to attach clone task
1330
	 *  @param	bool	$clone_change_dt		recalculate date of task regarding new project start date
1331
	 *	@param	bool	$clone_affectation		clone affectation of project
1332
	 *	@param	bool	$clone_time				clone time of project
1333
	 *	@param	bool	$clone_file				clone file of project
1334
	 *  @param	bool	$clone_note				clone note of project
1335
	 *	@param	bool	$clone_prog				clone progress of project
1336
	 * 	@return	int								New id of clone
1337
	 */
1338
	function createFromClone($fromid,$project_id,$parent_task_id,$clone_change_dt=false,$clone_affectation=false,$clone_time=false,$clone_file=false,$clone_note=false,$clone_prog=false)
1339
	{
1340
		global $user,$langs,$conf;
1341
1342
		$error=0;
1343
1344
		//Use 00:00 of today if time is use on task.
1345
		$now=dol_mktime(0,0,0,dol_print_date(dol_now(),'%m'),dol_print_date(dol_now(),'%d'),dol_print_date(dol_now(),'%Y'));
1346
1347
		$datec = $now;
1348
1349
		$clone_task=new Task($this->db);
1350
		$origin_task=new Task($this->db);
1351
1352
		$clone_task->context['createfromclone']='createfromclone';
1353
1354
		$this->db->begin();
1355
1356
		// Load source object
1357
		$clone_task->fetch($fromid);
1358
		$clone_task->fetch_optionals();
1359
		//var_dump($clone_task->array_options);exit;
1360
		
1361
		$origin_task->fetch($fromid);
1362
1363
		$defaultref='';
1364
		$obj = empty($conf->global->PROJECT_TASK_ADDON)?'mod_task_simple':$conf->global->PROJECT_TASK_ADDON;
1365
		if (! empty($conf->global->PROJECT_TASK_ADDON) && is_readable(DOL_DOCUMENT_ROOT ."/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.".php"))
1366
		{
1367
			require_once DOL_DOCUMENT_ROOT ."/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.'.php';
1368
			$modTask = new $obj;
1369
			$defaultref = $modTask->getNextValue(0,$clone_task);
1370
		}
1371
1372
		$ori_project_id					= $clone_task->fk_project;
1373
1374
		$clone_task->id					= 0;
1375
		$clone_task->ref				= $defaultref;
1376
        $clone_task->fk_project			= $project_id;
1377
        $clone_task->fk_task_parent		= $parent_task_id;
1378
        $clone_task->date_c				= $datec;
1379
        $clone_task->planned_workload	= $origin_task->planned_workload;
1380
		$clone_task->rang				= $origin_task->rang;
1381
1382
        //Manage Task Date
1383
        if ($clone_change_dt)
1384
        {
1385
        	$projectstatic=new Project($this->db);
1386
        	$projectstatic->fetch($ori_project_id);
1387
1388
        	//Origin project strat date
1389
	    	$orign_project_dt_start = $projectstatic->date_start;
1390
1391
	    	//Calcultate new task start date with difference between origin proj start date and origin task start date
1392
	    	if (!empty($clone_task->date_start))
1393
	    	{
1394
				$clone_task->date_start			= $now + $clone_task->date_start - $orign_project_dt_start;
1395
	    	}
1396
1397
	    	//Calcultate new task end date with difference between origin proj end date and origin task end date
1398
	    	if (!empty($clone_task->date_end))
1399
	    	{
1400
				$clone_task->date_end			= $now + $clone_task->date_end - $orign_project_dt_start;
1401
	    	}
1402
1403
        }
1404
1405
		if (!$clone_prog)
1406
        {
1407
        	    $clone_task->progress=0;
1408
        }
1409
1410
		// Create clone
1411
		$result=$clone_task->create($user);
1412
1413
		// Other options
1414
		if ($result < 0)
1415
		{
1416
			$this->error=$clone_task->error;
1417
			$error++;
1418
		}
1419
1420
		// End
1421
		if (! $error)
1422
		{
1423
			$clone_task_id=$clone_task->id;
1424
			$clone_task_ref = $clone_task->ref;
1425
1426
       		//Note Update
1427
			if (!$clone_note)
1428
       		{
1429
        	    $clone_task->note_private='';
1430
    			$clone_task->note_public='';
1431
        	}
1432
        	else
1433
        	{
1434
        		$this->db->begin();
1435
				$res=$clone_task->update_note(dol_html_entity_decode($clone_task->note_public, ENT_QUOTES),'_public');
1436
				if ($res < 0)
1437
				{
1438
					$this->error.=$clone_task->error;
1439
					$error++;
1440
					$this->db->rollback();
1441
				}
1442
				else
1443
				{
1444
					$this->db->commit();
1445
				}
1446
1447
				$this->db->begin();
1448
				$res=$clone_task->update_note(dol_html_entity_decode($clone_task->note_private, ENT_QUOTES), '_private');
1449
				if ($res < 0)
1450
				{
1451
					$this->error.=$clone_task->error;
1452
					$error++;
1453
					$this->db->rollback();
1454
				}
1455
				else
1456
				{
1457
					$this->db->commit();
1458
				}
1459
        	}
1460
1461
			//Duplicate file
1462
			if ($clone_file)
1463
			{
1464
				require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1465
1466
				//retreive project origin ref to know folder to copy
1467
				$projectstatic=new Project($this->db);
1468
	        	$projectstatic->fetch($ori_project_id);
1469
	        	$ori_project_ref=$projectstatic->ref;
1470
1471
	        	if ($ori_project_id!=$project_id)
1472
	        	{
1473
	        		$projectstatic->fetch($project_id);
1474
	        		$clone_project_ref=$projectstatic->ref;
1475
	        	}
1476
	        	else
1477
	        	{
1478
	        		$clone_project_ref=$ori_project_ref;
1479
	        	}
1480
1481
				$clone_task_dir = $conf->projet->dir_output . "/" . dol_sanitizeFileName($clone_project_ref). "/" . dol_sanitizeFileName($clone_task_ref);
1482
				$ori_task_dir = $conf->projet->dir_output . "/" . dol_sanitizeFileName($ori_project_ref). "/" . dol_sanitizeFileName($fromid);
1483
1484
				$filearray=dol_dir_list($ori_task_dir,"files",0,'','(\.meta|_preview\.png)$','',SORT_ASC,1);
1485
				foreach($filearray as $key => $file)
1486
				{
1487
					if (!file_exists($clone_task_dir))
1488
					{
1489
						if (dol_mkdir($clone_task_dir) < 0)
1490
						{
1491
							$this->error.=$langs->trans('ErrorInternalErrorDetected').':dol_mkdir';
1492
							$error++;
1493
						}
1494
					}
1495
1496
					$rescopy = dol_copy($ori_task_dir . '/' . $file['name'], $clone_task_dir . '/' . $file['name'],0,1);
1497
					if (is_numeric($rescopy) && $rescopy < 0)
1498
					{
1499
						$this->error.=$langs->trans("ErrorFailToCopyFile",$ori_task_dir . '/' . $file['name'],$clone_task_dir . '/' . $file['name']);
1500
						$error++;
1501
					}
1502
				}
1503
			}
1504
1505
			// clone affectation
1506
			if ($clone_affectation)
1507
			{
1508
				$origin_task = new Task($this->db);
1509
				$origin_task->fetch($fromid);
1510
1511
				foreach(array('internal','external') as $source)
1512
				{
1513
					$tab = $origin_task->liste_contact(-1,$source);
1514
					$num=count($tab);
1515
					$i = 0;
1516
					while ($i < $num)
1517
					{
1518
						$clone_task->add_contact($tab[$i]['id'], $tab[$i]['code'], $tab[$i]['source']);
1519
						if ($clone_task->error == 'DB_ERROR_RECORD_ALREADY_EXISTS')
1520
						{
1521
							$langs->load("errors");
1522
							$this->error.=$langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType");
1523
							$error++;
1524
						}
1525
						else
1526
						{
1527
							if ($clone_task->error!='')
1528
							{
1529
								$this->error.=$clone_task->error;
1530
								$error++;
1531
							}
1532
						}
1533
						$i++;
1534
					}
1535
				}
1536
			}
1537
1538
			if($clone_time)
1539
			{
1540
				//TODO clone time of affectation
1541
			}
1542
		}
1543
1544
		unset($clone_task->context['createfromclone']);
1545
1546
		if (! $error)
1547
		{
1548
			$this->db->commit();
1549
			return $clone_task_id;
0 ignored issues
show
Bug introduced by
The variable $clone_task_id does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1550
		}
1551
		else
1552
		{
1553
			$this->db->rollback();
1554
			dol_syslog(get_class($this)."::createFromClone nbError: ".$error." error : " . $this->error, LOG_ERR);
1555
			return -1;
1556
		}
1557
	}
1558
1559
1560
	/**
1561
	 *	Return status label of object
1562
	 *
1563
	 *	@param	integer	$mode		0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto
1564
	 * 	@return	string	  			Label
1565
	 */
1566
	function getLibStatut($mode=0)
1567
	{
1568
		return $this->LibStatut($this->fk_statut,$mode);
1569
	}
1570
1571
	/**
1572
	 *	Return status label for an object
1573
	 *
1574
	 *	@param	int			$statut	  	Id statut
1575
	 *	@param	integer		$mode		0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto
1576
	 * 	@return	string	  				Label
1577
	 */
1578
	function LibStatut($statut,$mode=0)
1579
	{
1580
		// list of Statut of the task
1581
		$this->statuts[0]='Draft';
1582
		$this->statuts[1]='Validated';
1583
		$this->statuts[2]='Running';
1584
		$this->statuts[3]='Finish';
1585
		$this->statuts[4]='Transfered';
1586
		$this->statuts_short[0]='Draft';
1587
		$this->statuts_short[1]='Validated';
1588
		$this->statuts_short[2]='Running';
1589
		$this->statuts_short[3]='Finish';
1590
		$this->statuts_short[4]='Transfered';
1591
1592
		global $langs;
1593
1594
		if ($mode == 0)
1595
		{
1596
			return $langs->trans($this->statuts[$statut]);
1597
		}
1598
		if ($mode == 1)
1599
		{
1600
			return $langs->trans($this->statuts_short[$statut]);
1601
		}
1602
		if ($mode == 2)
1603
		{
1604
			if ($statut==0) return img_picto($langs->trans($this->statuts_short[$statut]),'statut0').' '.$langs->trans($this->statuts_short[$statut]);
1605
			if ($statut==1) return img_picto($langs->trans($this->statuts_short[$statut]),'statut1').' '.$langs->trans($this->statuts_short[$statut]);
1606
			if ($statut==2) return img_picto($langs->trans($this->statuts_short[$statut]),'statut3').' '.$langs->trans($this->statuts_short[$statut]);
1607
			if ($statut==3) return img_picto($langs->trans($this->statuts_short[$statut]),'statut4').' '.$langs->trans($this->statuts_short[$statut]);
1608
			if ($statut==4) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6').' '.$langs->trans($this->statuts_short[$statut]);
1609
			if ($statut==5) return img_picto($langs->trans($this->statuts_short[$statut]),'statut5').' '.$langs->trans($this->statuts_short[$statut]);
1610
		}
1611
		if ($mode == 3)
1612
		{
1613
			if ($statut==0) return img_picto($langs->trans($this->statuts_short[$statut]),'statut0');
1614
			if ($statut==1) return img_picto($langs->trans($this->statuts_short[$statut]),'statut1');
1615
			if ($statut==2) return img_picto($langs->trans($this->statuts_short[$statut]),'statut3');
1616
			if ($statut==3) return img_picto($langs->trans($this->statuts_short[$statut]),'statut4');
1617
			if ($statut==4) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
1618
			if ($statut==5) return img_picto($langs->trans($this->statuts_short[$statut]),'statut5');
1619
		}
1620
		if ($mode == 4)
1621
		{
1622
			if ($statut==0) return img_picto($langs->trans($this->statuts_short[$statut]),'statut0').' '.$langs->trans($this->statuts[$statut]);
1623
			if ($statut==1) return img_picto($langs->trans($this->statuts_short[$statut]),'statut1').' '.$langs->trans($this->statuts[$statut]);
1624
			if ($statut==2) return img_picto($langs->trans($this->statuts_short[$statut]),'statut3').' '.$langs->trans($this->statuts[$statut]);
1625
			if ($statut==3) return img_picto($langs->trans($this->statuts_short[$statut]),'statut4').' '.$langs->trans($this->statuts[$statut]);
1626
			if ($statut==4) return img_picto($langs->trans($this->statuts_short[$statut]),'statut6').' '.$langs->trans($this->statuts[$statut]);
1627
			if ($statut==5) return img_picto($langs->trans($this->statuts_short[$statut]),'statut5').' '.$langs->trans($this->statuts[$statut]);
1628
		}
1629
		if ($mode == 5)
1630
		{
1631
			if ($statut==0) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut0');
1632
			if ($statut==1) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut1');
1633
			if ($statut==2) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut3');
1634
			if ($statut==3) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut4');
1635
			if ($statut==4) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut6');
1636
			if ($statut==5) return $langs->trans($this->statuts_short[$statut]).' '.img_picto($langs->trans($this->statuts_short[$statut]),'statut5');
1637
		}
1638
	}
1639
1640
	/**
1641
	 *  Create an intervention document on disk using template defined into PROJECT_TASK_ADDON_PDF
1642
	 *
1643
	 *  @param	string		$modele			force le modele a utiliser ('' par defaut)
1644
	 *  @param	Translate	$outputlangs	objet lang a utiliser pour traduction
1645
	 *  @param  int			$hidedetails    Hide details of lines
1646
	 *  @param  int			$hidedesc       Hide description
1647
	 *  @param  int			$hideref        Hide ref
1648
	 *  @return int         				0 if KO, 1 if OK
1649
	 */
1650
	public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
1651
	{
1652
		global $conf,$langs;
1653
1654
		$langs->load("projects");
1655
1656
		if (! dol_strlen($modele)) {
1657
1658
			$modele = 'nodefault';
1659
1660
			if ($this->modelpdf) {
1661
				$modele = $this->modelpdf;
1662
			} elseif (! empty($conf->global->PROJECT_TASK_ADDON_PDF)) {
1663
				$modele = $conf->global->PROJECT_TASK_ADDON_PDF;
1664
			}
1665
		}
1666
1667
		$modelpath = "core/modules/project/task/doc/";
1668
1669
		return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
1670
	}
1671
1672
	
1673
	/**
1674
	 * Load indicators for dashboard (this->nbtodo and this->nbtodolate)
1675
	 *
1676
	 * @param	User	$user   Objet user
1677
	 * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK
1678
	 */
1679
	function load_board($user)
1680
	{
1681
	    global $conf, $langs;
1682
	
1683
	    $mine=0; $socid=$user->societe_id;
1684
	    
1685
	    $projectstatic = new Project($this->db);
1686
	    $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user,$mine,1,$socid);
1687
	    
1688
	    // List of tasks (does not care about permissions. Filtering will be done later)
1689
	    $sql = "SELECT p.rowid as projectid, p.fk_statut as projectstatus,";
1690
	    $sql.= " t.rowid as taskid, t.progress as progress, t.fk_statut as status,";
1691
	    $sql.= " t.dateo as date_start, t.datee as datee";
1692
        $sql.= " FROM ".MAIN_DB_PREFIX."projet as p";
1693
        $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid";
1694
        if (! $user->rights->societe->client->voir && ! $socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON sc.fk_soc = s.rowid";
1695
        $sql.= ", ".MAIN_DB_PREFIX."projet_task as t";
1696
        $sql.= " WHERE p.entity IN (".getEntity('project').')';
1697
        $sql.= " AND p.fk_statut = 1";
1698
        $sql.= " AND t.fk_projet = p.rowid";
1699
        $sql.= " AND t.progress < 100";         // tasks to do
1700
        if ($mine || ! $user->rights->projet->all->lire) $sql.= " AND p.rowid IN (".$projectsListId.")";
1701
        // No need to check company, as filtering of projects must be done by getProjectsAuthorizedForUser
1702
        //if ($socid || ! $user->rights->societe->client->voir)	$sql.= "  AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")";
1703
        if ($socid) $sql.= "  AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")";
1704
        if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND ((s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id.") OR (s.rowid IS NULL))";
1705
        //print $sql;
1706
	    $resql=$this->db->query($sql);
1707
	    if ($resql)
1708
	    {
1709
	        $task_static = new Task($this->db);
1710
	
1711
	        $response = new WorkboardResponse();
1712
	        $response->warning_delay = $conf->projet->task->warning_delay/60/60/24;
1713
	        $response->label = $langs->trans("OpenedTasks");
1714
	        if ($user->rights->projet->all->lire) $response->url = DOL_URL_ROOT.'/projet/tasks/list.php?mainmenu=project';
1715
	        else $response->url = DOL_URL_ROOT.'/projet/tasks/list.php?mode=mine&amp;mainmenu=project';
1716
	        $response->img = img_object($langs->trans("Tasks"),"task");
1717
	
1718
	        // This assignment in condition is not a bug. It allows walking the results.
1719
	        while ($obj=$this->db->fetch_object($resql))
1720
	        {
1721
	            $response->nbtodo++;
1722
	
1723
	            $task_static->projectstatus = $obj->projectstatus;
1724
	            $task_static->progress = $obj->progress;
1725
	            $task_static->fk_statut = $obj->status;
1726
	            $task_static->date_end = $this->db->jdate($obj->datee);
1727
	
1728
	            if ($task_static->hasDelay()) {
1729
	                $response->nbtodolate++;
1730
	            }
1731
	        }
1732
	
1733
	        return $response;
1734
	    }
1735
	    else
1736
	    {
1737
	        $this->error=$this->db->error();
1738
	        return -1;
1739
	    }
1740
	}
1741
	
1742
	/**
1743
	 * Is the task delayed?
1744
	 *
1745
	 * @return bool
1746
	 */
1747
	public function hasDelay()
1748
	{
1749
	    global $conf;
1750
	
1751
        if (! ($this->progress >= 0 && $this->progress < 100)) {
1752
            return false;
1753
        }
1754
1755
        $now = dol_now();
1756
1757
        $datetouse = ($this->date_end > 0) ? $this->date_end : ($this->datee > 0 ? $this->datee : 0);
1758
1759
        return ($datetouse > 0 && ($datetouse < ($now - $conf->projet->task->warning_delay)));
1760
	}	
1761
}
1762