Passed
Branch develop (a7390e)
by
unknown
25:38
created

project_prepare_head()   F

Complexity

Conditions 25
Paths 5616

Size

Total Lines 118
Code Lines 80

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 25
eloc 80
c 0
b 0
f 0
nc 5616
nop 1
dl 0
loc 118
rs 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/* 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