Passed
Branch develop (5cbde9)
by
unknown
26:38
created

project.lib.php ➔ projectLinesPerDay()   F

Complexity

Conditions 63
Paths > 20000

Size

Total Lines 358

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 63
nc 429496.7295
nop 15
dl 0
loc 358
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

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:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/* Copyright (C) 2006-2015 Laurent Destailleur  <[email protected]>
3
 * Copyright (C) 2010      Regis Houssin        <[email protected]>
4
 * Copyright (C) 2011      Juanjo Menent        <[email protected]>
5
 * Copyright (C) 2018       Frédéric France         <[email protected]>
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19
 * or see http://www.gnu.org/
20
 */
21
22
/**
23
 *	    \file       htdocs/core/lib/project.lib.php
24
 *		\brief      Functions used by project module
25
 *      \ingroup    project
26
 */
27
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
28
29
30
/**
31
 * Prepare array with list of tabs
32
 *
33
 * @param   Object	$object		Object related to tabs
34
 * @return  array				Array of tabs to show
35
 */
36
function project_prepare_head($object)
37
{
38
	global $db, $langs, $conf, $user;
39
40
	$h = 0;
41
	$head = array();
42
43
	$head[$h][0] = DOL_URL_ROOT.'/projet/card.php?id='.$object->id;
44
	$head[$h][1] = $langs->trans("Project");
45
	$head[$h][2] = 'project';
46
	$h++;
47
48
	$nbContact = count($object->liste_contact(-1, 'internal')) + count($object->liste_contact(-1, 'external'));
49
	$head[$h][0] = DOL_URL_ROOT.'/projet/contact.php?id='.$object->id;
50
	$head[$h][1] = $langs->trans("ProjectContact");
51
	if ($nbContact > 0) $head[$h][1].= ' <span class="badge">'.$nbContact.'</span>';
52
	$head[$h][2] = 'contact';
53
	$h++;
54
55
	if (empty($conf->global->PROJECT_HIDE_TASKS))
56
	{
57
		// Then tab for sub level of projet, i mean tasks
58
		$head[$h][0] = DOL_URL_ROOT.'/projet/tasks.php?id='.$object->id;
59
		$head[$h][1] = $langs->trans("Tasks");
60
61
		require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
62
		$taskstatic=new Task($db);
63
		$nbTasks=count($taskstatic->getTasksArray(0, 0, $object->id, 0, 0));
64
		if ($nbTasks > 0) $head[$h][1].= ' <span class="badge">'.($nbTasks).'</span>';
65
		$head[$h][2] = 'tasks';
66
		$h++;
67
68
		$nbTimeSpent=0;
69
		$sql = "SELECT t.rowid";
70
		//$sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t, ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."user as u";
71
		//$sql .= " WHERE t.fk_user = u.rowid AND t.fk_task = pt.rowid";
72
		$sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t, ".MAIN_DB_PREFIX."projet_task as pt";
73
		$sql .= " WHERE t.fk_task = pt.rowid";
74
		$sql .= " AND pt.fk_projet =".$object->id;
75
		$resql = $db->query($sql);
76
		if ($resql)
77
		{
78
			$obj = $db->fetch_object($resql);
79
			if ($obj) $nbTimeSpent=1;
80
		}
81
		else dol_print_error($db);
82
83
		$head[$h][0] = DOL_URL_ROOT.'/projet/tasks/time.php?withproject=1&projectid='.$object->id;
84
		$head[$h][1] = $langs->trans("TimeSpent");
85
		if ($nbTimeSpent > 0) $head[$h][1].= ' <span class="badge">...</span>';
86
		$head[$h][2] = 'timespent';
87
		$h++;
88
	}
89
90
	if (! empty($conf->fournisseur->enabled) || ! empty($conf->propal->enabled) || ! empty($conf->commande->enabled)
91
		|| ! empty($conf->facture->enabled) || ! empty($conf->contrat->enabled)
92
		|| ! empty($conf->ficheinter->enabled) || ! empty($conf->agenda->enabled) || ! empty($conf->deplacement->enabled))
93
	{
94
		$head[$h][0] = DOL_URL_ROOT.'/projet/element.php?id='.$object->id;
95
		$head[$h][1] = $langs->trans("ProjectOverview");
96
		$head[$h][2] = 'element';
97
		$h++;
98
	}
99
100
	// Show more tabs from modules
101
	// Entries must be declared in modules descriptor with line
102
	// $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__');   to add new tab
103
	// $this->tabs = array('entity:-tabname);   												to remove a tab
104
	complete_head_from_modules($conf, $langs, $object, $head, $h, 'project');
105
106
107
	if (empty($conf->global->MAIN_DISABLE_NOTES_TAB))
108
	{
109
		$nbNote = 0;
110
		if(!empty($object->note_private)) $nbNote++;
111
		if(!empty($object->note_public)) $nbNote++;
112
		$head[$h][0] = DOL_URL_ROOT.'/projet/note.php?id='.$object->id;
113
		$head[$h][1] = $langs->trans('Notes');
114
		if ($nbNote > 0) $head[$h][1].= ' <span class="badge">'.$nbNote.'</span>';
115
		$head[$h][2] = 'notes';
116
		$h++;
117
	}
118
119
	require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
120
	require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
121
	$upload_dir = $conf->projet->dir_output . "/" . dol_sanitizeFileName($object->ref);
122
	$nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$'));
123
	$nbLinks=Link::count($db, $object->element, $object->id);
124
	$head[$h][0] = DOL_URL_ROOT.'/projet/document.php?id='.$object->id;
125
	$head[$h][1] = $langs->trans('Documents');
126
	if (($nbFiles+$nbLinks) > 0) $head[$h][1].= ' <span class="badge">'.($nbFiles+$nbLinks).'</span>';
127
	$head[$h][2] = 'document';
128
	$h++;
129
130
	// Manage discussion
131
	if (!empty($conf->global->PROJECT_ALLOW_COMMENT_ON_PROJECT))
132
	{
133
		$nbComments = $object->getNbComments();
134
		$head[$h][0] = DOL_URL_ROOT.'/projet/comment.php?id='.$object->id;
135
		$head[$h][1] = $langs->trans("CommentLink");
136
		if ($nbComments > 0) $head[$h][1].= ' <span class="badge">'.$nbComments.'</span>';
137
		$head[$h][2] = 'project_comment';
138
		$h++;
139
	}
140
141
	$head[$h][0] = DOL_URL_ROOT.'/projet/info.php?id='.$object->id;
142
	$head[$h][1].= $langs->trans("Events");
143
	if (! empty($conf->agenda->enabled) && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read) ))
144
	{
145
		$head[$h][1].= '/';
146
		$head[$h][1].= $langs->trans("Agenda");
147
	}
148
	$head[$h][2] = 'agenda';
149
	$h++;
150
151
	complete_head_from_modules($conf, $langs, $object, $head, $h, 'project', 'remove');
152
153
	return $head;
154
}
155
156
157
/**
158
 * Prepare array with list of tabs
159
 *
160
 * @param   Object	$object		Object related to tabs
161
 * @return  array				Array of tabs to show
162
 */
163
function task_prepare_head($object)
164
{
165
	global $db, $langs, $conf, $user;
166
	$h = 0;
167
	$head = array();
168
169
	$head[$h][0] = DOL_URL_ROOT.'/projet/tasks/task.php?id='.$object->id.(GETPOST('withproject')?'&withproject=1':'');
170
	$head[$h][1] = $langs->trans("Card");
171
	$head[$h][2] = 'task_task';
172
	$h++;
173
174
	$nbContact = count($object->liste_contact(-1, 'internal')) + count($object->liste_contact(-1, 'external'));
175
	$head[$h][0] = DOL_URL_ROOT.'/projet/tasks/contact.php?id='.$object->id.(GETPOST('withproject')?'&withproject=1':'');
176
	$head[$h][1] = $langs->trans("TaskRessourceLinks");
177
	if ($nbContact > 0) $head[$h][1].= ' <span class="badge">'.$nbContact.'</span>';
178
	$head[$h][2] = 'task_contact';
179
	$h++;
180
181
	// Is there timespent ?
182
	$nbTimeSpent=0;
183
	$sql = "SELECT t.rowid";
184
	//$sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t, ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."user as u";
185
	//$sql .= " WHERE t.fk_user = u.rowid AND t.fk_task = pt.rowid";
186
	$sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t";
187
	$sql .= " WHERE t.fk_task =".$object->id;
188
	$resql = $db->query($sql);
189
	if ($resql)
190
	{
191
		$obj = $db->fetch_object($resql);
192
		if ($obj) $nbTimeSpent=1;
193
	}
194
	else dol_print_error($db);
195
196
	$head[$h][0] = DOL_URL_ROOT.'/projet/tasks/time.php?id='.$object->id.(GETPOST('withproject')?'&withproject=1':'');
197
	$head[$h][1] = $langs->trans("TimeSpent");
198
	if ($nbTimeSpent > 0) $head[$h][1].= ' <span class="badge">...</span>';
199
	$head[$h][2] = 'task_time';
200
	$h++;
201
202
	// Show more tabs from modules
203
	// Entries must be declared in modules descriptor with line
204
	// $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__');   to add new tab
205
	// $this->tabs = array('entity:-tabname);   												to remove a tab
206
	complete_head_from_modules($conf, $langs, $object, $head, $h, 'task');
207
208
	if (empty($conf->global->MAIN_DISABLE_NOTES_TAB))
209
	{
210
		$nbNote = 0;
211
		if(!empty($object->note_private)) $nbNote++;
212
		if(!empty($object->note_public)) $nbNote++;
213
		$head[$h][0] = DOL_URL_ROOT.'/projet/tasks/note.php?id='.$object->id.(GETPOST('withproject')?'&withproject=1':'');
214
		$head[$h][1] = $langs->trans('Notes');
215
		if ($nbNote > 0) $head[$h][1].= ' <span class="badge">'.$nbNote.'</span>';
216
		$head[$h][2] = 'task_notes';
217
		$h++;
218
	}
219
220
	$head[$h][0] = DOL_URL_ROOT.'/projet/tasks/document.php?id='.$object->id.(GETPOST('withproject')?'&withproject=1':'');
221
	$filesdir = $conf->projet->dir_output . "/" . dol_sanitizeFileName($object->project->ref) . '/' .dol_sanitizeFileName($object->ref);
222
	include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
223
	include_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
224
	$nbFiles = count(dol_dir_list($filesdir, 'files', 0, '', '(\.meta|_preview.*\.png)$'));
225
	$nbLinks=Link::count($db, $object->element, $object->id);
226
	$head[$h][1] = $langs->trans('Documents');
227
	if (($nbFiles+$nbLinks) > 0) $head[$h][1].= ' <span class="badge">'.($nbFiles+$nbLinks).'</span>';
228
	$head[$h][2] = 'task_document';
229
	$h++;
230
231
	// Manage discussion
232
	if (!empty($conf->global->PROJECT_ALLOW_COMMENT_ON_TASK))
233
	{
234
		$nbComments = $object->getNbComments();
235
		$head[$h][0] = DOL_URL_ROOT.'/projet/tasks/comment.php?id='.$object->id.(GETPOST('withproject')?'&withproject=1':'');
236
		$head[$h][1] = $langs->trans("CommentLink");
237
		if ($nbComments > 0) $head[$h][1].= ' <span class="badge">'.$nbComments.'</span>';
238
		$head[$h][2] = 'task_comment';
239
		$h++;
240
	}
241
242
	complete_head_from_modules($conf, $langs, $object, $head, $h, 'task', 'remove');
243
244
	return $head;
245
}
246
247
/**
248
 * Prepare array with list of tabs
249
 *
250
 * @param	string	$mode		Mode
251
 * @param   string  $fuser      Filter on user
252
 * @return  array				Array of tabs to show
253
 */
