dolibarr  9.0.0
project.lib.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2006-2015 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2010 Regis Houssin <regis.houssin@inodbox.com>
4  * Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es>
5  * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
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 
27 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
28 
29 
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 
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 
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 
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 
350 function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$taskrole, $projectsListId='', $addordertick=0, $projectidfortotallink=0, $filterprogresscalc='')
351 {
352  global $user, $bc, $langs, $conf, $db;
353  global $projectstatic, $taskstatic;
354 
355  $lastprojectid=0;
356 
357  $projectsArrayId=explode(',',$projectsListId);
358  if ($filterprogresscalc!=='') {
359  foreach ($lines as $key=>$line) {
360  if (!empty($line->planned_workload) && !empty($line->duration)) {
361  $filterprogresscalc = str_replace(' = ', ' == ', $filterprogresscalc);
362  if (!eval($filterprogresscalc)) {
363  unset($lines[$key]);
364  }
365  }
366  }
367  $lines=array_values($lines);
368  }
369 
370  $numlines=count($lines);
371 
372  // We declare counter as global because we want to edit them into recursive call
373  global $total_projectlinesa_spent,$total_projectlinesa_planned,$total_projectlinesa_spent_if_planned;
374  if ($level == 0)
375  {
376  $total_projectlinesa_spent=0;
377  $total_projectlinesa_planned=0;
378  $total_projectlinesa_spent_if_planned=0;
379  }
380 
381  for ($i = 0 ; $i < $numlines ; $i++)
382  {
383  if ($parent == 0 && $level >= 0) $level = 0; // if $level = -1, we dont' use sublevel recursion, we show all lines
384 
385  // Process line
386  // print "i:".$i."-".$lines[$i]->fk_project.'<br>';
387 
388  if ($lines[$i]->fk_parent == $parent || $level < 0) // if $level = -1, we dont' use sublevel recursion, we show all lines
389  {
390  // Show task line.
391  $showline=1;
392  $showlineingray=0;
393 
394  // If there is filters to use
395  if (is_array($taskrole))
396  {
397  // If task not legitimate to show, search if a legitimate task exists later in tree
398  if (! isset($taskrole[$lines[$i]->id]) && $lines[$i]->id != $lines[$i]->fk_parent)
399  {
400  // So search if task has a subtask legitimate to show
401  $foundtaskforuserdeeper=0;
402  searchTaskInChild($foundtaskforuserdeeper,$lines[$i]->id,$lines,$taskrole);
403  //print '$foundtaskforuserpeeper='.$foundtaskforuserdeeper.'<br>';
404  if ($foundtaskforuserdeeper > 0)
405  {
406  $showlineingray=1; // We will show line but in gray
407  }
408  else
409  {
410  $showline=0; // No reason to show line
411  }
412  }
413  }
414  else
415  {
416  // 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
417  // or into all other projects if user has permission to).
418  if (empty($user->rights->projet->all->lire))
419  {
420  // User is not allowed on this project and project is not public, so we hide line
421  if (! in_array($lines[$i]->fk_project, $projectsArrayId))
422  {
423  // Note that having a user assigned to a task into a project user has no permission on, should not be possible
424  // because assignement on task can be done only on contact of project.
425  // If assignement was done and after, was removed from contact of project, then we can hide the line.
426  $showline=0;
427  }
428  }
429  }
430 
431  if ($showline)
432  {
433  // Break on a new project
434  if ($parent == 0 && $lines[$i]->fk_project != $lastprojectid)
435  {
436  $var = !$var;
437  $lastprojectid=$lines[$i]->fk_project;
438  }
439 
440  print '<tr '.$bc[$var].' id="row-'.$lines[$i]->id.'">'."\n";
441 
442  if ($showproject)
443  {
444  // Project ref
445  print "<td>";
446  //if ($showlineingray) print '<i>';
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  if ($lines[$i]->public || in_array($lines[$i]->fk_project,$projectsArrayId) || ! empty($user->rights->projet->all->lire)) print $projectstatic->getNomUrl(1);
452  else print $projectstatic->getNomUrl(1,'nolink');
453  //if ($showlineingray) print '</i>';
454  print "</td>";
455 
456  // Project status
457  print '<td>';
458  $projectstatic->statut=$lines[$i]->projectstatus;
459  print $projectstatic->getLibStatut(2);
460  print "</td>";
461  }
462 
463  // Ref of task
464  print '<td>';
465  if ($showlineingray)
466  {
467  print '<i>'.img_object('','projecttask').' '.$lines[$i]->ref.'</i>';
468  }
469  else
470  {
471  $taskstatic->id=$lines[$i]->id;
472  $taskstatic->ref=$lines[$i]->ref;
473  $taskstatic->label=($taskrole[$lines[$i]->id]?$langs->trans("YourRole").': '.$taskrole[$lines[$i]->id]:'');
474  print $taskstatic->getNomUrl(1,'withproject');
475  }
476  print '</td>';
477 
478  // Title of task
479  print "<td>";
480  if ($showlineingray) print '<i>';
481  //else print '<a href="'.DOL_URL_ROOT.'/projet/tasks/task.php?id='.$lines[$i]->id.'&withproject=1">';
482  for ($k = 0 ; $k < $level ; $k++)
483  {
484  print "&nbsp; &nbsp; &nbsp;";
485  }
486  print $lines[$i]->label;
487  if ($showlineingray) print '</i>';
488  //else print '</a>';
489  print "</td>\n";
490 
491  // Date start
492  print '<td align="center">';
493  print dol_print_date($lines[$i]->date_start,'dayhour');
494  print '</td>';
495 
496  // Date end
497  print '<td align="center">';
498  $taskstatic->projectstatus = $lines[$i]->projectstatus;
499  $taskstatic->progress = $lines[$i]->progress;
500  $taskstatic->fk_statut = $lines[$i]->status;
501  $taskstatic->datee = $lines[$i]->date_end;
502  print dol_print_date($lines[$i]->date_end,'dayhour');
503  if ($taskstatic->hasDelay()) print img_warning($langs->trans("Late"));
504  print '</td>';
505 
506  $plannedworkloadoutputformat='allhourmin';
507  $timespentoutputformat='allhourmin';
508  if (! empty($conf->global->PROJECT_PLANNED_WORKLOAD_FORMAT)) $plannedworkloadoutputformat=$conf->global->PROJECT_PLANNED_WORKLOAD_FORMAT;
509  if (! empty($conf->global->PROJECT_TIMES_SPENT_FORMAT)) $timespentoutputformat=$conf->global->PROJECT_TIME_SPENT_FORMAT;
510 
511  // Planned Workload (in working hours)
512  print '<td align="right">';
513  $fullhour=convertSecondToTime($lines[$i]->planned_workload,$plannedworkloadoutputformat);
514  $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
515  if ($lines[$i]->planned_workload != '')
516  {
517  print $fullhour;
518  // TODO Add delay taking account of working hours per day and working day per week
519  //if ($workingdelay != $fullhour) print '<br>('.$workingdelay.')';
520  }
521  //else print '--:--';
522  print '</td>';
523 
524  // Time spent
525  print '<td align="right">';
526  if ($showlineingray) print '<i>';
527  else print '<a href="'.DOL_URL_ROOT.'/projet/tasks/time.php?id='.$lines[$i]->id.($showproject?'':'&withproject=1').'">';
528  if ($lines[$i]->duration) print convertSecondToTime($lines[$i]->duration,$timespentoutputformat);
529  else print '--:--';
530  if ($showlineingray) print '</i>';
531  else print '</a>';
532  print '</td>';
533 
534  // Progress calculated (Note: ->duration is time spent)
535  print '<td align="right">';
536  if ($lines[$i]->planned_workload || $lines[$i]->duration)
537  {
538  if ($lines[$i]->planned_workload) print round(100 * $lines[$i]->duration / $lines[$i]->planned_workload,2).' %';
539  else print '<span class="opacitymedium">'.$langs->trans('WorkloadNotDefined').'</span>';
540  }
541  print '</td>';
542 
543  // Progress declared
544  print '<td align="right">';
545  if ($lines[$i]->progress != '')
546  {
547  print $lines[$i]->progress.' %';
548  }
549  print '</td>';
550 
551  // Contacts of task
552  if (! empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST))
553  {
554  print '<td>';
555  foreach(array('internal','external') as $source)
556  {
557  $tab = $lines[$i]->liste_contact(-1,$source);
558  $num=count($tab);
559  if (!empty($num)){
560  foreach ($tab as $contacttask){
561  //var_dump($contacttask);
562  if ($source == 'internal') $c = new User($db);
563  else $c = new Contact($db);
564  $c->fetch($contacttask['id']);
565  print $c->getNomUrl(1) . ' (' . $contacttask['libelle'] . ')' . '<br>';
566  }
567  }
568  }
569  print '</td>';
570  }
571 
572  // Tick to drag and drop
573  if ($addordertick)
574  {
575  print '<td align="center" class="tdlineupdown hideonsmartphone">&nbsp;</td>';
576  }
577 
578  print "</tr>\n";
579 
580  if (! $showlineingray) $inc++;
581 
582  if ($level >= 0) // Call sublevels
583  {
584  $level++;
585  if ($lines[$i]->id) projectLinesa($inc, $lines[$i]->id, $lines, $level, $var, $showproject, $taskrole, $projectsListId, $addordertick);
586  $level--;
587  }
588 
589  $total_projectlinesa_spent += $lines[$i]->duration;
590  $total_projectlinesa_planned += $lines[$i]->planned_workload;
591  if ($lines[$i]->planned_workload) $total_projectlinesa_spent_if_planned += $lines[$i]->duration;
592  }
593  }
594  else
595  {
596  //$level--;
597  }
598  }
599 
600  if (($total_projectlinesa_planned > 0 || $total_projectlinesa_spent > 0) && $level <= 0)
601  {
602  print '<tr class="liste_total nodrag nodrop">';
603  print '<td class="liste_total">'.$langs->trans("Total").'</td>';
604  if ($showproject) print '<td></td><td></td>';
605  print '<td></td>';
606  print '<td></td>';
607  print '<td></td>';
608  print '<td align="right" class="nowrap liste_total">';
609  print convertSecondToTime($total_projectlinesa_planned, 'allhourmin');
610  print '</td>';
611  print '<td align="right" class="nowrap liste_total">';
612  if ($projectidfortotallink > 0) print '<a href="'.DOL_URL_ROOT.'/projet/tasks/time.php?projectid='.$projectidfortotallink.($showproject?'':'&withproject=1').'">';
613  print convertSecondToTime($total_projectlinesa_spent, 'allhourmin');
614  if ($projectidfortotallink > 0) print '</a>';
615  print '</td>';
616  print '<td align="right" class="nowrap liste_total">';
617  if ($total_projectlinesa_planned) print round(100 * $total_projectlinesa_spent / $total_projectlinesa_planned,2).' %';
618  print '</td>';
619  print '<td></td>';
620  // Contacts of task
621  if (! empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST))
622  {
623  print '<td></td>';
624  }
625  if ($addordertick) print '<td class="hideonsmartphone"></td>';
626  print '</tr>';
627  }
628 
629  return $inc;
630 }
631 
632 
650 function projectLinesPerAction(&$inc, $parent, $fuser, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask, $preselectedday, &$isavailable, $oldprojectforbreak=0)
651 {
652  global $conf, $db, $user, $bc, $langs;
653  global $form, $formother, $projectstatic, $taskstatic, $thirdpartystatic;
654 
655  $lastprojectid=0;
656  $totalforeachline=array();
657  $workloadforid=array();
658  $lineswithoutlevel0=array();
659 
660  $numlines=count($lines);
661 
662  // Create a smaller array with sublevels only to be used later. This increase dramatically performances.
663  if ($parent == 0) // Always and only if at first level
664  {
665  for ($i = 0 ; $i < $numlines ; $i++)
666  {
667  if ($lines[$i]->fk_task_parent) $lineswithoutlevel0[]=$lines[$i];
668  }
669  }
670 
671  if (empty($oldprojectforbreak))
672  {
673  $oldprojectforbreak = (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)?0:-1); // 0 to start break , -1 no break
674  }
675 
676  //dol_syslog('projectLinesPerDay inc='.$inc.' preselectedday='.$preselectedday.' task parent id='.$parent.' level='.$level." count(lines)=".$numlines." count(lineswithoutlevel0)=".count($lineswithoutlevel0));
677  for ($i = 0 ; $i < $numlines ; $i++)
678  {
679  if ($parent == 0) $level = 0;
680 
681  //if ($lines[$i]->fk_task_parent == $parent)
682  //{
683  // If we want all or we have a role on task, we show it
684  if (empty($mine) || ! empty($tasksrole[$lines[$i]->id]))
685  {
686  //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);
687 
688  // Break on a new project
689  if ($parent == 0 && $lines[$i]->fk_project != $lastprojectid)
690  {
691  $lastprojectid=$lines[$i]->fk_project;
692  if ($preselectedday)
693  {
694  $projectstatic->id = $lines[$i]->fk_project;
695  }
696  }
697 
698  if (empty($workloadforid[$projectstatic->id]))
699  {
700  if ($preselectedday)
701  {
702  $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
703  $workloadforid[$projectstatic->id]=1;
704  }
705  }
706 
707  $projectstatic->id=$lines[$i]->fk_project;
708  $projectstatic->ref=$lines[$i]->project_ref;
709  $projectstatic->title=$lines[$i]->project_label;
710  $projectstatic->public=$lines[$i]->public;
711 
712  $taskstatic->id=$lines[$i]->task_id;
713  $taskstatic->ref=($lines[$i]->task_ref?$lines[$i]->task_ref:$lines[$i]->task_id);
714  $taskstatic->label=$lines[$i]->task_label;
715  $taskstatic->date_start=$lines[$i]->date_start;
716  $taskstatic->date_end=$lines[$i]->date_end;
717 
718  $thirdpartystatic->id=$lines[$i]->socid;
719  $thirdpartystatic->name=$lines[$i]->thirdparty_name;
720  $thirdpartystatic->email=$lines[$i]->thirdparty_email;
721 
722  if (empty($oldprojectforbreak) || ($oldprojectforbreak != -1 && $oldprojectforbreak != $projectstatic->id))
723  {
724  print '<tr class="oddeven trforbreak">'."\n";
725  print '<td colspan="11">';
726  print $projectstatic->getNomUrl(1,'',0,$langs->transnoentitiesnoconv("YourRole").': '.$projectsrole[$lines[$i]->fk_project]);
727  if ($projectstatic->title)
728  {
729  print ' - ';
730  print $projectstatic->title;
731  }
732  print '</td>';
733  print '</tr>';
734  }
735 
736  if ($oldprojectforbreak != -1) $oldprojectforbreak = $projectstatic->id;
737 
738  print '<tr class="oddeven">'."\n";
739 
740  // User
741  /*
742  print '<td class="nowrap">';
743  print $fuser->getNomUrl(1, 'withproject', 'time');
744  print '</td>';
745  */
746 
747  // Project
748  print "<td>";
749  if ($oldprojectforbreak == -1)
750  {
751  print $projectstatic->getNomUrl(1,'',0,$langs->transnoentitiesnoconv("YourRole").': '.$projectsrole[$lines[$i]->fk_project]);
752  print '<br>'.$projectstatic->title;
753  }
754  print "</td>";
755 
756  // Thirdparty
757  print '<td class="tdoverflowmax100">';
758  if ($thirdpartystatic->id > 0) print $thirdpartystatic->getNomUrl(1, 'project', 10);
759  print '</td>';
760 
761  // Ref
762  print '<td>';
763  print '<!-- Task id = '.$lines[$i]->id.' -->';
764  for ($k = 0 ; $k < $level ; $k++) print "&nbsp;&nbsp;&nbsp;";
765  print $taskstatic->getNomUrl(1, 'withproject', 'time');
766  // Label task
767  print '<br>';
768  for ($k = 0 ; $k < $level ; $k++) print "&nbsp;&nbsp;&nbsp;";
769  print $taskstatic->label;
770  //print "<br>";
771  //for ($k = 0 ; $k < $level ; $k++) print "&nbsp;&nbsp;&nbsp;";
772  //print get_date_range($lines[$i]->date_start,$lines[$i]->date_end,'',$langs,0);
773  print "</td>\n";
774 
775  // Date
776  print '<td align="center">';
777  print dol_print_date($lines[$i]->timespent_datehour,'day');
778  print '</td>';
779 
780  $disabledproject=1;$disabledtask=1;
781  //print "x".$lines[$i]->fk_project;
782  //var_dump($lines[$i]);
783  //var_dump($projectsrole[$lines[$i]->fk_project]);
784  // If at least one role for project
785  if ($lines[$i]->public || ! empty($projectsrole[$lines[$i]->fk_project]) || $user->rights->projet->all->creer)
786  {
787  $disabledproject=0;
788  $disabledtask=0;
789  }
790  // If $restricteditformytask is on and I have no role on task, i disable edit
791  if ($restricteditformytask && empty($tasksrole[$lines[$i]->id]))
792  {
793  $disabledtask=1;
794  }
795 
796  // Hour
797  print '<td class="nowrap" align="center">';
798  print dol_print_date($lines[$i]->timespent_datehour,'hour');
799  print '</td>';
800 
801  $cssonholiday='';
802  if (! $isavailable[$preselectedday]['morning'] && ! $isavailable[$preselectedday]['afternoon']) $cssonholiday.='onholidayallday ';
803  elseif (! $isavailable[$preselectedday]['morning']) $cssonholiday.='onholidaymorning ';
804  elseif (! $isavailable[$preselectedday]['afternoon']) $cssonholiday.='onholidayafternoon ';
805 
806  // Duration
807  print '<td align="center" class="duration'.($cssonholiday?' '.$cssonholiday:'').'">';
808 
809  $dayWorkLoad = $lines[$i]->timespent_duration;
810  $totalforeachline[$preselectedday]+=$lines[$i]->timespent_duration;
811 
812  $alreadyspent='';
813  if ($dayWorkLoad > 0) $alreadyspent=convertSecondToTime($lines[$i]->timespent_duration,'allhourmin');
814 
815  print convertSecondToTime($lines[$i]->timespent_duration,'allhourmin');
816 
817  $modeinput='hours';
818 
819  print '<script type="text/javascript">';
820  print "jQuery(document).ready(function () {\n";
821  print " jQuery('.inputhour, .inputminute').bind('keyup', function(e) { updateTotal(0, '".$modeinput."') });";
822  print "})\n";
823  print '</script>';
824 
825  print '</td>';
826 
827  // Note
828  print '<td align="center">';
829  print '<textarea name="'.$lines[$i]->id.'note" rows="'.ROWS_2.'" id="'.$lines[$i]->id.'note"'.($disabledtask?' disabled="disabled"':'').'>';
830  print $lines[$i]->timespent_note;
831  print '</textarea>';
832  print '</td>';
833 
834  // Warning
835  print '<td align="right">';
836  /*if ((! $lines[$i]->public) && $disabledproject) print $form->textwithpicto('',$langs->trans("UserIsNotContactOfProject"));
837  else if ($disabledtask)
838  {
839  $titleassigntask = $langs->trans("AssignTaskToMe");
840  if ($fuser->id != $user->id) $titleassigntask = $langs->trans("AssignTaskToUser", '...');
841 
842  print $form->textwithpicto('',$langs->trans("TaskIsNotAssignedToUser", $titleassigntask));
843  }*/
844  print '</td>';
845 
846  print "</tr>\n";
847  }
848  //}
849  //else
850  //{
851  //$level--;
852  //}
853  }
854 
855  return $totalforeachline;
856 }
857 
858 
876 function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask, $preselectedday, &$isavailable, $oldprojectforbreak=0)
877 {
878  global $conf, $db, $user, $bc, $langs;
879  global $form, $formother, $projectstatic, $taskstatic, $thirdpartystatic;
880 
881  $lastprojectid=0;
882  $totalforeachday=array();
883  $workloadforid=array();
884  $lineswithoutlevel0=array();
885 
886  $numlines=count($lines);
887 
888  // Create a smaller array with sublevels only to be used later. This increase dramatically performances.
889  if ($parent == 0) // Always and only if at first level
890  {
891  for ($i = 0 ; $i < $numlines ; $i++)
892  {
893  if ($lines[$i]->fk_task_parent) $lineswithoutlevel0[]=$lines[$i];
894  }
895  }
896 
897  if (empty($oldprojectforbreak))
898  {
899  $oldprojectforbreak = (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)?0:-1); // 0 to start break , -1 no break
900  }
901 
902  //dol_syslog('projectLinesPerDay inc='.$inc.' preselectedday='.$preselectedday.' task parent id='.$parent.' level='.$level." count(lines)=".$numlines." count(lineswithoutlevel0)=".count($lineswithoutlevel0));
903  for ($i = 0 ; $i < $numlines ; $i++)
904  {
905  if ($parent == 0) $level = 0;
906 
907  if ($lines[$i]->fk_task_parent == $parent)
908  {
909  // If we want all or we have a role on task, we show it
910  if (empty($mine) || ! empty($tasksrole[$lines[$i]->id]))
911  {
912  //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);
913 
914  if ($restricteditformytask == 2 && empty($tasksrole[$lines[$i]->id])) // we have no role on task and we request to hide such cases
915  {
916  continue;
917  }
918 
919  // Break on a new project
920  if ($parent == 0 && $lines[$i]->fk_project != $lastprojectid)
921  {
922  $lastprojectid=$lines[$i]->fk_project;
923  if ($preselectedday)
924  {
925  $projectstatic->id = $lines[$i]->fk_project;
926  }
927  }
928 
929  if (empty($workloadforid[$projectstatic->id]))
930  {
931  if ($preselectedday)
932  {
933  $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
934  $workloadforid[$projectstatic->id]=1;
935  }
936  }
937 
938  $projectstatic->id=$lines[$i]->fk_project;
939  $projectstatic->ref=$lines[$i]->projectref;
940  $projectstatic->title=$lines[$i]->projectlabel;
941  $projectstatic->public=$lines[$i]->public;
942 
943  $taskstatic->id=$lines[$i]->id;
944  $taskstatic->ref=($lines[$i]->ref?$lines[$i]->ref:$lines[$i]->id);
945  $taskstatic->label=$lines[$i]->label;
946  $taskstatic->date_start=$lines[$i]->date_start;
947  $taskstatic->date_end=$lines[$i]->date_end;
948 
949  $thirdpartystatic->id=$lines[$i]->socid;
950  $thirdpartystatic->name=$lines[$i]->thirdparty_name;
951  $thirdpartystatic->email=$lines[$i]->thirdparty_email;
952 
953  if (empty($oldprojectforbreak) || ($oldprojectforbreak != -1 && $oldprojectforbreak != $projectstatic->id))
954  {
955  print '<tr class="oddeven trforbreak">'."\n";
956  print '<td colspan="9">';
957  print $projectstatic->getNomUrl(1,'',0,'<strong>'.$langs->transnoentitiesnoconv("YourRole").':</strong> '.$projectsrole[$lines[$i]->fk_project]);
958  if ($thirdpartystatic->id > 0) print ' - '.$thirdpartystatic->getNomUrl(1);
959  if ($projectstatic->title)
960  {
961  print ' - ';
962  print $projectstatic->title;
963  }
964  print '</td>';
965  print '</tr>';
966  }
967 
968  if ($oldprojectforbreak != -1) $oldprojectforbreak = $projectstatic->id;
969 
970  print '<tr class="oddeven">'."\n";
971 
972  // User
973  /*
974  print '<td class="nowrap">';
975  print $fuser->getNomUrl(1, 'withproject', 'time');
976  print '</td>';
977  */
978 
979  // Project
980  /*print "<td>";
981  if ($oldprojectforbreak == -1) print $projectstatic->getNomUrl(1,'',0,$langs->transnoentitiesnoconv("YourRole").': '.$projectsrole[$lines[$i]->fk_project]);
982  print "</td>";*/
983 
984  // Thirdparty
985  /*print '<td class="tdoverflowmax100">';
986  if ($thirdpartystatic->id > 0) print $thirdpartystatic->getNomUrl(1, 'project', 10);
987  print '</td>';*/
988 
989  // Ref
990  print '<td>';
991  print '<!-- Task id = '.$lines[$i]->id.' -->';
992  for ($k = 0 ; $k < $level ; $k++) print "&nbsp;&nbsp;&nbsp;";
993  print $taskstatic->getNomUrl(1, 'withproject', 'time');
994  // Label task
995  print '<br>';
996  for ($k = 0 ; $k < $level ; $k++) print "&nbsp;&nbsp;&nbsp;";
997  print $taskstatic->label;
998  //print "<br>";
999  //for ($k = 0 ; $k < $level ; $k++) print "&nbsp;&nbsp;&nbsp;";
1000  //print get_date_range($lines[$i]->date_start,$lines[$i]->date_end,'',$langs,0);
1001  print "</td>\n";
1002 
1003  // Planned Workload
1004  print '<td align="right" class="leftborder plannedworkload">';
1005  if ($lines[$i]->planned_workload) print convertSecondToTime($lines[$i]->planned_workload,'allhourmin');
1006  else print '--:--';
1007  print '</td>';
1008 
1009  // Progress declared %
1010  print '<td align="right">';
1011  print $formother->select_percent($lines[$i]->progress, $lines[$i]->id . 'progress');
1012  print '</td>';
1013 
1014  // Time spent by everybody
1015  print '<td align="right">';
1016  // $lines[$i]->duration is a denormalised field = summ of time spent by everybody for task. What we need is time consummed by user
1017  if ($lines[$i]->duration)
1018  {
1019  print '<a href="'.DOL_URL_ROOT.'/projet/tasks/time.php?id='.$lines[$i]->id.'">';
1020  print convertSecondToTime($lines[$i]->duration,'allhourmin');
1021  print '</a>';
1022  }
1023  else print '--:--';
1024  print "</td>\n";
1025 
1026  // Time spent by user
1027  print '<td align="right">';
1028  $tmptimespent=$taskstatic->getSummaryOfTimeSpent($fuser->id);
1029  if ($tmptimespent['total_duration']) print convertSecondToTime($tmptimespent['total_duration'],'allhourmin');
1030  else print '--:--';
1031  print "</td>\n";
1032 
1033  $disabledproject=1;$disabledtask=1;
1034  //print "x".$lines[$i]->fk_project;
1035  //var_dump($lines[$i]);
1036  //var_dump($projectsrole[$lines[$i]->fk_project]);
1037  // If at least one role for project
1038  if ($lines[$i]->public || ! empty($projectsrole[$lines[$i]->fk_project]) || $user->rights->projet->all->creer)
1039  {
1040  $disabledproject=0;
1041  $disabledtask=0;
1042  }
1043  // If $restricteditformytask is on and I have no role on task, i disable edit
1044  if ($restricteditformytask && empty($tasksrole[$lines[$i]->id]))
1045  {
1046  $disabledtask=1;
1047  }
1048 
1049  // Form to add new time
1050  print '<td class="nowrap leftborder" align="center">';
1051  $tableCell = $form->selectDate($preselectedday, $lines[$i]->id, 1, 1, 2, "addtime", 0, 0, $disabledtask);
1052  print $tableCell;
1053  print '</td>';
1054 
1055  $cssonholiday='';
1056  if (! $isavailable[$preselectedday]['morning'] && ! $isavailable[$preselectedday]['afternoon']) $cssonholiday.='onholidayallday ';
1057  elseif (! $isavailable[$preselectedday]['morning']) $cssonholiday.='onholidaymorning ';
1058  elseif (! $isavailable[$preselectedday]['afternoon']) $cssonholiday.='onholidayafternoon ';
1059 
1060  global $daytoparse;
1061  $tmparray = dol_getdate($daytoparse,true); // detail of current day
1062  $idw = $tmparray['wday'];
1063 
1064  global $numstartworkingday, $numendworkingday;
1065  $cssweekend='';
1066  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.
1067  {
1068  $cssweekend='weekend';
1069  }
1070 
1071  // Duration
1072  print '<td class="center duration'.($cssonholiday?' '.$cssonholiday:'').($cssweekend?' '.$cssweekend:'').'">';
1073  $dayWorkLoad = $projectstatic->weekWorkLoadPerTask[$preselectedday][$lines[$i]->id];
1074  $totalforeachday[$preselectedday]+=$dayWorkLoad;
1075 
1076  $alreadyspent='';
1077  if ($dayWorkLoad > 0) $alreadyspent=convertSecondToTime($dayWorkLoad,'allhourmin');
1078 
1079  $idw = 0;
1080 
1081  $tableCell='';
1082  $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>';
1083  $tableCell.='<span class="hideonsmartphone"> + </span>';
1084  //$tableCell.='&nbsp;&nbsp;&nbsp;';
1085  $tableCell.=$form->select_duration($lines[$i]->id.'duration','',$disabledtask,'text',0,1);
1086  //$tableCell.='&nbsp;<input type="submit" class="button"'.($disabledtask?' disabled':'').' value="'.$langs->trans("Add").'">';
1087  print $tableCell;
1088 
1089  $modeinput='hours';
1090 
1091  print '<script type="text/javascript">';
1092  print "jQuery(document).ready(function () {\n";
1093  print " jQuery('.inputhour, .inputminute').bind('keyup', function(e) { updateTotal(0, '".$modeinput."') });";
1094  print "})\n";
1095  print '</script>';
1096 
1097  print '</td>';
1098 
1099  // Note
1100  print '<td align="center">';
1101  print '<textarea name="'.$lines[$i]->id.'note" rows="'.ROWS_2.'" id="'.$lines[$i]->id.'note"'.($disabledtask?' disabled="disabled"':'').'>';
1102  print '</textarea>';
1103  print '</td>';
1104 
1105  // Warning
1106  print '<td align="right">';
1107  if ((! $lines[$i]->public) && $disabledproject) print $form->textwithpicto('',$langs->trans("UserIsNotContactOfProject"));
1108  else if ($disabledtask)
1109  {
1110  $titleassigntask = $langs->trans("AssignTaskToMe");
1111  if ($fuser->id != $user->id) $titleassigntask = $langs->trans("AssignTaskToUser", '...');
1112 
1113  print $form->textwithpicto('',$langs->trans("TaskIsNotAssignedToUser", $titleassigntask));
1114  }
1115  print '</td>';
1116 
1117  print "</tr>\n";
1118  }
1119 
1120  $inc++;
1121  $level++;
1122  if ($lines[$i]->id > 0)
1123  {
1124  //var_dump('totalforeachday after taskid='.$lines[$i]->id.' and previous one on level '.$level);
1125  //var_dump($totalforeachday);
1126  $ret = projectLinesPerDay($inc, $lines[$i]->id, $fuser, ($parent == 0 ? $lineswithoutlevel0 : $lines), $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $preselectedday, $isavailable, $oldprojectforbreak);
1127  //var_dump('ret with parent='.$lines[$i]->id.' level='.$level);
1128  //var_dump($ret);
1129  foreach($ret as $key => $val)
1130  {
1131  $totalforeachday[$key]+=$val;
1132  }
1133  //var_dump('totalforeachday after taskid='.$lines[$i]->id.' and previous one on level '.$level.' + subtasks');
1134  //var_dump($totalforeachday);
1135  }
1136  $level--;
1137  }
1138  else
1139  {
1140  //$level--;
1141  }
1142  }
1143 
1144  return $totalforeachday;
1145 }
1146 
1147 
1165 function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask, &$isavailable, $oldprojectforbreak=0)
1166 {
1167  global $conf, $db, $user, $bc, $langs;
1168  global $form, $formother, $projectstatic, $taskstatic, $thirdpartystatic;
1169 
1170  $numlines=count($lines);
1171 
1172  $lastprojectid=0;
1173  $workloadforid=array();
1174  $totalforeachday=array();
1175  $lineswithoutlevel0=array();
1176 
1177  // Create a smaller array with sublevels only to be used later. This increase dramatically performances.
1178  if ($parent == 0) // Always and only if at first level
1179  {
1180  for ($i = 0 ; $i < $numlines ; $i++)
1181  {
1182  if ($lines[$i]->fk_task_parent) $lineswithoutlevel0[]=$lines[$i];
1183  }
1184  }
1185 
1186  //dol_syslog('projectLinesPerWeek inc='.$inc.' firstdaytoshow='.$firstdaytoshow.' task parent id='.$parent.' level='.$level." count(lines)=".$numlines." count(lineswithoutlevel0)=".count($lineswithoutlevel0));
1187 
1188  if (empty($oldprojectforbreak))
1189  {
1190  $oldprojectforbreak = (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)?0:-1); // 0 = start break, -1 = never break
1191  }
1192 
1193  for ($i = 0 ; $i < $numlines ; $i++)
1194  {
1195  if ($parent == 0) $level = 0;
1196 
1197  if ($lines[$i]->fk_task_parent == $parent)
1198  {
1199  // If we want all or we have a role on task, we show it
1200  if (empty($mine) || ! empty($tasksrole[$lines[$i]->id]))
1201  {
1202  //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);
1203 
1204  if ($restricteditformytask == 2 && empty($tasksrole[$lines[$i]->id])) // we have no role on task and we request to hide such cases
1205  {
1206  continue;
1207  }
1208 
1209  // Break on a new project
1210  if ($parent == 0 && $lines[$i]->fk_project != $lastprojectid)
1211  {
1212  $lastprojectid=$lines[$i]->fk_project;
1213  $projectstatic->id = $lines[$i]->fk_project;
1214  }
1215 
1216  //var_dump('--- '.$level.' '.$firstdaytoshow.' '.$fuser->id.' '.$projectstatic->id.' '.$workloadforid[$projectstatic->id]);
1217  //var_dump($projectstatic->weekWorkLoadPerTask);
1218  if (empty($workloadforid[$projectstatic->id]))
1219  {
1220  $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
1221  $workloadforid[$projectstatic->id]=1;
1222  }
1223  //var_dump($projectstatic->weekWorkLoadPerTask);
1224  //var_dump('--- '.$projectstatic->id.' '.$workloadforid[$projectstatic->id]);
1225 
1226  $projectstatic->id=$lines[$i]->fk_project;
1227  $projectstatic->ref=$lines[$i]->projectref;
1228  $projectstatic->title=$lines[$i]->projectlabel;
1229  $projectstatic->public=$lines[$i]->public;
1230  $projectstatic->thirdparty_name=$lines[$i]->thirdparty_name;
1231 
1232  $taskstatic->id=$lines[$i]->id;
1233  $taskstatic->ref=($lines[$i]->ref?$lines[$i]->ref:$lines[$i]->id);
1234  $taskstatic->label=$lines[$i]->label;
1235  $taskstatic->date_start=$lines[$i]->date_start;
1236  $taskstatic->date_end=$lines[$i]->date_end;
1237 
1238  $thirdpartystatic->id=$lines[$i]->thirdparty_id;
1239  $thirdpartystatic->name=$lines[$i]->thirdparty_name;
1240  $thirdpartystatic->email=$lines[$i]->thirdparty_email;
1241 
1242  if (empty($oldprojectforbreak) || ($oldprojectforbreak != -1 && $oldprojectforbreak != $projectstatic->id))
1243  {
1244  print '<tr class="oddeven trforbreak">'."\n";
1245  print '<td colspan="13">';
1246  print $projectstatic->getNomUrl(1,'',0,'<strong>'.$langs->transnoentitiesnoconv("YourRole").':</strong> '.$projectsrole[$lines[$i]->fk_project]);
1247  if ($thirdpartystatic->id > 0) print ' - '.$thirdpartystatic->getNomUrl(1);
1248  if ($projectstatic->title)
1249  {
1250  print ' - ';
1251  print $projectstatic->title;
1252  }
1253  print '</td>';
1254  print '</tr>';
1255  }
1256 
1257  if ($oldprojectforbreak != -1) $oldprojectforbreak = $projectstatic->id;
1258 
1259  print '<tr class="oddeven">'."\n";
1260 
1261  // User
1262  /*
1263  print '<td class="nowrap">';
1264  print $fuser->getNomUrl(1, 'withproject', 'time');
1265  print '</td>';
1266  */
1267 
1268  // Project
1269  /*print '<td class="nowrap">';
1270  if ($oldprojectforbreak == -1) print $projectstatic->getNomUrl(1,'',0,$langs->transnoentitiesnoconv("YourRole").': '.$projectsrole[$lines[$i]->fk_project]);
1271  print "</td>";*/
1272 
1273  // Thirdparty
1274  /*print '<td class="tdoverflowmax100">';
1275  if ($thirdpartystatic->id > 0) print $thirdpartystatic->getNomUrl(1, 'project');
1276  print '</td>';*/
1277 
1278  // Ref
1279  print '<td class="nowrap">';
1280  print '<!-- Task id = '.$lines[$i]->id.' -->';
1281  for ($k = 0 ; $k < $level ; $k++) print "&nbsp;&nbsp;&nbsp;";
1282  print $taskstatic->getNomUrl(1, 'withproject', 'time');
1283  // Label task
1284  print '<br>';
1285  for ($k = 0 ; $k < $level ; $k++) print "&nbsp;&nbsp;&nbsp;";
1286  //print $taskstatic->getNomUrl(0, 'withproject', 'time');
1287  print $taskstatic->label;
1288  //print "<br>";
1289  //for ($k = 0 ; $k < $level ; $k++) print "&nbsp;&nbsp;&nbsp;";
1290  //print get_date_range($lines[$i]->date_start,$lines[$i]->date_end,'',$langs,0);
1291  print "</td>\n";
1292 
1293  // Planned Workload
1294  print '<td align="right" class="leftborder plannedworkload">';
1295  if ($lines[$i]->planned_workload) print convertSecondToTime($lines[$i]->planned_workload,'allhourmin');
1296  else print '--:--';
1297  print '</td>';
1298 
1299  // Progress declared %
1300  print '<td align="right">';
1301  print $formother->select_percent($lines[$i]->progress, $lines[$i]->id . 'progress');
1302  print '</td>';
1303 
1304  // Time spent by everybody
1305  print '<td align="right">';
1306  // $lines[$i]->duration is a denormalised field = summ of time spent by everybody for task. What we need is time consummed by user
1307  if ($lines[$i]->duration)
1308  {
1309  print '<a href="'.DOL_URL_ROOT.'/projet/tasks/time.php?id='.$lines[$i]->id.'">';
1310  print convertSecondToTime($lines[$i]->duration,'allhourmin');
1311  print '</a>';
1312  }
1313  else print '--:--';
1314  print "</td>\n";
1315 
1316  // Time spent by user
1317  print '<td align="right">';
1318  $tmptimespent=$taskstatic->getSummaryOfTimeSpent($fuser->id);
1319  if ($tmptimespent['total_duration']) print convertSecondToTime($tmptimespent['total_duration'],'allhourmin');
1320  else print '--:--';
1321  print "</td>\n";
1322 
1323  $disabledproject=1;$disabledtask=1;
1324  //print "x".$lines[$i]->fk_project;
1325  //var_dump($lines[$i]);
1326  //var_dump($projectsrole[$lines[$i]->fk_project]);
1327  // If at least one role for project
1328  if ($lines[$i]->public || ! empty($projectsrole[$lines[$i]->fk_project]) || $user->rights->projet->all->creer)
1329  {
1330  $disabledproject=0;
1331  $disabledtask=0;
1332  }
1333  // If $restricteditformytask is on and I have no role on task, i disable edit
1334  if ($restricteditformytask && empty($tasksrole[$lines[$i]->id]))
1335  {
1336  $disabledtask=1;
1337  }
1338 
1339  //var_dump($projectstatic->weekWorkLoadPerTask);
1340 
1341  // Fields to show current time
1342  $tableCell=''; $modeinput='hours';
1343  for ($idw = 0; $idw < 7; $idw++)
1344  {
1345  $tmpday=dol_time_plus_duree($firstdaytoshow, $idw, 'd');
1346 
1347  $cssonholiday='';
1348  if (! $isavailable[$tmpday]['morning'] && ! $isavailable[$tmpday]['afternoon']) $cssonholiday.='onholidayallday ';
1349  elseif (! $isavailable[$tmpday]['morning']) $cssonholiday.='onholidaymorning ';
1350  elseif (! $isavailable[$tmpday]['afternoon']) $cssonholiday.='onholidayafternoon ';
1351 
1352  $tmparray=dol_getdate($tmpday);
1353  $dayWorkLoad = $projectstatic->weekWorkLoadPerTask[$tmpday][$lines[$i]->id];
1354  $totalforeachday[$tmpday]+=$dayWorkLoad;
1355 
1356  $alreadyspent='';
1357  if ($dayWorkLoad > 0) $alreadyspent=convertSecondToTime($dayWorkLoad,'allhourmin');
1358  $alttitle=$langs->trans("AddHereTimeSpentForDay",$tmparray['day'],$tmparray['mon']);
1359 
1360  global $numstartworkingday, $numendworkingday;
1361  $cssweekend='';
1362  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.
1363  {
1364  $cssweekend='weekend';
1365  }
1366 
1367  $tableCell ='<td align="center" class="hide'.$idw.($cssonholiday?' '.$cssonholiday:'').($cssweekend?' '.$cssweekend:'').'">';
1368  $placeholder='';
1369  if ($alreadyspent)
1370  {
1371  $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>';
1372  //$placeholder=' placeholder="00:00"';
1373  //$tableCell.='+';
1374  }
1375  $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"';
1376  $tableCell.=' onkeypress="return regexEvent(this,event,\'timeChar\')"';
1377  $tableCell.=' onkeyup="updateTotal('.$idw.',\''.$modeinput.'\')"';
1378  $tableCell.=' onblur="regexEvent(this,event,\''.$modeinput.'\'); updateTotal('.$idw.',\''.$modeinput.'\')" />';
1379  $tableCell.='</td>';
1380  print $tableCell;
1381  }
1382 
1383  // Warning
1384  print '<td align="right">';
1385  if ((! $lines[$i]->public) && $disabledproject) print $form->textwithpicto('',$langs->trans("UserIsNotContactOfProject"));
1386  else if ($disabledtask)
1387  {
1388  $titleassigntask = $langs->trans("AssignTaskToMe");
1389  if ($fuser->id != $user->id) $titleassigntask = $langs->trans("AssignTaskToUser", '...');
1390 
1391  print $form->textwithpicto('',$langs->trans("TaskIsNotAssignedToUser", $titleassigntask));
1392  }
1393  print '</td>';
1394 
1395  print "</tr>\n";
1396  }
1397 
1398  // Call to show task with a lower level (task under the current task)
1399  $inc++;
1400  $level++;
1401  if ($lines[$i]->id > 0)
1402  {
1403  //var_dump('totalforeachday after taskid='.$lines[$i]->id.' and previous one on level '.$level);
1404  //var_dump($totalforeachday);
1405  $ret = projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, ($parent == 0 ? $lineswithoutlevel0 : $lines), $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $isavailable, $oldprojectforbreak);
1406  //var_dump('ret with parent='.$lines[$i]->id.' level='.$level);
1407  //var_dump($ret);
1408  foreach($ret as $key => $val)
1409  {
1410  $totalforeachday[$key]+=$val;
1411  }
1412  //var_dump('totalforeachday after taskid='.$lines[$i]->id.' and previous one on level '.$level.' + subtasks');
1413  //var_dump($totalforeachday);
1414  }
1415  $level--;
1416  }
1417  else
1418  {
1419  //$level--;
1420  }
1421  }
1422 
1423  return $totalforeachday;
1424 }
1425 
1426 
1436 function searchTaskInChild(&$inc, $parent, &$lines, &$taskrole)
1437 {
1438  //print 'Search in line with parent id = '.$parent.'<br>';
1439  $numlines=count($lines);
1440  for ($i = 0 ; $i < $numlines ; $i++)
1441  {
1442  // Process line $lines[$i]
1443  if ($lines[$i]->fk_parent == $parent && $lines[$i]->id != $lines[$i]->fk_parent)
1444  {
1445  // If task is legitimate to show, no more need to search deeper
1446  if (isset($taskrole[$lines[$i]->id]))
1447  {
1448  //print 'Found a legitimate task id='.$lines[$i]->id.'<br>';
1449  $inc++;
1450  return $inc;
1451  }
1452 
1453  searchTaskInChild($inc, $lines[$i]->id, $lines, $taskrole);
1454  //print 'Found inc='.$inc.'<br>';
1455 
1456  if ($inc > 0) return $inc;
1457  }
1458  }
1459 
1460  return $inc;
1461 }
1462 
1476 function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks=0, $statut=-1, $listofoppstatus=array(),$hiddenfields=array())
1477 {
1478  global $langs,$conf,$user,$bc;
1479 
1480  require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
1481 
1482  $projectstatic=new Project($db);
1483  $thirdpartystatic=new Societe($db);
1484 
1485  $sortfield='';
1486  $sortorder='';
1487  $project_year_filter=0;
1488 
1489  $title=$langs->trans("Projects");
1490  if (strcmp($statut, '') && $statut >= 0) $title=$langs->trans("Projects").' '.$langs->trans($projectstatic->statuts_long[$statut]);
1491 
1492  $arrayidtypeofcontact=array();
1493 
1494  print '<div class="div-table-responsive-no-min">';
1495  print '<table class="noborder" width="100%">';
1496 
1497  $sql= " FROM ".MAIN_DB_PREFIX."projet as p";
1498  if ($mytasks)
1499  {
1500  $sql.= ", ".MAIN_DB_PREFIX."projet_task as t";
1501  $sql.= ", ".MAIN_DB_PREFIX."element_contact as ec";
1502  $sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc";
1503  }
1504  else
1505  {
1506  $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t ON p.rowid = t.fk_projet";
1507  }
1508  $sql.= " WHERE p.entity IN (".getEntity('project').")";
1509  $sql.= " AND p.rowid IN (".$projectsListId.")";
1510  if ($socid) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")";
1511  if ($mytasks)
1512  {
1513  $sql.= " AND p.rowid = t.fk_projet";
1514  $sql.= " AND ec.element_id = t.rowid";
1515  $sql.= " AND ec.fk_socpeople = ".$user->id;
1516  $sql.= " AND ec.fk_c_type_contact = ctc.rowid"; // Replace the 2 lines with ec.fk_c_type_contact in $arrayidtypeofcontact
1517  $sql.= " AND ctc.element = 'project_task'";
1518  }
1519  if ($statut >= 0)
1520  {
1521  $sql.= " AND p.fk_statut = ".$statut;
1522  }
1523  if (!empty($conf->global->PROJECT_LIMIT_YEAR_RANGE))
1524  {
1525  $project_year_filter = GETPOST("project_year_filter");
1526  //Check if empty or invalid year. Wildcard ignores the sql check
1527  if ($project_year_filter != "*")
1528  {
1529  if (empty($project_year_filter) || !ctype_digit($project_year_filter))
1530  {
1531  $project_year_filter = date("Y");
1532  }
1533  $sql.= " AND (p.dateo IS NULL OR p.dateo <= ".$db->idate(dol_get_last_day($project_year_filter,12,false)).")";
1534  $sql.= " AND (p.datee IS NULL OR p.datee >= ".$db->idate(dol_get_first_day($project_year_filter,1,false)).")";
1535  }
1536  }
1537 
1538  // Get id of project we must show tasks
1539  $arrayidofprojects=array();
1540  $sql1 = "SELECT p.rowid as projectid";
1541  $sql1.= $sql;
1542  $resql = $db->query($sql1);
1543  if ($resql)
1544  {
1545  $i=0;
1546  $num = $db->num_rows($resql);
1547  while ($i < $num)
1548  {
1549  $objp = $db->fetch_object($resql);
1550  $arrayidofprojects[$objp->projectid]=$objp->projectid;
1551  $i++;
1552  }
1553  }
1554  else dol_print_error($db);
1555  if (empty($arrayidofprojects)) $arrayidofprojects[0]=-1;
1556 
1557  // Get list of project with calculation on tasks
1558  $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,";
1559  $sql2.= " p.dateo, p.datee,";
1560  $sql2.= " COUNT(t.rowid) as nb, SUM(t.planned_workload) as planned_workload, SUM(t.planned_workload * t.progress / 100) as declared_progess_workload";
1561  $sql2.= " FROM ".MAIN_DB_PREFIX."projet as p";
1562  $sql2.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = p.fk_soc";
1563  $sql2.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t ON p.rowid = t.fk_projet";
1564  $sql2.= " WHERE p.rowid IN (".join(',',$arrayidofprojects).")";
1565  $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";
1566  $sql2.= " ORDER BY p.title, p.ref";
1567 
1568  $resql = $db->query($sql2);
1569  if ($resql)
1570  {
1571  $total_task = 0;
1572  $total_opp_amount = 0;
1573  $ponderated_opp_amount = 0;
1574 
1575  $num = $db->num_rows($resql);
1576  $i = 0;
1577 
1578  print '<tr class="liste_titre">';
1579  print_liste_field_titre($title.' <span class="badge">'.$num.'</span>',$_SERVER["PHP_SELF"],"","","","",$sortfield,$sortorder);
1580  print_liste_field_titre("ThirdParty",$_SERVER["PHP_SELF"],"","","","",$sortfield,$sortorder);
1581  if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES))
1582  {
1583  print_liste_field_titre("OpportunityAmount","","","","",'align="right"',$sortfield,$sortorder);
1584  print_liste_field_titre("OpportunityStatus","","","","",'align="right"',$sortfield,$sortorder);
1585  }
1586  if (empty($conf->global->PROJECT_HIDE_TASKS))
1587  {
1588  print_liste_field_titre("Tasks","","","","",'align="right"',$sortfield,$sortorder);
1589  if (! in_array('plannedworkload', $hiddenfields)) print_liste_field_titre("PlannedWorkload","","","","",'align="right"',$sortfield,$sortorder);
1590  if (! in_array('declaredprogress', $hiddenfields)) print_liste_field_titre("ProgressDeclared","","","","",'align="right"',$sortfield,$sortorder);
1591  }
1592  print_liste_field_titre("Status","","","","",'align="right"',$sortfield,$sortorder);
1593  print "</tr>\n";
1594 
1595  $total_plannedworkload=0;
1596  $total_declaredprogressworkload=0;
1597  while ($i < $num)
1598  {
1599  $objp = $db->fetch_object($resql);
1600 
1601  $projectstatic->id = $objp->projectid;
1602  $projectstatic->user_author_id = $objp->fk_user_creat;
1603  $projectstatic->public = $objp->public;
1604 
1605  // Check is user has read permission on project
1606  $userAccess = $projectstatic->restrictedProjectArea($user);
1607  if ($userAccess >= 0)
1608  {
1609  $projectstatic->ref=$objp->ref;
1610  $projectstatic->statut = $objp->status;
1611  $projectstatic->title = $objp->title;
1612  $projectstatic->datee = $db->jdate($objp->datee);
1613  $projectstatic->dateo = $db->jdate($objp->dateo);
1614 
1615 
1616  print '<tr class="oddeven">';
1617  print '<td>';
1618  print $projectstatic->getNomUrl(1);
1619  if (! in_array('projectlabel', $hiddenfields)) print '<br>'.dol_trunc($objp->title,24);
1620  print '</td>';
1621  print '<td>';
1622  if ($objp->fk_soc > 0)
1623  {
1624  $thirdpartystatic->id=$objp->fk_soc;
1625  $thirdpartystatic->ref=$objp->socname;
1626  $thirdpartystatic->name=$objp->socname;
1627  print $thirdpartystatic->getNomUrl(1);
1628  }
1629  print '</td>';
1630  if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES))
1631  {
1632  print '<td align="right">';
1633  if ($objp->opp_amount) print price($objp->opp_amount, 0, '', 1, -1, -1, $conf->currency);
1634  print '</td>';
1635  print '<td align="right">';
1636  $code = dol_getIdFromCode($db, $objp->opp_status, 'c_lead_status', 'rowid', 'code');
1637  if ($code) print $langs->trans("OppStatus".$code);
1638  print '</td>';
1639  }
1640  if (empty($conf->global->PROJECT_HIDE_TASKS))
1641  {
1642  print '<td align="right">'.$objp->nb.'</td>';
1643 
1644  $plannedworkload=$objp->planned_workload;
1645  $total_plannedworkload+=$plannedworkload;
1646  if (! in_array('plannedworkload', $hiddenfields))
1647  {
1648  print '<td align="right">'.($plannedworkload?convertSecondToTime($plannedworkload):'').'</td>';
1649  }
1650  if (! in_array('declaredprogress', $hiddenfields))
1651  {
1652  $declaredprogressworkload=$objp->declared_progess_workload;
1653  $total_declaredprogressworkload+=$declaredprogressworkload;
1654  print '<td align="right">';
1655  //print $objp->planned_workload.'-'.$objp->declared_progess_workload."<br>";
1656  print ($plannedworkload?round(100*$declaredprogressworkload/$plannedworkload,0).'%':'');
1657  print '</td>';
1658  }
1659  }
1660 
1661  print '<td align="right">'.$projectstatic->getLibStatut(3).'</td>';
1662  print "</tr>\n";
1663 
1664  $total_task = $total_task + $objp->nb;
1665  $total_opp_amount = $total_opp_amount + $objp->opp_amount;
1666  $ponderated_opp_amount = $ponderated_opp_amount + price2num($listofoppstatus[$objp->opp_status] * $objp->opp_amount / 100);
1667  }
1668 
1669  $i++;
1670  }
1671 
1672  print '<tr class="liste_total">';
1673  print '<td colspan="2">'.$langs->trans("Total")."</td>";
1674  if (! empty($conf->global->PROJECT_USE_OPPORTUNITIES))
1675  {
1676  print '<td class="liste_total" align="right">'.price($total_opp_amount, 0, '', 1, -1, -1, $conf->currency).'</td>';
1677  print '<td class="liste_total" align="right">'.$form->textwithpicto(price($ponderated_opp_amount, 0, '', 1, -1, -1, $conf->currency), $langs->trans("OpportunityPonderatedAmountDesc"), 1).'</td>';
1678  }
1679  if (empty($conf->global->PROJECT_HIDE_TASKS))
1680  {
1681  print '<td class="liste_total" align="right">'.$total_task.'</td>';
1682  if (! in_array('plannedworkload', $hiddenfields)) print '<td class="liste_total" align="right">'.($total_plannedworkload?convertSecondToTime($total_plannedworkload):'').'</td>';
1683  if (! in_array('declaredprogress', $hiddenfields)) print '<td class="liste_total" align="right">'.($total_plannedworkload?round(100*$total_declaredprogressworkload/$total_plannedworkload,0).'%':'').'</td>';
1684  }
1685  print '<td class="liste_total"></td>';
1686  print '</tr>';
1687 
1688  $db->free($resql);
1689  }
1690  else
1691  {
1692  dol_print_error($db);
1693  }
1694 
1695  print "</table>";
1696  print '</div>';
1697 
1698  if (!empty($conf->global->PROJECT_LIMIT_YEAR_RANGE))
1699  {
1700  //Add the year filter input
1701  print '<form method="get" action="'.$_SERVER["PHP_SELF"].'">';
1702  print '<table width="100%">';
1703  print '<tr>';
1704  print '<td>'.$langs->trans("Year").'</td>';
1705  print '<td style="text-align:right"><input type="text" size="4" class="flat" name="project_year_filter" value="'.$project_year_filter.'"/>';
1706  print "</tr>\n";
1707  print '</table></form>';
1708  }
1709 }
convertSecondToTime($iSecond, $format='all', $lengthOfDay=86400, $lengthOfWeek=7)
Return, in clear text, value of a number of seconds in days, hours and minutes.
Definition: date.lib.php:180
img_warning($titlealt='default', $moreatt='')
Show warning logo.
print
Draft customers invoices.
Definition: index.php:91
if(! empty($conf->facture->enabled) && $user->rights->facture->lire) if(! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->lire) if(! empty($conf->don->enabled) && $user->rights->societe->lire) if(! empty($conf->tax->enabled) && $user->rights->tax->charges->lire) if(! empty($conf->facture->enabled) &&! empty($conf->commande->enabled) && $user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(! empty($conf->facture->enabled) && $user->rights->facture->lire) if(! empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1053
Class to manage contact/addresses.
complete_head_from_modules($conf, $langs, $object, &$head, &$h, $type, $mode='add')
Complete or removed entries into a head array (used to build tabs).
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$taskrole, $projectsListId='', $addordertick=0, $projectidfortotallink=0, $filterprogresscalc='')
Show task lines with a particular parent.
Class to manage Dolibarr users.
Definition: user.class.php:41
dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0)
Return an id or code from a code or id.
dol_print_error($db='', $error='', $errors=null)
Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte...
projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask, &$isavailable, $oldprojectforbreak=0)
Output a task line into a perday intput mode.
searchTaskInChild(&$inc, $parent, &$lines, &$taskrole)
Search in task lines with a particular parent if there is a task for a particular user (in taskrole) ...
if(! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'] s nom
Definition: list.php:573
projectLinesPerAction(&$inc, $parent, $fuser, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask, $preselectedday, &$isavailable, $oldprojectforbreak=0)
Output a task line into a pertime intput mode.
if(GETPOST('cancel', 'alpha')) if(! GETPOST( 'confirmmassaction', 'alpha') &&$massaction !='presend' &&$massaction !='confirm_presend')
Draft customers invoices.
Definition: list.php:156
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0)
Scan a directory and return a list of files/directories.
Definition: files.lib.php:59
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages...
dol_print_date($time, $format='', $tzoutput='tzserver', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
Class to manage tasks.
Definition: task.class.php:33
project_prepare_head($object)
Prepare array with list of tabs.
Definition: project.lib.php:36
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="")
Show title line of an array.
dol_getdate($timestamp, $fast=false)
Return an array with locale date info.
projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask, $preselectedday, &$isavailable, $oldprojectforbreak=0)
Output a task line into a pertime intput mode.
project_admin_prepare_head()
Prepare array with list of tabs.
project_timesheet_prepare_head($mode, $fuser=null)
Prepare array with list of tabs.
dol_time_plus_duree($time, $duration_value, $duration_unit)
Add a delay to a date.
Definition: date.lib.php:116
price2num($amount, $rounding='', $alreadysqlnb=0)
Function that return a number with universal decimal format (decimal separator is &#39;...
task_prepare_head($object)
Prepare array with list of tabs.