254
function project_timesheet_prepare_head($mode, $fuser = null)
255
{
256
	global $langs, $conf, $user;
257
	$h = 0;
258
	$head = array();
259
260
	$h = 0;
261
262
	$param='';
263
	$param.=($mode?'&mode='.$mode:'');
264
	if (is_object($fuser) && $fuser->id > 0 && $fuser->id != $user->id) $param.='&search_usertoprocessid='.$fuser->id;
265
266
	if (empty($conf->global->PROJECT_DISABLE_TIMESHEET_PERWEEK))
267
	{
268
		$head[$h][0] = DOL_URL_ROOT."/projet/activity/perweek.php".($param?'?'.$param:'');
269
		$head[$h][1] = $langs->trans("InputPerWeek");
270
		$head[$h][2] = 'inputperweek';
271
		$h++;
272
	}
273
274
	if (empty($conf->global->PROJECT_DISABLE_TIMESHEET_PERTIME))
275
	{
276
		$head[$h][0] = DOL_URL_ROOT."/projet/activity/perday.php".($param?'?'.$param:'');
277
		$head[$h][1] = $langs->trans("InputPerDay");
278
		$head[$h][2] = 'inputperday';
279
		$h++;
280
	}
281
282
	/*if ($conf->global->MAIN_FEATURES_LEVEL >= 2)
283
	{
284
		$head[$h][0] = DOL_URL_ROOT."/projet/activity/perline.php".($param?'?'.$param:'');
285
		$head[$h][1] = $langs->trans("InputDetail");
286
		$head[$h][2] = 'inputperline';
287
		$h++;
288
	}*/
289
290
	complete_head_from_modules($conf, $langs, null, $head, $h, 'project_timesheet');
291
292
	complete_head_from_modules($conf, $langs, null, $head, $h, 'project_timesheet', 'remove');
293
294
	return $head;
295
}
296
297
298
/**
299
 * Prepare array with list of tabs
300
 *
301
 * @return  array				Array of tabs to show
302
 */
303
function project_admin_prepare_head()
304
{
305
	global $langs, $conf, $user;
306
	$h = 0;
307
	$head = array();
308
309
	$h = 0;
310
311
	$head[$h][0] = DOL_URL_ROOT."/projet/admin/project.php";
312
	$head[$h][1] = $langs->trans("Projects");
313
	$head[$h][2] = 'project';
314
	$h++;
315
316
	complete_head_from_modules($conf, $langs, null, $head, $h, 'project_admin');
317
318
	$head[$h][0] = DOL_URL_ROOT."/projet/admin/project_extrafields.php";
319
	$head[$h][1] = $langs->trans("ExtraFieldsProject");
320
	$head[$h][2] = 'attributes';
321
	$h++;
322
323
	$head[$h][0] = DOL_URL_ROOT.'/projet/admin/project_task_extrafields.php';
324
	$head[$h][1] = $langs->trans("ExtraFieldsProjectTask");
325
	$head[$h][2] = 'attributes_task';
326
	$h++;
327
328
	complete_head_from_modules($conf, $langs, null, $head, $h, 'project_admin', 'remove');
329
330
	return $head;
331
}
332
333
334
/**
335
 * Show task lines with a particular parent
336
 *
337
 * @param	string	   	$inc				    Line number (start to 0, then increased by recursive call)
338
 * @param   string		$parent				    Id of parent project to show (0 to show all)
339
 * @param   Task[]		$lines				    Array of lines
340
 * @param   int			$level				    Level (start to 0, then increased/decrease by recursive call), or -1 to show all level in order of $lines without the recursive groupment feature.
341
 * @param 	string		$var				    Color
342
 * @param 	int			$showproject		    Show project columns
343
 * @param	int			$taskrole			    Array of roles of user for each tasks
344
 * @param	int			$projectsListId		    List of id of project allowed to user (string separated with comma)
345
 * @param	int			$addordertick		    Add a tick to move task
346
 * @param   int         $projectidfortotallink  0 or Id of project to use on total line (link to see all time consumed for project)
347
 * @param   string      $filterprogresscalc     filter text
348
 * @param   string      $showbilltime           Add the column 'TimeToBill' and 'TimeBilled'
349
 * @return	void
350
 */
351
function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$taskrole, $projectsListId = '', $addordertick = 0, $projectidfortotallink = 0, $filterprogresscalc = '', $showbilltime = 0)
352
{
353
	global $user, $bc, $langs, $conf, $db;
354
	global $projectstatic, $taskstatic;
355
356
	$lastprojectid=0;
357
358
	$projectsArrayId=explode(',', $projectsListId);
359
	if ($filterprogresscalc!=='') {
360
		foreach ($lines as $key=>$line) {
361
			if (!empty($line->planned_workload) && !empty($line->duration)) {
362
				$filterprogresscalc = str_replace(' = ', ' == ', $filterprogresscalc);
363
				if (!eval($filterprogresscalc)) {
0 ignored issues
show
introduced by
The use of eval() is discouraged.
Loading history...
364
					unset($lines[$key]);
365
				}
366
			}
367
		}
368
		$lines=array_values($lines);
369
	}
370
371
	$numlines=count($lines);
372
373
	// We declare counter as global because we want to edit them into recursive call
374
	global $total_projectlinesa_spent, $total_projectlinesa_planned, $total_projectlinesa_spent_if_planned, $total_projectlinesa_declared_if_planned, $total_projectlinesa_tobill, $total_projectlinesa_billed;
375
376
	if ($level == 0)
377
	{
378
		$total_projectlinesa_spent=0;
379
		$total_projectlinesa_planned=0;
380
		$total_projectlinesa_spent_if_planned=0;
381
        $total_projectlinesa_declared_if_planned=0;
382
		$total_projectlinesa_tobill=0;
383
		$total_projectlinesa_billed=0;
384
	}
385
386
	for ($i = 0 ; $i < $numlines ; $i++)
387
	{
388
		if ($parent == 0 && $level >= 0) $level = 0;              // if $level = -1, we dont' use sublevel recursion, we show all lines
389
390
		// Process line
391
		// print "i:".$i."-".$lines[$i]->fk_project.'<br>';
392
393
		if ($lines[$i]->fk_parent == $parent || $level < 0)       // if $level = -1, we dont' use sublevel recursion, we show all lines
394
		{
395
			// Show task line.
396
			$showline=1;
397
			$showlineingray=0;
398
399
			// If there is filters to use
400
			if (is_array($taskrole))
401
			{
402
				// If task not legitimate to show, search if a legitimate task exists later in tree
403
				if (! isset($taskrole[$lines[$i]->id]) && $lines[$i]->id != $lines[$i]->fk_parent)
404
				{
405
					// So search if task has a subtask legitimate to show
406
					$foundtaskforuserdeeper=0;
407
					searchTaskInChild($foundtaskforuserdeeper, $lines[$i]->id, $lines, $taskrole);
408
					//print '$foundtaskforuserpeeper='.$foundtaskforuserdeeper.'<br>';
409
					if ($foundtaskforuserdeeper > 0)
410
					{
411
						$showlineingray=1;		// We will show line but in gray
412
					}
413
					else
414
					{
415
						$showline=0;			// No reason to show line
416
					}
417
				}
418
			}
419
			else
420
			{
421
				// Caller did not ask to filter on tasks of a specific user (this probably means he want also tasks of all users, into public project
422
				// or into all other projects if user has permission to).
423
				if (empty($user->rights->projet->all->lire))
424
				{
425
					// User is not allowed on this project and project is not public, so we hide line
426
					if (! in_array($lines[$i]->fk_project, $projectsArrayId))
427
					{
428
						// Note that having a user assigned to a task into a project user has no permission on, should not be possible
429
						// because assignement on task can be done only on contact of project.
430
						// If assignement was done and after, was removed from contact of project, then we can hide the line.
431
						$showline=0;
432
					}
433
				}
434
			}
435
436
			if ($showline)
437
			{
438
				// Break on a new project
439
				if ($parent == 0 && $lines[$i]->fk_project != $lastprojectid)
440
				{
441
					$var = !$var;
442
					$lastprojectid=$lines[$i]->fk_project;
443
				}
444
445
				print '<tr '.$bc[$var].' id="row-'.$lines[$i]->id.'">'."\n";
446
447
				$projectstatic->id=$lines[$i]->fk_project;
448
				$projectstatic->ref=$lines[$i]->projectref;
449
				$projectstatic->public=$lines[$i]->public;
450
				$projectstatic->title=$lines[$i]->projectlabel;
451
				$projectstatic->bill_time=$lines[$i]->bill_time;
452
453
				$taskstatic->id=$lines[$i]->id;
454
				$taskstatic->ref=$lines[$i]->ref;
455
				$taskstatic->label=($taskrole[$lines[$i]->id]?$langs->trans("YourRole").': '.$taskrole[$lines[$i]->id]:'');
456
				$taskstatic->projectstatus = $lines[$i]->projectstatus;
457
				$taskstatic->progress = $lines[$i]->progress;
458
				$taskstatic->fk_statut = $lines[$i]->status;
459
				$taskstatic->datee = $lines[$i]->date_end;
460
461
				if ($showproject)
462
				{
463
					// Project ref
464
					print "<td>";
465
					//if ($showlineingray) print '<i>';
466
					if ($lines[$i]->public || in_array($lines[$i]->fk_project, $projectsArrayId) || ! empty($user->rights->projet->all->lire)) print $projectstatic->getNomUrl(1);
467
					else print $projectstatic->getNomUrl(1, 'nolink');
468
					//if ($showlineingray) print '</i>';
469
					print "</td>";
470
471
					// Project status
472
					print '<td>';
473
					$projectstatic->statut=$lines[$i]->projectstatus;
474
					print $projectstatic->getLibStatut(2);
475
					print "</td>";
476
				}
477
478
				// Ref of task
479
				print '<td class="nowraponall">';
480
				if ($showlineingray)
481
				{
482
					print '<i>'.img_object('', 'projecttask').' '.$lines[$i]->ref.'</i>';
483
				}
484
				else
485
				{
486
					print $taskstatic->getNomUrl(1, 'withproject');
487
				}
488
				print '</td>';
489
490
				// Title of task
491
				print "<td>";
492
				if ($showlineingray) print '<i>';
493
				//else print '<a href="'.DOL_URL_ROOT.'/projet/tasks/task.php?id='.$lines[$i]->id.'&withproject=1">';
494
				for ($k = 0 ; $k < $level ; $k++)
495
				{
496
					print '<div class="marginleftonly">';
497
				}
498
				print $lines[$i]->label;
499
				for ($k = 0 ; $k < $level ; $k++)
500
				{
501
					print '</div>';
502
				}
503
				if ($showlineingray) print '</i>';
504
				//else print '</a>';
505
				print "</td>\n";
506
507
				// Date start
508
				print '<td class="center">';
509
				print dol_print_date($lines[$i]->date_start, 'dayhour');
510
				print '</td>';
511
512
				// Date end
513
				print '<td class="center">';
514
				print dol_print_date($lines[$i]->date_end, 'dayhour');
515
				if ($taskstatic->hasDelay()) print img_warning($langs->trans("Late"));
516
				print '</td>';
517
518
				$plannedworkloadoutputformat='allhourmin';
519
				$timespentoutputformat='allhourmin';
520
				if (! empty($conf->global->PROJECT_PLANNED_WORKLOAD_FORMAT)) $plannedworkloadoutputformat=$conf->global->PROJECT_PLANNED_WORKLOAD_FORMAT;
521
				if (! empty($conf->global->PROJECT_TIMES_SPENT_FORMAT)) $timespentoutputformat=$conf->global->PROJECT_TIME_SPENT_FORMAT;
522
523
				// Planned Workload (in working hours)
524
				print '<td class="right">';
525
				$fullhour=convertSecondToTime($lines[$i]->planned_workload, $plannedworkloadoutputformat);
526
				$workingdelay=convertSecondToTime($lines[$i]->planned_workload, 'all', 86400, 7);	// TODO Replace 86400 and 7 to take account working hours per day and working day per weeks
527
				if ($lines[$i]->planned_workload != '')
528
				{
529
					print $fullhour;
530
					// TODO Add delay taking account of working hours per day and working day per week
531
					//if ($workingdelay != $fullhour) print '<br>('.$workingdelay.')';
532
				}
533
				//else print '--:--';
534
				print '</td>';
535
536
				// Time spent
537
				print '<td class="right">';
538
				if ($showlineingray) print '<i>';
539
				else print '<a href="'.DOL_URL_ROOT.'/projet/tasks/time.php?id='.$lines[$i]->id.($showproject?'':'&withproject=1').'">';
540
				if ($lines[$i]->duration) print convertSecondToTime($lines[$i]->duration, $timespentoutputformat);
541
				else print '--:--';
542
				if ($showlineingray) print '</i>';
543
				else print '</a>';
544
				print '</td>';
545
546
				// Progress calculated (Note: ->duration is time spent)
547
				print '<td class="right">';
548
				if ($lines[$i]->planned_workload || $lines[$i]->duration)
549
				{
550
					if ($lines[$i]->planned_workload) print round(100 * $lines[$i]->duration / $lines[$i]->planned_workload, 2).' %';
551
					else print '<span class="opacitymedium">'.$langs->trans('WorkloadNotDefined').'</span>';
552
				}
553
				print '</td>';
554
555
				// Progress declared
556
				print '<td class="right">';
557
				if ($lines[$i]->progress != '')
558
				{
559
					print $lines[$i]->progress.' %';
560
				}
561
				print '</td>';
562
563
				if ($showbilltime)
564
				{
565
    				// Time not billed
566
    				print '<td class="right">';
567
    				if ($lines[$i]->bill_time)
568
    				{
569
    				    print convertSecondToTime($lines[$i]->tobill, 'allhourmin');
570
    				    $total_projectlinesa_tobill += $lines[$i]->tobill;
571
    				}
572
    				else
573
    				{
574
    				    print '<span class="opacitymedium">'.$langs->trans("NA").'</span>';
575
    				}
576
    				print '</td>';
577
578
    				// Time billed
579
    				print '<td class="right">';
580
    				if ($lines[$i]->bill_time)
581
    				{
582
    				    print convertSecondToTime($lines[$i]->billed, 'allhourmin');
583
    				    $total_projectlinesa_billed += $lines[$i]->billed;
584
    				}
585
    				else
586
    				{
587
    				    print '<span class="opacitymedium">'.$langs->trans("NA").'</span>';
588
    				}
589
    				print '</td>';
590
				}
591
592
				// Contacts of task
593
				if (! empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST))
594
				{
595
					print '<td>';
596
					foreach(array('internal','external') as $source)
597
					{
598
						$tab = $lines[$i]->liste_contact(-1, $source);
599
						$num=count($tab);
600
						if (!empty($num)){
601
							foreach ($tab as $contacttask){
602
								//var_dump($contacttask);
603
								if ($source == 'internal') $c = new User($db);
604
								else $c = new Contact($db);
605
								$c->fetch($contacttask['id']);
606
								print $c->getNomUrl(1) . ' (' . $contacttask['libelle'] . ')' . '<br>';
607
							}
608
						}
609
					}
610
					print '</td>';
611
				}
612
613
				// Tick to drag and drop
614
				if ($addordertick)
615
				{
616
					print '<td class="tdlineupdown hideonsmartphone center">&nbsp;</td>';
617
				}
618
619
				print "</tr>\n";
620
621
				if (! $showlineingray) $inc++;
622
623
				if ($level >= 0)    // Call sublevels
624
				{
625
					$level++;
626
					if ($lines[$i]->id) projectLinesa($inc, $lines[$i]->id, $lines, $level, $var, $showproject, $taskrole, $projectsListId, $addordertick, $projectidfortotallink, $filterprogresscalc, $showbilltime);
627
					$level--;
628
				}
629
630
				$total_projectlinesa_spent += $lines[$i]->duration;
631
				$total_projectlinesa_planned += $lines[$i]->planned_workload;
632
				if ($lines[$i]->planned_workload) $total_projectlinesa_spent_if_planned += $lines[$i]->duration;
633
                if ($lines[$i]->planned_workload) $total_projectlinesa_declared_if_planned += $lines[$i]->planned_workload * $lines[$i]->progress / 100;
634
			}
635
		}
636
		else
637
		{
638
			//$level--;
639
		}
640
	}
641
642
	if (($total_projectlinesa_planned > 0 || $total_projectlinesa_spent > 0 || $total_projectlinesa_tobill > 0 || $total_projectlinesa_billed > 0)
643
	    && $level <= 0)
644
	{
645
		print '<tr class="liste_total nodrag nodrop">';
646
		print '<td class="liste_total">'.$langs->trans("Total").'</td>';
647
		if ($showproject) print '<td></td><td></td>';
648
		print '<td></td>';
649
		print '<td></td>';
650
		print '<td></td>';
651
		print '<td class="nowrap liste_total right">';
652
		print convertSecondToTime($total_projectlinesa_planned, 'allhourmin');
653
		print '</td>';
654
		print '<td class="nowrap liste_total right">';
655
		if ($projectidfortotallink > 0) print '<a href="'.DOL_URL_ROOT.'/projet/tasks/time.php?projectid='.$projectidfortotallink.($showproject?'':'&withproject=1').'">';
656
		print convertSecondToTime($total_projectlinesa_spent, 'allhourmin');
657
		if ($projectidfortotallink > 0) print '</a>';
658
		print '</td>';
659
		print '<td class="nowrap liste_total right">';
660
		if ($total_projectlinesa_planned) print round(100 * $total_projectlinesa_spent / $total_projectlinesa_planned, 2).' %';
661
		print '</td>';
662
		print '<td class="nowrap liste_total right">';
663
        if ($total_projectlinesa_planned) print round(100 * $total_projectlinesa_declared_if_planned / $total_projectlinesa_planned, 2).' %';
664
		print '</td>';
665
		if ($showbilltime)
666
		{
667
    		print '<td class="nowrap liste_total right">';
668
    		print convertSecondToTime($total_projectlinesa_tobill, 'allhourmin');
669
    		print '</td>';
670
    		print '<td class="nowrap liste_total right">';
671
    		print convertSecondToTime($total_projectlinesa_billed, 'allhourmin');
672
    		print '</td>';
673
		}
674
		// Contacts of task
675
		if (! empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST))
676
		{
677
			print '<td></td>';
678
		}
679
		if ($addordertick) print '<td class="hideonsmartphone"></td>';
680
		print '</tr>';
681
	}
682
683
	return $inc;
684
}
685
686
687
/**
688
 * Output a task line into a pertime intput mode
689
 *
690
 * @param	string	   	$inc					Line number (start to 0, then increased by recursive call)
691
 * @param   string		$parent					Id of parent task to show (0 to show all)
692
 * @param	User|null	$fuser					Restrict list to user if defined
693
 * @param   Task[]		$lines					Array of lines
694
 * @param   int			$level					Level (start to 0, then increased/decrease by recursive call)
695
 * @param   string		$projectsrole			Array of roles user has on project
696
 * @param   string		$tasksrole				Array of roles user has on task
697
 * @param	string		$mine					Show only task lines I am assigned to
698
 * @param   int			$restricteditformytask	0=No restriction, 1=Enable add time only if task is a task i am affected to
699
 * @param	int			$preselectedday			Preselected day
700
 * @param   array       $isavailable			Array with data that say if user is available for several days for morning and afternoon
701
 * @param	int			$oldprojectforbreak		Old project id of last project break
702
 * @return  array								Array with time spent for $fuser for each day of week on tasks in $lines and substasks
703
 */
704
function projectLinesPerAction(&$inc, $parent, $fuser, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask, $preselectedday, &$isavailable, $oldprojectforbreak = 0)
705
{
706
	global $conf, $db, $user, $bc, $langs;
707
	global $form, $formother, $projectstatic, $taskstatic, $thirdpartystatic;
708
709
	$lastprojectid=0;
710
	$totalforeachline=array();
711
	$workloadforid=array();
712
	$lineswithoutlevel0=array();
713
714
	$numlines=count($lines);
715
716
	// Create a smaller array with sublevels only to be used later. This increase dramatically performances.
717
	if ($parent == 0) // Always and only if at first level
718
	{
719
		for ($i = 0 ; $i < $numlines ; $i++)
720
		{
721
			if ($lines[$i]->fk_task_parent) $lineswithoutlevel0[]=$lines[$i];
722
		}
723
	}
724
725
	if (empty($oldprojectforbreak))
726
	{
727
		$oldprojectforbreak = (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)?0:-1);	// 0 to start break , -1 no break
728
	}
729
730
	//dol_syslog('projectLinesPerDay inc='.$inc.' preselectedday='.$preselectedday.' task parent id='.$parent.' level='.$level." count(lines)=".$numlines." count(lineswithoutlevel0)=".count($lineswithoutlevel0));
731
	for ($i = 0 ; $i < $numlines ; $i++)
732
	{
733
		if ($parent == 0) $level = 0;
734
735
		//if ($lines[$i]->fk_task_parent == $parent)
736
		//{
737
			// If we want all or we have a role on task, we show it
738
			if (empty($mine) || ! empty($tasksrole[$lines[$i]->id]))
739
			{
740
				//dol_syslog("projectLinesPerWeek Found line ".$i.", a qualified task (i have role or want to show all tasks) with id=".$lines[$i]->id." project id=".$lines[$i]->fk_project);
741
742
				// Break on a new project
743
				if ($parent == 0 && $lines[$i]->fk_project != $lastprojectid)
744
				{
745
					$lastprojectid=$lines[$i]->fk_project;
746
					if ($preselectedday)
747
					{
748
						$projectstatic->id = $lines[$i]->fk_project;
749
					}
750
				}
751
752
				if (empty($workloadforid[$projectstatic->id]))
753
				{
754
					if ($preselectedday)
755
					{
756
						$projectstatic->loadTimeSpent($preselectedday, 0, $fuser->id);	// Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week
757
						$workloadforid[$projectstatic->id]=1;
758
					}
759
				}
760
761
				$projectstatic->id=$lines[$i]->fk_project;
762
				$projectstatic->ref=$lines[$i]->project_ref;
763
				$projectstatic->title=$lines[$i]->project_label;
764
				$projectstatic->public=$lines[$i]->public;
765
766
				$taskstatic->id=$lines[$i]->task_id;
0 ignored issues
show
Bug introduced by
The property task_id does not seem to exist on Task.
Loading history...
767
				$taskstatic->ref=($lines[$i]->task_ref?$lines[$i]->task_ref:$lines[$i]->task_id);
768
				$taskstatic->label=$lines[$i]->task_label;
769
				$taskstatic->date_start=$lines[$i]->date_start;
770
				$taskstatic->date_end=$lines[$i]->date_end;
771
772
				$thirdpartystatic->id=$lines[$i]->socid;
773
				$thirdpartystatic->name=$lines[$i]->thirdparty_name;
774
				$thirdpartystatic->email=$lines[$i]->thirdparty_email;
775
776
				if (empty($oldprojectforbreak) || ($oldprojectforbreak != -1 && $oldprojectforbreak != $projectstatic->id))
777
				{
778
					print '<tr class="oddeven trforbreak">'."\n";
779
					print '<td colspan="11">';
780
					print $projectstatic->getNomUrl(1, '', 0, $langs->transnoentitiesnoconv("YourRole").': '.$projectsrole[$lines[$i]->fk_project]);
781
					if ($projectstatic->title)
782
					{
783
						print ' - ';
784
						print $projectstatic->title;
785
					}
786
					print '</td>';
787
					print '</tr>';
788
				}
789
790
				if ($oldprojectforbreak != -1) $oldprojectforbreak = $projectstatic->id;
791
792
				print '<tr class="oddeven">'."\n";
793
794
				// User
795
				/*
796
				 print '<td class="nowrap">';
797
				 print $fuser->getNomUrl(1, 'withproject', 'time');
798
				 print '</td>';
799
				 */
800
801
				// Project
802
				print "<td>";
803
				if ($oldprojectforbreak == -1)
804
				{
805
					print $projectstatic->getNomUrl(1, '', 0, $langs->transnoentitiesnoconv("YourRole").': '.$projectsrole[$lines[$i]->fk_project]);
806
					print '<br>'.$projectstatic->title;
807
				}
808
				print "</td>";
809
810
				// Thirdparty
811
				print '<td class="tdoverflowmax100">';
812
				if ($thirdpartystatic->id > 0) print $thirdpartystatic->getNomUrl(1, 'project', 10);
813
				print '</td>';
814
815
				// Ref
816
				print '<td>';
817
				print '<!-- Task id = '.$lines[$i]->id.' -->';
818
				for ($k = 0 ; $k < $level ; $k++) print "&nbsp;&nbsp;&nbsp;";
819
				print $taskstatic->getNomUrl(1, 'withproject', 'time');
820
				// Label task
821
				print '<br>';
822
				for ($k = 0 ; $k < $level ; $k++) print "&nbsp;&nbsp;&nbsp;";
823
				print $taskstatic->label;
824
				//print "<br>";
825
				//for ($k = 0 ; $k < $level ; $k++) print "&nbsp;&nbsp;&nbsp;";
826
				//print get_date_range($lines[$i]->date_start,$lines[$i]->date_end,'',$langs,0);
827
				print "</td>\n";
828
829
				// Date
830
				print '<td class="center">';
831
				print dol_print_date($lines[$i]->timespent_datehour, 'day');
832
				print '</td>';
833
834
				$disabledproject=1;$disabledtask=1;
835
				//print "x".$lines[$i]->fk_project;
836
				//var_dump($lines[$i]);
837
				//var_dump($projectsrole[$lines[$i]->fk_project]);
838
				// If at least one role for project
839
				if ($lines[$i]->public || ! empty($projectsrole[$lines[$i]->fk_project]) || $user->rights->projet->all->creer)
840
				{
841
					$disabledproject=0;
842
					$disabledtask=0;
843
				}
844
				// If $restricteditformytask is on and I have no role on task, i disable edit
845
				if ($restricteditformytask && empty($tasksrole[$lines[$i]->id]))
846
				{
847
					$disabledtask=1;
848
				}
849
850
				// Hour
851
				print '<td class="nowrap center">';
852
				print dol_print_date($lines[$i]->timespent_datehour, 'hour');
853
				print '</td>';
854
855
				$cssonholiday='';
856
				if (! $isavailable[$preselectedday]['morning'] && ! $isavailable[$preselectedday]['afternoon'])   $cssonholiday.='onholidayallday ';
857
				elseif (! $isavailable[$preselectedday]['morning'])   $cssonholiday.='onholidaymorning ';
858
				elseif (! $isavailable[$preselectedday]['afternoon']) $cssonholiday.='onholidayafternoon ';
859
860
				// Duration
861
				print '<td class="duration'.($cssonholiday?' '.$cssonholiday:'').' center">';
862
863
				$dayWorkLoad = $lines[$i]->timespent_duration;
864
				$totalforeachline[$preselectedday]+=$lines[$i]->timespent_duration;
865
866
				$alreadyspent='';
867
				if ($dayWorkLoad > 0) $alreadyspent=convertSecondToTime($lines[$i]->timespent_duration, 'allhourmin');
868
869
				print convertSecondToTime($lines[$i]->timespent_duration, 'allhourmin');
870
871
				$modeinput='hours';
872
873
				print '<script type="text/javascript">';
874
				print "jQuery(document).ready(function () {\n";
875
				print " 	jQuery('.inputhour, .inputminute').bind('keyup', function(e) { updateTotal(0, '".$modeinput."') });";
876
				print "})\n";
877
				print '</script>';
878
879
				print '</td>';
880
881
				// Note
882
				print '<td class="center">';
883
				print '<textarea name="'.$lines[$i]->id.'note" rows="'.ROWS_2.'" id="'.$lines[$i]->id.'note"'.($disabledtask?' disabled="disabled"':'').'>';
884
				print $lines[$i]->timespent_note;
885
				print '</textarea>';
886
				print '</td>';
887
888
				// Warning
889
				print '<td class="right">';
890
				/*if ((! $lines[$i]->public) && $disabledproject) print $form->textwithpicto('',$langs->trans("UserIsNotContactOfProject"));
891
				else if ($disabledtask)
892
				{
893
					$titleassigntask = $langs->trans("AssignTaskToMe");
894
					if ($fuser->id != $user->id) $titleassigntask = $langs->trans("AssignTaskToUser", '...');
895
896
					print $form->textwithpicto('',$langs->trans("TaskIsNotAssignedToUser", $titleassigntask));
897
				}*/
898
				print '</td>';
899
900
				print "</tr>\n";
901
			}
902
		//}
903
		//else
904
		//{
905
			//$level--;
906
		//}
907
	}
908
909
	return $totalforeachline;
910
}
911
912
913
/**
914
 * Output a task line into a pertime intput mode
915
 *
916
 * @param	string	   	$inc					Line number (start to 0, then increased by recursive call)
917
 * @param   string		$parent					Id of parent task to show (0 to show all)
918
 * @param	User|null	$fuser					Restrict list to user if defined
919
 * @param   Task[]		$lines					Array of lines
920
 * @param   int			$level					Level (start to 0, then increased/decrease by recursive call)
921
 * @param   string		$projectsrole			Array of roles user has on project
922
 * @param   string		$tasksrole				Array of roles user has on task
923
 * @param	string		$mine					Show only task lines I am assigned to
924
 * @param   int			$restricteditformytask	0=No restriction, 1=Enable add time only if task is assigned to me, 2=Enable add time only if tasks is assigned to me and hide others
925
 * @param	int			$preselectedday			Preselected day
926
 * @param   array       $isavailable			Array with data that say if user is available for several days for morning and afternoon
927
 * @param	int			$oldprojectforbreak		Old project id of last project break
928
 * @param	array		$arrayfields		    Array of additional column
929
 * @param	array		$extrafields		    Array of additional column
930
 * @param	array		$extralabels		    Array of additional column
931
 * @return  array								Array with time spent for $fuser for each day of week on tasks in $lines and substasks
932
 */
933
function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask, $preselectedday, &$isavailable, $oldprojectforbreak = 0, $arrayfields = array(), $extrafields = '', $extralabels = array())
934
{
935
	global $conf, $db, $user, $bc, $langs;
936
	global $form, $formother, $projectstatic, $taskstatic, $thirdpartystatic;
937
938
	$lastprojectid=0;
939
	$totalforeachday=array();
940
	$workloadforid=array();
941
	$lineswithoutlevel0=array();
942
943
	$numlines=count($lines);
944
945
	// Create a smaller array with sublevels only to be used later. This increase dramatically performances.
946
	if ($parent == 0) // Always and only if at first level
947
	{
948
		for ($i = 0 ; $i < $numlines ; $i++)
949
		{
950
			if ($lines[$i]->fk_task_parent) $lineswithoutlevel0[]=$lines[$i];
951
		}
952
	}
953
954
	if (empty($oldprojectforbreak))
955
	{
956
		$oldprojectforbreak = (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)?0:-1);	// 0 to start break , -1 no break
957
	}
958
959
	//dol_syslog('projectLinesPerDay inc='.$inc.' preselectedday='.$preselectedday.' task parent id='.$parent.' level='.$level." count(lines)=".$numlines." count(lineswithoutlevel0)=".count($lineswithoutlevel0));
960
	for ($i = 0 ; $i < $numlines ; $i++)
961
	{
962
		if ($parent == 0) $level = 0;
963
964
		if ($lines[$i]->fk_task_parent == $parent)
965
		{
966
            $obj = &$lines[$i]; // To display extrafields
967
968
			// If we want all or we have a role on task, we show it
969
			if (empty($mine) || ! empty($tasksrole[$lines[$i]->id]))
970
			{
971
				//dol_syslog("projectLinesPerWeek Found line ".$i.", a qualified task (i have role or want to show all tasks) with id=".$lines[$i]->id." project id=".$lines[$i]->fk_project);
972
973
				if ($restricteditformytask == 2 && empty($tasksrole[$lines[$i]->id]))	// we have no role on task and we request to hide such cases
974
				{
975
					continue;
976
				}
977
978
				// Break on a new project
979
				if ($parent == 0 && $lines[$i]->fk_project != $lastprojectid)
980
				{
981
					$lastprojectid=$lines[$i]->fk_project;
982
					if ($preselectedday)
983
					{
984
						$projectstatic->id = $lines[$i]->fk_project;
985
					}
986
				}
987
988
				if (empty($workloadforid[$projectstatic->id]))
989
				{
990
					if ($preselectedday)
991
					{
992
						$projectstatic->loadTimeSpent($preselectedday, 0, $fuser->id);	// Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week
993
		   				$workloadforid[$projectstatic->id]=1;
994
					}
995
				}
996
997
				$projectstatic->id=$lines[$i]->fk_project;
998
				$projectstatic->ref=$lines[$i]->projectref;
999
				$projectstatic->title=$lines[$i]->projectlabel;
1000
				$projectstatic->public=$lines[$i]->public;
1001
1002
				$taskstatic->id=$lines[$i]->id;
1003
				$taskstatic->ref=($lines[$i]->ref?$lines[$i]->ref:$lines[$i]->id);
1004
				$taskstatic->label=$lines[$i]->label;
1005
				$taskstatic->date_start=$lines[$i]->date_start;
1006
				$taskstatic->date_end=$lines[$i]->date_end;
1007
1008
				$thirdpartystatic->id=$lines[$i]->socid;
1009
				$thirdpartystatic->name=$lines[$i]->thirdparty_name;
1010
				$thirdpartystatic->email=$lines[$i]->thirdparty_email;
1011
1012
				if (empty($oldprojectforbreak) || ($oldprojectforbreak != -1 && $oldprojectforbreak != $projectstatic->id))
1013
				{
1014
                    $addcolspan=0;
1015
                    if (! empty($arrayfields['t.planned_workload']['checked'])) $addcolspan++;
1016
                    if (! empty($arrayfields['t.progress']['checked'])) $addcolspan++;
1017
                    foreach ($arrayfields as $key => $val)
1018
                    {
1019
                        if ($val['checked'] && substr($key, 0, 5) == 'efpt.') $addcolspan++;
1020
                    }
1021
1022
					print '<tr class="oddeven trforbreak">'."\n";
1023
					print '<td colspan="'.(7+$addcolspan).'">';
1024
					print $projectstatic->getNomUrl(1, '', 0, '<strong>'.$langs->transnoentitiesnoconv("YourRole").':</strong> '.$projectsrole[$lines[$i]->fk_project]);
1025
					if ($thirdpartystatic->id > 0) print ' - '.$thirdpartystatic->getNomUrl(1);
1026
					if ($projectstatic->title)
1027
					{
1028
						print ' - ';
1029
						print $projectstatic->title;
1030
					}
1031
					/*
1032
                    $colspan=5+(empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)?0:2);
1033
                    print '<table class="">';
1034
1035
                    print '<tr class="liste_titre">';
1036
1037
                    // PROJECT fields
1038
                    if (! empty($arrayfields['p.fk_opp_status']['checked'])) print_liste_field_titre($arrayfields['p.fk_opp_status']['label'], $_SERVER["PHP_SELF"], 'p.fk_opp_status', "", $param, '', $sortfield, $sortorder, 'center ');
1039
                    if (! empty($arrayfields['p.opp_amount']['checked']))    print_liste_field_titre($arrayfields['p.opp_amount']['label'], $_SERVER["PHP_SELF"], 'p.opp_amount', "", $param, '', $sortfield, $sortorder, 'right ');
1040
                    if (! empty($arrayfields['p.opp_percent']['checked']))   print_liste_field_titre($arrayfields['p.opp_percent']['label'], $_SERVER["PHP_SELF"], 'p.opp_percent', "", $param, '', $sortfield, $sortorder, 'right ');
1041
                    if (! empty($arrayfields['p.budget_amount']['checked'])) print_liste_field_titre($arrayfields['p.budget_amount']['label'], $_SERVER["PHP_SELF"], 'p.budget_amount', "", $param, '', $sortfield, $sortorder, 'right ');
1042
                    if (! empty($arrayfields['p.bill_time']['checked']))     print_liste_field_titre($arrayfields['p.bill_time']['label'], $_SERVER["PHP_SELF"], 'p.bill_time', "", $param, '', $sortfield, $sortorder, 'right ');
1043
1044
                    $extrafieldsobjectkey='projet';
1045
                    $extrafieldsobjectprefix='efp.';
1046
                    include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
1047
1048
                    print '</tr>';
1049
                    print '<tr>';
1050
1051
                    // PROJECT fields
1052
                    if (! empty($arrayfields['p.fk_opp_status']['checked']))
1053
                    {
1054
                        print '<td class="nowrap">';
1055
                        $code = dol_getIdFromCode($db, $lines[$i]->fk_opp_status, 'c_lead_status', 'rowid', 'code');
1056
                        if ($code) print $langs->trans("OppStatus".$code);
1057
                        print "</td>\n";
1058
                    }
1059
                    if (! empty($arrayfields['p.opp_amount']['checked']))
1060
                    {
1061
                        print '<td class="nowrap">';
1062
                        print price($lines[$i]->opp_amount, 0, $langs, 1, 0, -1, $conf->currency);
1063
                        print "</td>\n";
1064
                    }
1065
                    if (! empty($arrayfields['p.opp_percent']['checked']))
1066
                    {
1067
                        print '<td class="nowrap">';
1068
                        print price($lines[$i]->opp_percent, 0, $langs, 1, 0).' %';
1069
                        print "</td>\n";
1070
                    }
1071
                    if (! empty($arrayfields['p.budget_amount']['checked']))
1072
                    {
1073
                        print '<td class="nowrap">';
1074
                        print price($lines[$i]->budget_amount, 0, $langs, 1, 0, 0, $conf->currency);
1075
                        print "</td>\n";
1076
                    }
1077
                    if (! empty($arrayfields['p.bill_time']['checked']))
1078
                    {
1079
                        print '<td class="nowrap">';
1080
                        print yn($lines[$i]->bill_time);
1081
                        print "</td>\n";
1082
                    }
1083
1084
                    $extrafieldsobjectkey='projet';
1085
                    $extrafieldsobjectprefix='efp.';
1086
                    include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
1087
1088
                    print '</tr>';
1089
                    print '</table>';
1090
1091
					*/
1092
					print '</td>';
1093
					print '</tr>';
1094
				}
1095
1096
				if ($oldprojectforbreak != -1) $oldprojectforbreak = $projectstatic->id;
1097
1098
				print '<tr class="oddeven">'."\n";
1099
1100
				// User
1101
				/*
1102
				print '<td class="nowrap">';
1103
				print $fuser->getNomUrl(1, 'withproject', 'time');
1104
				print '</td>';
1105
				*/
1106
1107
				// Project
1108
				if (! empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT))
1109
				{
1110
				    print "<td>";
1111
				    if ($oldprojectforbreak == -1) print $projectstatic->getNomUrl(1, '', 0, $langs->transnoentitiesnoconv("YourRole").': '.$projectsrole[$lines[$i]->fk_project]);
1112
				    print "</td>";
1113
				}
1114
1115
				// Thirdparty
1116
				if (! empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT))
1117
				{
1118
				    print '<td class="tdoverflowmax100">';
1119
				    if ($thirdpartystatic->id > 0) print $thirdpartystatic->getNomUrl(1, 'project', 10);
1120
				    print '</td>';
1121
				}
1122
1123
				// Ref
1124
				print '<td>';
1125
				print '<!-- Task id = '.$lines[$i]->id.' -->';
1126
				for ($k = 0 ; $k < $level ; $k++) print "&nbsp;&nbsp;&nbsp;";
1127
				print $taskstatic->getNomUrl(1, 'withproject', 'time');
1128
				// Label task
1129
				print '<br>';
1130
				for ($k = 0 ; $k < $level ; $k++) print "&nbsp;&nbsp;&nbsp;";
1131
				print $taskstatic->label;
1132
				//print "<br>";
1133
				//for ($k = 0 ; $k < $level ; $k++) print "&nbsp;&nbsp;&nbsp;";
1134
				//print get_date_range($lines[$i]->date_start,$lines[$i]->date_end,'',$langs,0);
1135
				print "</td>\n";
1136
1137
                // TASK extrafields
1138
                $extrafieldsobjectkey='projet_task';
1139
                $extrafieldsobjectprefix='efpt.';
1140
                include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
1141
1142
                // Planned Workload
1143
                if (! empty($arrayfields['t.planned_workload']['checked']))
1144
                {
1145
                    print '<td class="leftborder plannedworkload right">';
1146
				    if ($lines[$i]->planned_workload) print convertSecondToTime($lines[$i]->planned_workload, 'allhourmin');
1147
				    else print '--:--';
1148
				    print '</td>';
1149
                }
1150
1151
				// Progress declared %
1152
                if (! empty($arrayfields['t.progress']['checked']))
1153
                {
1154
                    print '<td class="right">';
1155
				    print $formother->select_percent($lines[$i]->progress, $lines[$i]->id . 'progress');
1156
				    print '</td>';
1157
                }
1158
1159
				// Time spent by everybody
1160
				print '<td class="right">';
1161
				// $lines[$i]->duration is a denormalised field = summ of time spent by everybody for task. What we need is time consummed by user
1162
				if ($lines[$i]->duration)
1163
				{
1164
					print '<a href="'.DOL_URL_ROOT.'/projet/tasks/time.php?id='.$lines[$i]->id.'">';
1165
					print convertSecondToTime($lines[$i]->duration, 'allhourmin');
1166
					print '</a>';
1167
				}
1168
				else print '--:--';
1169
				print "</td>\n";
1170
1171
				// Time spent by user
1172
				print '<td class="right">';
1173
				$tmptimespent=$taskstatic->getSummaryOfTimeSpent($fuser->id);
1174
				if ($tmptimespent['total_duration']) print convertSecondToTime($tmptimespent['total_duration'], 'allhourmin');
1175
				else print '--:--';
1176
				print "</td>\n";
1177
1178
				$disabledproject=1;$disabledtask=1;
1179
				//print "x".$lines[$i]->fk_project;
1180
				//var_dump($lines[$i]);
1181
				//var_dump($projectsrole[$lines[$i]->fk_project]);
1182
				// If at least one role for project
1183
				if ($lines[$i]->public || ! empty($projectsrole[$lines[$i]->fk_project]) || $user->rights->projet->all->creer)
1184
				{
1185
					$disabledproject=0;
1186
					$disabledtask=0;
1187
				}
1188
				// If $restricteditformytask is on and I have no role on task, i disable edit
1189
				if ($restricteditformytask && empty($tasksrole[$lines[$i]->id]))
1190
				{
1191
					$disabledtask=1;
1192
				}
1193
1194
				// Form to add new time
1195
				print '<td class="nowrap leftborder center">';
1196
				$tableCell = $form->selectDate($preselectedday, $lines[$i]->id, 1, 1, 2, "addtime", 0, 0, $disabledtask);
1197
				print $tableCell;
1198
				print '</td>';
1199
1200
				$cssonholiday='';
1201
				if (! $isavailable[$preselectedday]['morning'] && ! $isavailable[$preselectedday]['afternoon'])   $cssonholiday.='onholidayallday ';
1202
				elseif (! $isavailable[$preselectedday]['morning'])   $cssonholiday.='onholidaymorning ';
1203
				elseif (! $isavailable[$preselectedday]['afternoon']) $cssonholiday.='onholidayafternoon ';
1204
1205
				global $daytoparse;
1206
				$tmparray = dol_getdate($daytoparse, true);	// detail of current day
1207
				$idw = $tmparray['wday'];
1208
1209
				global $numstartworkingday, $numendworkingday;
1210
				$cssweekend='';
1211
				if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday)	// This is a day is not inside the setup of working days, so we use a week-end css.
1212
				{
1213
					$cssweekend='weekend';
1214
				}
1215
1216
				// Duration
1217
				print '<td class="center duration'.($cssonholiday?' '.$cssonholiday:'').($cssweekend?' '.$cssweekend:'').'">';
1218
				$dayWorkLoad = $projectstatic->weekWorkLoadPerTask[$preselectedday][$lines[$i]->id];
1219
				$totalforeachday[$preselectedday]+=$dayWorkLoad;
1220
1221
				$alreadyspent='';
1222
				if ($dayWorkLoad > 0) $alreadyspent=convertSecondToTime($dayWorkLoad, 'allhourmin');
1223
1224
				$idw = 0;
1225
1226
				$tableCell='';
1227
				$tableCell.='<span class="timesheetalreadyrecorded" title="texttoreplace"><input type="text" class="center" size="2" disabled id="timespent['.$inc.']['.$idw.']" name="task['.$lines[$i]->id.']['.$idw.']" value="'.$alreadyspent.'"></span>';
1228
				$tableCell.='<span class="hideonsmartphone"> + </span>';
1229
				//$tableCell.='&nbsp;&nbsp;&nbsp;';
1230
				$tableCell.=$form->select_duration($lines[$i]->id.'duration', '', $disabledtask, 'text', 0, 1);
1231
				//$tableCell.='&nbsp;<input type="submit" class="button"'.($disabledtask?' disabled':'').' value="'.$langs->trans("Add").'">';
1232
				print $tableCell;
1233
1234
				$modeinput='hours';
1235
1236
				print '<script type="text/javascript">';
1237
				print "jQuery(document).ready(function () {\n";
1238
				print " 	jQuery('.inputhour, .inputminute').bind('keyup', function(e) { updateTotal(0, '".$modeinput."') });";
1239
				print "})\n";
1240
				print '</script>';
1241
1242
				print '</td>';
1243
1244
				// Note
1245
				print '<td class="center">';
1246
				print '<textarea name="'.$lines[$i]->id.'note" rows="'.ROWS_2.'" id="'.$lines[$i]->id.'note"'.($disabledtask?' disabled="disabled"':'').'>';
1247
				print '</textarea>';
1248
				print '</td>';
1249
1250
				// Warning
1251
				print '<td class="right">';
1252
   				if ((! $lines[$i]->public) && $disabledproject) print $form->textwithpicto('', $langs->trans("UserIsNotContactOfProject"));
1253
   				elseif ($disabledtask)
1254
   				{
1255
   					$titleassigntask = $langs->trans("AssignTaskToMe");
1256
   					if ($fuser->id != $user->id) $titleassigntask = $langs->trans("AssignTaskToUser", '...');
1257
1258
   					print $form->textwithpicto('', $langs->trans("TaskIsNotAssignedToUser", $titleassigntask));
1259
   				}
1260
				print '</td>';
1261
1262
				print "</tr>\n";
1263
			}
1264
1265
			$inc++;
1266
			$level++;
1267
			if ($lines[$i]->id > 0)
1268
			{
1269
				//var_dump('totalforeachday after taskid='.$lines[$i]->id.' and previous one on level '.$level);
1270
				//var_dump($totalforeachday);
1271
				$ret = projectLinesPerDay($inc, $lines[$i]->id, $fuser, ($parent == 0 ? $lineswithoutlevel0 : $lines), $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $preselectedday, $isavailable, $oldprojectforbreak, $arrayfields, $extrafields, $extralabels);
1272
				//var_dump('ret with parent='.$lines[$i]->id.' level='.$level);
1273
				//var_dump($ret);
1274
				foreach($ret as $key => $val)
1275
				{
1276
					$totalforeachday[$key]+=$val;
1277
				}
1278
				//var_dump('totalforeachday after taskid='.$lines[$i]->id.' and previous one on level '.$level.' + subtasks');
1279
				//var_dump($totalforeachday);
1280
			}
1281
			$level--;
1282
		}
1283
		else
1284
		{
1285
			//$level--;
1286
		}
1287
	}
1288
1289
	return $totalforeachday;
1290
}
1291
1292
1293
/**
1294
 * Output a task line into a perday intput mode
1295
 *
1296
 * @param	string	   	$inc					Line output identificator (start to 0, then increased by recursive call)
1297
 * @param	int			$firstdaytoshow			First day to show
1298
 * @param	User|null	$fuser					Restrict list to user if defined
1299
 * @param   string		$parent					Id of parent task to show (0 to show all)
1300
 * @param   Task[]		$lines					Array of lines (list of tasks but we will show only if we have a specific role on task)
1301
 * @param   int			$level					Level (start to 0, then increased/decrease by recursive call)
1302
 * @param   string		$projectsrole			Array of roles user has on project
1303
 * @param   string		$tasksrole				Array of roles user has on task
1304
 * @param	string		$mine					Show only task lines I am assigned to
1305
 * @param   int			$restricteditformytask	0=No restriction, 1=Enable add time only if task is assigned to me, 2=Enable add time only if tasks is assigned to me and hide others
1306
 * @param   array       $isavailable			Array with data that say if user is available for several days for morning and afternoon
1307
 * @param	int			$oldprojectforbreak		Old project id of last project break
1308
 * @param	array		$arrayfields		    Array of additional column
1309
 * @param	array		$extrafields		    Array of additional column
1310
 * @param	array		$extralabels		    Array of additional column
1311
 * @return  array								Array with time spent for $fuser for each day of week on tasks in $lines and substasks
1312
 */
1313
function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask, &$isavailable, $oldprojectforbreak = 0, $arrayfields = array(), $extrafields = '', $extralabels = array())
1314
{
1315
	global $conf, $db, $user, $bc, $langs;
1316
	global $form, $formother, $projectstatic, $taskstatic, $thirdpartystatic;
1317
1318
	$numlines=count($lines);
1319
1320
	$lastprojectid=0;
1321
	$workloadforid=array();
1322
	$totalforeachday=array();
1323
	$lineswithoutlevel0=array();
1324
1325
	// Create a smaller array with sublevels only to be used later. This increase dramatically performances.
1326
	if ($parent == 0) // Always and only if at first level
1327
	{
1328
		for ($i = 0 ; $i < $numlines ; $i++)
1329
		{
1330
		   if ($lines[$i]->fk_task_parent) $lineswithoutlevel0[]=$lines[$i];
1331
		}
1332
	}
1333
1334
	//dol_syslog('projectLinesPerWeek inc='.$inc.' firstdaytoshow='.$firstdaytoshow.' task parent id='.$parent.' level='.$level." count(lines)=".$numlines." count(lineswithoutlevel0)=".count($lineswithoutlevel0));
1335
1336
	if (empty($oldprojectforbreak))
1337
	{
1338
		$oldprojectforbreak = (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)?0:-1);	// 0 = start break, -1 = never break
1339
	}
1340
1341
	for ($i = 0 ; $i < $numlines ; $i++)
1342
	{
1343
		if ($parent == 0) $level = 0;
1344
1345
		if ($lines[$i]->fk_task_parent == $parent)
1346
		{
1347
            $obj = &$lines[$i]; // To display extrafields
1348
1349
			// If we want all or we have a role on task, we show it
1350
			if (empty($mine) || ! empty($tasksrole[$lines[$i]->id]))
1351
			{
1352
				//dol_syslog("projectLinesPerWeek Found line ".$i.", a qualified task (i have role or want to show all tasks) with id=".$lines[$i]->id." project id=".$lines[$i]->fk_project);
1353
1354
				if ($restricteditformytask == 2 && empty($tasksrole[$lines[$i]->id]))	// we have no role on task and we request to hide such cases
1355
				{
1356
					continue;
1357
				}
1358
1359
				// Break on a new project
1360
				if ($parent == 0 && $lines[$i]->fk_project != $lastprojectid)
1361
				{
1362
					$lastprojectid=$lines[$i]->fk_project;
1363
					$projectstatic->id = $lines[$i]->fk_project;
1364
				}
1365
1366
				//var_dump('--- '.$level.' '.$firstdaytoshow.' '.$fuser->id.' '.$projectstatic->id.' '.$workloadforid[$projectstatic->id]);
1367
				//var_dump($projectstatic->weekWorkLoadPerTask);
1368
				if (empty($workloadforid[$projectstatic->id]))
1369
				{
1370
					$projectstatic->loadTimeSpent($firstdaytoshow, 0, $fuser->id);	// Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week
1371
					$workloadforid[$projectstatic->id]=1;
1372
				}
1373
				//var_dump($projectstatic->weekWorkLoadPerTask);
1374
				//var_dump('--- '.$projectstatic->id.' '.$workloadforid[$projectstatic->id]);
1375
1376
				$projectstatic->id=$lines[$i]->fk_project;
1377
				$projectstatic->ref=$lines[$i]->projectref;
1378
				$projectstatic->title=$lines[$i]->projectlabel;
1379
				$projectstatic->public=$lines[$i]->public;
1380
				$projectstatic->thirdparty_name=$lines[$i]->thirdparty_name;
1381
1382
				$taskstatic->id=$lines[$i]->id;
1383
				$taskstatic->ref=($lines[$i]->ref?$lines[$i]->ref:$lines[$i]->id);
1384
				$taskstatic->label=$lines[$i]->label;
1385
				$taskstatic->date_start=$lines[$i]->date_start;
1386
				$taskstatic->date_end=$lines[$i]->date_end;
1387
1388
				$thirdpartystatic->id=$lines[$i]->thirdparty_id;
1389
				$thirdpartystatic->name=$lines[$i]->thirdparty_name;
1390
				$thirdpartystatic->email=$lines[$i]->thirdparty_email;
1391
1392
				if (empty($oldprojectforbreak) || ($oldprojectforbreak != -1 && $oldprojectforbreak != $projectstatic->id))
1393
				{
1394
                    $addcolspan=0;
1395
                    if (! empty($arrayfields['t.planned_workload']['checked'])) $addcolspan++;
1396
                    if (! empty($arrayfields['t.progress']['checked'])) $addcolspan++;
1397
                    foreach ($arrayfields as $key => $val)
1398
                    {
1399
                        if ($val['checked'] && substr($key, 0, 5) == 'efpt.') $addcolspan++;
1400
                    }
1401
1402
					print '<tr class="oddeven trforbreak">'."\n";
1403
					print '<td colspan="'.(11+$addcolspan).'">';
1404
					print $projectstatic->getNomUrl(1, '', 0, '<strong>'.$langs->transnoentitiesnoconv("YourRole").':</strong> '.$projectsrole[$lines[$i]->fk_project]);
1405
					if ($thirdpartystatic->id > 0) print ' - '.$thirdpartystatic->getNomUrl(1);
1406
					if ($projectstatic->title)
1407
					{
1408
						print ' - ';
1409
						print $projectstatic->title;
1410
					}
1411
1412
                    /*$colspan=5+(empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)?0:2);
1413
					print '<table class="">';
1414
1415
					print '<tr class="liste_titre">';
1416
1417
					// PROJECT fields
1418
                    if (! empty($arrayfields['p.fk_opp_status']['checked'])) print_liste_field_titre($arrayfields['p.fk_opp_status']['label'], $_SERVER["PHP_SELF"], 'p.fk_opp_status', "", $param, '', $sortfield, $sortorder, 'center ');
1419
                    if (! empty($arrayfields['p.opp_amount']['checked']))    print_liste_field_titre($arrayfields['p.opp_amount']['label'], $_SERVER["PHP_SELF"], 'p.opp_amount', "", $param, '', $sortfield, $sortorder, 'right ');
1420
                    if (! empty($arrayfields['p.opp_percent']['checked']))   print_liste_field_titre($arrayfields['p.opp_percent']['label'], $_SERVER["PHP_SELF"], 'p.opp_percent', "", $param, '', $sortfield, $sortorder, 'right ');
1421
                    if (! empty($arrayfields['p.budget_amount']['checked'])) print_liste_field_titre($arrayfields['p.budget_amount']['label'], $_SERVER["PHP_SELF"], 'p.budget_amount', "", $param, '', $sortfield, $sortorder, 'right ');
1422
                    if (! empty($arrayfields['p.bill_time']['checked']))     print_liste_field_titre($arrayfields['p.bill_time']['label'], $_SERVER["PHP_SELF"], 'p.bill_time', "", $param, '', $sortfield, $sortorder, 'right ');
1423
1424
                    $extrafieldsobjectkey='projet';
1425
                    $extrafieldsobjectprefix='efp.';
1426
                    include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
1427
1428
                    print '</tr>';
1429
                    print '<tr>';
1430
1431
                    // PROJECT fields
1432
                    if (! empty($arrayfields['p.fk_opp_status']['checked']))
1433
                    {
1434
                        print '<td class="nowrap">';
1435
                        $code = dol_getIdFromCode($db, $lines[$i]->fk_opp_status, 'c_lead_status', 'rowid', 'code');
1436
                        if ($code) print $langs->trans("OppStatus".$code);
1437
                        print "</td>\n";
1438
                    }
1439
                    if (! empty($arrayfields['p.opp_amount']['checked']))
1440
                    {
1441
                        print '<td class="nowrap">';
1442
                        print price($lines[$i]->opp_amount, 0, $langs, 1, 0, -1, $conf->currency);
1443
                        print "</td>\n";
1444
                    }
1445
                    if (! empty($arrayfields['p.opp_percent']['checked']))
1446
                    {
1447
                        print '<td class="nowrap">';
1448
                        print price($lines[$i]->opp_percent, 0, $langs, 1, 0).' %';
1449
                        print "</td>\n";
1450
                    }
1451
                    if (! empty($arrayfields['p.budget_amount']['checked']))
1452
                    {
1453
                        print '<td class="nowrap">';
1454
                        print price($lines[$i]->budget_amount, 0, $langs, 1, 0, 0, $conf->currency);
1455
                        print "</td>\n";
1456
                    }
1457
                    if (! empty($arrayfields['p.bill_time']['checked']))
1458
                    {
1459
                        print '<td class="nowrap">';
1460
                        print yn($lines[$i]->bill_time);
1461
                        print "</td>\n";
1462
                    }
1463
1464
                    $extrafieldsobjectkey='projet';
1465
                    $extrafieldsobjectprefix='efp.';
1466
                    include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
1467
1468
                    print '</tr>';
1469
                    print '</table>';
1470
					*/
1471
1472
					print '</td>';
1473
					print '</tr>';
1474
				}
1475
1476
				if ($oldprojectforbreak != -1) $oldprojectforbreak = $projectstatic->id;
1477
1478
				print '<tr class="oddeven">'."\n";
1479
1480
				// User
1481
				/*
1482
				print '<td class="nowrap">';
1483
				print $fuser->getNomUrl(1, 'withproject', 'time');
1484
				print '</td>';
1485
				*/
1486
1487
				// Project
1488
				if (! empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT))
1489
				{
1490
    				print '<td class="nowrap">';
1491
    				if ($oldprojectforbreak == -1) print $projectstatic->getNomUrl(1, '', 0, $langs->transnoentitiesnoconv("YourRole").': '.$projectsrole[$lines[$i]->fk_project]);
1492
    				print "</td>";
1493
				}
1494
1495
				// Thirdparty
1496
				if (! empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT))
1497
				{
1498
				    print '<td class="tdoverflowmax100">';
1499
				    if ($thirdpartystatic->id > 0) print $thirdpartystatic->getNomUrl(1, 'project');
1500
				    print '</td>';
1501
				}
1502
1503
				// Ref
1504
				print '<td class="nowrap">';
1505
				print '<!-- Task id = '.$lines[$i]->id.' -->';
1506
				for ($k = 0 ; $k < $level ; $k++) print "&nbsp;&nbsp;&nbsp;";
1507
				print $taskstatic->getNomUrl(1, 'withproject', 'time');
1508
				// Label task
1509
				print '<br>';
1510
				for ($k = 0 ; $k < $level ; $k++) print "&nbsp;&nbsp;&nbsp;";
1511
				//print $taskstatic->getNomUrl(0, 'withproject', 'time');
1512
				print $taskstatic->label;
1513
				//print "<br>";
1514
				//for ($k = 0 ; $k < $level ; $k++) print "&nbsp;&nbsp;&nbsp;";
1515
				//print get_date_range($lines[$i]->date_start,$lines[$i]->date_end,'',$langs,0);
1516
				print "</td>\n";
1517
1518
				// TASK extrafields
1519
                $extrafieldsobjectkey='projet_task';
1520
                $extrafieldsobjectprefix='efpt.';
1521
                include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
1522
1523
                // Planned Workload
1524
                if (! empty($arrayfields['t.planned_workload']['checked']))
1525
                {
1526
    				print '<td class="leftborder plannedworkload right">';
1527
    				if ($lines[$i]->planned_workload) print convertSecondToTime($lines[$i]->planned_workload, 'allhourmin');
1528
    				else print '--:--';
1529
    				print '</td>';
1530
                }
1531
1532
                if (! empty($arrayfields['t.progress']['checked']))
1533
                {
1534
                    // Progress declared %
1535
    				print '<td class="right">';
1536
    				print $formother->select_percent($lines[$i]->progress, $lines[$i]->id . 'progress');
1537
    				print '</td>';
1538
                }
1539
1540
				// Time spent by everybody
1541
				print '<td class="right">';
1542
				// $lines[$i]->duration is a denormalised field = summ of time spent by everybody for task. What we need is time consummed by user
1543
				if ($lines[$i]->duration)
1544
				{
1545
					print '<a href="'.DOL_URL_ROOT.'/projet/tasks/time.php?id='.$lines[$i]->id.'">';
1546
					print convertSecondToTime($lines[$i]->duration, 'allhourmin');
1547
					print '</a>';
1548
				}
1549
				else print '--:--';
1550
				print "</td>\n";
1551
1552
				// Time spent by user
1553
				print '<td class="right">';
1554
				$tmptimespent=$taskstatic->getSummaryOfTimeSpent($fuser->id);
1555
				if ($tmptimespent['total_duration']) print convertSecondToTime($tmptimespent['total_duration'], 'allhourmin');
1556
				else print '--:--';
1557
				print "</td>\n";
1558
1559
				$disabledproject=1;$disabledtask=1;
1560
				//print "x".$lines[$i]->fk_project;
1561
				//var_dump($lines[$i]);
1562
				//var_dump($projectsrole[$lines[$i]->fk_project]);
1563
				// If at least one role for project
1564
				if ($lines[$i]->public || ! empty($projectsrole[$lines[$i]->fk_project]) || $user->rights->projet->all->creer)
1565
				{
1566
					$disabledproject=0;
1567
					$disabledtask=0;
1568
				}
1569
				// If $restricteditformytask is on and I have no role on task, i disable edit
1570
				if ($restricteditformytask && empty($tasksrole[$lines[$i]->id]))
1571
				{
1572
					$disabledtask=1;
1573
				}
1574
1575
				//var_dump($projectstatic->weekWorkLoadPerTask);
1576
1577
				// Fields to show current time
1578
				$tableCell=''; $modeinput='hours';
1579
				for ($idw = 0; $idw < 7; $idw++)
1580
				{
1581
					$tmpday=dol_time_plus_duree($firstdaytoshow, $idw, 'd');
1582
1583
					$cssonholiday='';
1584
					if (! $isavailable[$tmpday]['morning'] && ! $isavailable[$tmpday]['afternoon'])   $cssonholiday.='onholidayallday ';
1585
					elseif (! $isavailable[$tmpday]['morning'])   $cssonholiday.='onholidaymorning ';
1586
					elseif (! $isavailable[$tmpday]['afternoon']) $cssonholiday.='onholidayafternoon ';
1587
1588
					$tmparray=dol_getdate($tmpday);
1589
					$dayWorkLoad = $projectstatic->weekWorkLoadPerTask[$tmpday][$lines[$i]->id];
1590
					$totalforeachday[$tmpday]+=$dayWorkLoad;
1591
1592
					$alreadyspent='';
1593
					if ($dayWorkLoad > 0) $alreadyspent=convertSecondToTime($dayWorkLoad, 'allhourmin');
1594
					$alttitle=$langs->trans("AddHereTimeSpentForDay", $tmparray['day'], $tmparray['mon']);
1595
1596
					global $numstartworkingday, $numendworkingday;
1597
					$cssweekend='';
1598
					if (($idw + 1) < $numstartworkingday || ($idw + 1) > $numendworkingday)	// This is a day is not inside the setup of working days, so we use a week-end css.
1599
					{
1600
						$cssweekend='weekend';
1601
					}
1602
1603
					$tableCell ='<td align="center" class="hide'.$idw.($cssonholiday?' '.$cssonholiday:'').($cssweekend?' '.$cssweekend:'').'">';
1604
					$placeholder='';
1605
					if ($alreadyspent)
1606
					{
1607
						$tableCell.='<span class="timesheetalreadyrecorded" title="texttoreplace"><input type="text" class="center smallpadd" size="2" disabled id="timespent['.$inc.']['.$idw.']" name="task['.$lines[$i]->id.']['.$idw.']" value="'.$alreadyspent.'"></span>';
1608
						//$placeholder=' placeholder="00:00"';
1609
					 	//$tableCell.='+';
1610
					}
1611
				  	$tableCell.='<input type="text" alt="'.($disabledtask?'':$alttitle).'" title="'.($disabledtask?'':$alttitle).'" '.($disabledtask?'disabled':$placeholder).' class="center smallpadd" size="2" id="timeadded['.$inc.']['.$idw.']" name="task['.$lines[$i]->id.']['.$idw.']" value="" cols="2"  maxlength="5"';
1612
					$tableCell.=' onkeypress="return regexEvent(this,event,\'timeChar\')"';
1613
				   	$tableCell.=' onkeyup="updateTotal('.$idw.',\''.$modeinput.'\')"';
1614
				   	$tableCell.=' onblur="regexEvent(this,event,\''.$modeinput.'\'); updateTotal('.$idw.',\''.$modeinput.'\')" />';
1615
				   	$tableCell.='</td>';
1616
					print $tableCell;
1617
				}
1618
1619
				// Warning
1620
				print '<td class="right">';
1621
   				if ((! $lines[$i]->public) && $disabledproject) print $form->textwithpicto('', $langs->trans("UserIsNotContactOfProject"));
1622
   				elseif ($disabledtask)
1623
   				{
1624
   					$titleassigntask = $langs->trans("AssignTaskToMe");
1625
   					if ($fuser->id != $user->id) $titleassigntask = $langs->trans("AssignTaskToUser", '...');
1626
1627
   					print $form->textwithpicto('', $langs->trans("TaskIsNotAssignedToUser", $titleassigntask));
1628
   				}
1629
				print '</td>';
1630
1631
				print "</tr>\n";
1632
			}
1633
1634
			// Call to show task with a lower level (task under the current task)
1635
			$inc++;
1636
			$level++;
1637
			if ($lines[$i]->id > 0)
1638
			{
1639
				//var_dump('totalforeachday after taskid='.$lines[$i]->id.' and previous one on level '.$level);
1640
				//var_dump($totalforeachday);
1641
				$ret = projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, ($parent == 0 ? $lineswithoutlevel0 : $lines), $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $isavailable, $oldprojectforbreak, $arrayfields, $extrafields, $extralabels);
1642
				//var_dump('ret with parent='.$lines[$i]->id.' level='.$level);
1643
				//var_dump($ret);
1644
				foreach($ret as $key => $val)
1645
				{
1646
					$totalforeachday[$key]+=$val;
1647
				}
1648
				//var_dump('totalforeachday after taskid='.$lines[$i]->id.' and previous one on level '.$level.' + subtasks');
1649
				//var_dump($totalforeachday);
1650
			}
1651
			$level--;
1652
		}
1653
		else
1654
		{
1655
			//$level--;
1656
		}
1657
	}
1658
1659
	return $totalforeachday;
1660
}
1661
1662
1663
/**
1664
 * Search in task lines with a particular parent if there is a task for a particular user (in taskrole)
1665
 *
1666
 * @param 	string	$inc				Counter that count number of lines legitimate to show (for return)
1667
 * @param 	int		$parent				Id of parent task to start
1668
 * @param 	array	$lines				Array of all tasks
1669
 * @param	string	$taskrole			Array of task filtered on a particular user
1670
 * @return	int							1 if there is
1671
 */
1672
function searchTaskInChild(&$inc, $parent, &$lines, &$taskrole)
1673
{
1674
	//print 'Search in line with parent id = '.$parent.'<br>';
1675
	$numlines=count($lines);
1676
	for ($i = 0 ; $i < $numlines ; $i++)
1677
	{
1678
		// Process line $lines[$i]
1679
		if ($lines[$i]->fk_parent == $parent && $lines[$i]->id != $lines[$i]->fk_parent)
1680
		{
1681
			// If task is legitimate to show, no more need to search deeper
1682
			if (isset($taskrole[$lines[$i]->id]))
1683
			{
1684
				//print 'Found a legitimate task id='.$lines[$i]->id.'<br>';
1685
				$inc++;
1686
				return $inc;
1687
			}
1688
1689
			searchTaskInChild($inc, $lines[$i]->id, $lines, $taskrole);
1690
			//print 'Found inc='.$inc.'<br>';
1691
1692
			if ($inc > 0) return $inc;
1693
		}
1694
	}
1695
1696
	return $inc;
1697
}
1698
1699
/**
1700
 * Return HTML table with list of projects and number of opened tasks
1701
 *
1702
 * @param	DoliDB	$db					Database handler
1703
 * @param	Form	$form				Object form
1704
 * @param   int		$socid				Id thirdparty
1705
 * @param   int		$projectsListId     Id of project I have permission on
1706
 * @param   int		$mytasks            Limited to task I am contact to
1707
 * @param	int		$statut				-1=No filter on statut, 0 or 1 = Filter on status
1708
 * @param	array	$listofoppstatus	List of opportunity status
1709
 * @param   array   $hiddenfields       List of info to not show ('projectlabel', 'declaredprogress', '...', )
1710
 * @return	void
1711
 */
1712
function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks = 0, $statut = -1, $listofoppstatus = array(), $hiddenfields = array())
1713
{
1714
	global $langs,$conf,$user,$bc;
1715
1716
	require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
1717
1718
	$projectstatic=new Project($db);
1719
	$thirdpartystatic=new Societe($db);
1720
1721
	$sortfield='';
1722
	$sortorder='';
1723
	$project_year_filter=0;
1724
1725
	$title=$langs->trans("Projects");
1726
	if (strcmp($statut, '') && $statut >= 0) $title=$langs->trans("Projects").' '.$langs->trans($projectstatic->statuts_long[$statut]);
1727
1728
	$arrayidtypeofcontact=array();
1729
1730
	print '<div class="div-table-responsive-no-min">';
1731
	print '<table class="noborder" width="100%">';
1732
1733
	$sql= " FROM ".MAIN_DB_PREFIX."projet as p";
1734
	if ($mytasks)
1735
	{
1736
		$sql.= ", ".MAIN_DB_PREFIX."projet_task as t";
1737
		$sql.= ", ".MAIN_DB_PREFIX."element_contact as ec";
1738
		$sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc";
1739
	}
1740
	else
1741
	{
1742
		$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t ON p.rowid = t.fk_projet";
1743
	}
1744
	$sql.= " WHERE p.entity IN (".getEntity('project').")";
1745
	$sql.= " AND p.rowid IN (".$projectsListId.")";
1746
	if ($socid) $sql.= "  AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")";
1747
	if ($mytasks)
1748
	{
1749
		$sql.= " AND p.rowid = t.fk_projet";
1750
		$sql.= " AND ec.element_id = t.rowid";
1751
		$sql.= " AND ec.fk_socpeople = ".$user->id;
1752
		$sql.= " AND ec.fk_c_type_contact = ctc.rowid";   // Replace the 2 lines with ec.fk_c_type_contact in $arrayidtypeofcontact
1753
		$sql.= " AND ctc.element = 'project_task'";
1754
	}
1755
	if ($statut >= 0)
1756
	{
1757
		$sql.= " AND p.fk_statut = ".$statut;
1758
	}
1759
	if (!empty($conf->global->PROJECT_LIMIT_YEAR_RANGE))
1760
	{
1761
		$project_year_filter = GETPOST("project_year_filter");
1762
		//Check if empty or invalid year. Wildcard ignores the sql check
1763
		if ($project_year_filter != "*")
1764
		{
1765
			if (empty($project_year_filter) || !ctype_digit($project_year_filter))
1766
			{
1767
				$project_year_filter = date("Y");
1768
			}
1769
			$sql.= " AND (p.dateo IS NULL OR p.dateo <= ".$db->idate(dol_get_last_day($project_year_filter, 12, false)).")";
1770
			$sql.= " AND (p.datee IS NULL OR p.datee >= ".$db->idate(dol_get_first_day($project_year_filter, 1, false)).")";
1771
		}
1772
	}
1773
1774
	// Get id of project we must show tasks
1775
	$arrayidofprojects=array();
1776
	$sql1 = "SELECT p.rowid as projectid";
1777
	$sql1.= $sql;
1778
	$resql = $db->query($sql1);
1779
	if ($resql)
1780
	{
1781
		$i=0;
1782
		$num = $db->num_rows($resql);
1783
		while ($i < $num)
1784
		{
1785
			$objp = $db->fetch_object($resql);
1786
			$arrayidofprojects[$objp->projectid]=$objp->projectid;
1787
			$i++;
1788
		}
1789
	}
1790
	else dol_print_error($db);
1791
	if (empty($arrayidofprojects)) $arrayidofprojects[0]=-1;
1792
1793
	// Get list of project with calculation on tasks
1794
	$sql2 = "SELECT p.rowid as projectid, p.ref, p.title, p.fk_soc, s.nom as socname, p.fk_user_creat, p.public, p.fk_statut as status, p.fk_opp_status as opp_status, p.opp_amount,";
1795
	$sql2.= " p.dateo, p.datee,";
1796
	$sql2.= " COUNT(t.rowid) as nb, SUM(t.planned_workload) as planned_workload, SUM(t.planned_workload * t.progress / 100) as declared_progess_workload";
1797
	$sql2.= " FROM ".MAIN_DB_PREFIX."projet as p";
1798
	$sql2.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = p.fk_soc";
1799
	$sql2.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t ON p.rowid = t.fk_projet";
1800
	$sql2.= " WHERE p.rowid IN (".join(',', $arrayidofprojects).")";
1801
	$sql2.= " GROUP BY p.rowid, p.ref, p.title, p.fk_soc, s.nom, p.fk_user_creat, p.public, p.fk_statut, p.fk_opp_status, p.opp_amount, p.dateo, p.datee";
1802
	$sql2.= " ORDER BY p.title, p.ref";
1803
1804
	$resql = $db->query($sql2);
1805
	if ($resql)
1806
	{
1807
	   $total_task = 0;
1808
		$total_opp_amount = 0;
1809
		$ponderated_opp_amount = 0;
1810
1811
		$num = $db->num_rows($resql);
1812
		$i = 0;
1813
1814
		print '<tr class="liste_titre">';
1815
		print_liste_field_titre($title.' <span class="badge">'.$num.'</span>', $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder);
1816
		print_liste_field_titre("ThirdParty", $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder);
1817
		if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES))
1818
		{
1819
			print_liste_field_titre("OpportunityAmount", "", "", "", "", 'align="right"', $sortfield, $sortorder);
1820
			print_liste_field_titre("OpportunityStatus", "", "", "", "", 'align="right"', $sortfield, $sortorder);
1821
		}
1822
		if (empty($conf->global->PROJECT_HIDE_TASKS))
1823
		{
1824
			print_liste_field_titre("Tasks", "", "", "", "", 'align="right"', $sortfield, $sortorder);
1825
			if (! in_array('plannedworkload', $hiddenfields))  print_liste_field_titre("PlannedWorkload", "", "", "", "", 'align="right"', $sortfield, $sortorder);
1826
			if (! in_array('declaredprogress', $hiddenfields)) print_liste_field_titre("ProgressDeclared", "", "", "", "", 'align="right"', $sortfield, $sortorder);
1827
		}
1828
		print_liste_field_titre("Status", "", "", "", "", 'align="right"', $sortfield, $sortorder);
1829
		print "</tr>\n";
1830
1831
		$total_plannedworkload=0;
1832
		$total_declaredprogressworkload=0;
1833
		while ($i < $num)
1834
		{
1835
			$objp = $db->fetch_object($resql);
1836
1837
			$projectstatic->id = $objp->projectid;
1838
			$projectstatic->user_author_id = $objp->fk_user_creat;
1839
			$projectstatic->public = $objp->public;
1840
1841
			// Check is user has read permission on project
1842
			$userAccess = $projectstatic->restrictedProjectArea($user);
1843
			if ($userAccess >= 0)
1844
			{
1845
				$projectstatic->ref=$objp->ref;
1846
				$projectstatic->statut = $objp->status;
1847
				$projectstatic->title = $objp->title;
1848
				$projectstatic->datee = $db->jdate($objp->datee);
1849
				$projectstatic->dateo = $db->jdate($objp->dateo);
1850
1851
1852
				print '<tr class="oddeven">';
1853
				print '<td>';
1854
				print $projectstatic->getNomUrl(1);
1855
				if (! in_array('projectlabel', $hiddenfields)) print '<br>'.dol_trunc($objp->title, 24);
1856
				print '</td>';
1857
				print '<td>';
1858
				if ($objp->fk_soc > 0)
1859
				{
1860
					$thirdpartystatic->id=$objp->fk_soc;
1861
					$thirdpartystatic->ref=$objp->socname;
1862
					$thirdpartystatic->name=$objp->socname;
1863
					print $thirdpartystatic->getNomUrl(1);
1864
				}
1865
				print '</td>';
1866
				if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES))
1867
				{
1868
					print '<td class="right">';
1869
					if ($objp->opp_amount) print price($objp->opp_amount, 0, '', 1, -1, -1, $conf->currency);
1870
					print '</td>';
1871
					print '<td class="right">';
1872
					$code = dol_getIdFromCode($db, $objp->opp_status, 'c_lead_status', 'rowid', 'code');
1873
					if ($code) print $langs->trans("OppStatus".$code);
1874
					print '</td>';
1875
				}
1876
				if (empty($conf->global->PROJECT_HIDE_TASKS))
1877
				{
1878
					print '<td class="right">'.$objp->nb.'</td>';
1879
1880
					$plannedworkload=$objp->planned_workload;
1881
					$total_plannedworkload+=$plannedworkload;
1882
					if (! in_array('plannedworkload', $hiddenfields))
1883
					{
1884
						print '<td class="right">'.($plannedworkload?convertSecondToTime($plannedworkload):'').'</td>';
1885
					}
1886
					if (! in_array('declaredprogress', $hiddenfields))
1887
					{
1888
						$declaredprogressworkload=$objp->declared_progess_workload;
1889
						$total_declaredprogressworkload+=$declaredprogressworkload;
1890
						print '<td class="right">';
1891
						//print $objp->planned_workload.'-'.$objp->declared_progess_workload."<br>";
1892
						print ($plannedworkload?round(100*$declaredprogressworkload/$plannedworkload, 0).'%':'');
1893
						print '</td>';
1894
					}
1895
				}
1896
1897
				print '<td class="right">'.$projectstatic->getLibStatut(3).'</td>';
1898
				print "</tr>\n";
1899
1900
				$total_task = $total_task + $objp->nb;
1901
				$total_opp_amount = $total_opp_amount + $objp->opp_amount;
1902
				$ponderated_opp_amount = $ponderated_opp_amount + price2num($listofoppstatus[$objp->opp_status] * $objp->opp_amount / 100);
1903
			}
1904
1905
			$i++;
1906
		}
1907
1908
		print '<tr class="liste_total">';
1909
		print '<td colspan="2">'.$langs->trans("Total")."</td>";
1910
		if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES))
1911
		{
1912
			print '<td class="liste_total right">'.price($total_opp_amount, 0, '', 1, -1, -1, $conf->currency).'</td>';
1913
			print '<td class="liste_total right">'.$form->textwithpicto(price($ponderated_opp_amount, 0, '', 1, -1, -1, $conf->currency), $langs->trans("OpportunityPonderatedAmountDesc"), 1).'</td>';
1914
		}
1915
		if (empty($conf->global->PROJECT_HIDE_TASKS))
1916
		{
1917
			print '<td class="liste_total right">'.$total_task.'</td>';
1918
			if (! in_array('plannedworkload', $hiddenfields))  print '<td class="liste_total right">'.($total_plannedworkload?convertSecondToTime($total_plannedworkload):'').'</td>';
1919
			if (! in_array('declaredprogress', $hiddenfields)) print '<td class="liste_total right">'.($total_plannedworkload?round(100*$total_declaredprogressworkload/$total_plannedworkload, 0).'%':'').'</td>';
1920
		}
1921
		print '<td class="liste_total"></td>';
1922
		print '</tr>';
1923
1924
		$db->free($resql);
1925
	}
1926
	else
1927
	{
1928
		dol_print_error($db);
1929
	}
1930
1931
	print "</table>";
1932
	print '</div>';
1933
1934
	if (!empty($conf->global->PROJECT_LIMIT_YEAR_RANGE))
1935
	{
1936
		//Add the year filter input
1937
		print '<form method="get" action="'.$_SERVER["PHP_SELF"].'">';
1938
		print '<table width="100%">';
1939
		print '<tr>';
1940
		print '<td>'.$langs->trans("Year").'</td>';
1941
		print '<td class="right"><input type="text" size="4" class="flat" name="project_year_filter" value="'.$project_year_filter.'"/>';
1 ignored issue
show
Bug introduced by
Are you sure $project_year_filter of type integer|string|string[] can be used in concatenation? ( Ignorable by Annotation )

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

1941
		print '<td class="right"><input type="text" size="4" class="flat" name="project_year_filter" value="'./** @scrutinizer ignore-type */ $project_year_filter.'"/>';
Loading history...
1942
		print "</tr>\n";
1943
		print '</table></form>';
1944
	}
1945
}
1946