dolibarr  13.0.2
ganttview.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2017 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
26 require "../main.inc.php";
27 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
28 require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
29 require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
30 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
31 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
34 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
35 
36 $id = GETPOST('id', 'intcomma');
37 $ref = GETPOST('ref', 'alpha');
38 
39 $mode = GETPOST('mode', 'alpha');
40 $mine = ($mode == 'mine' ? 1 : 0);
41 //if (! $user->rights->projet->all->lire) $mine=1; // Special for projects
42 
43 $object = new Project($db);
44 
45 include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once
46 if (!empty($conf->global->PROJECT_ALLOW_COMMENT_ON_PROJECT) && method_exists($object, 'fetchComments') && empty($object->comments)) $object->fetchComments();
47 
48 // Security check
49 $socid = 0;
50 //if ($user->socid > 0) $socid = $user->socid; // For external user, no check is done on company because readability is managed by public status of project and assignement.
51 $result = restrictedArea($user, 'projet', $id, 'projet&project');
52 
53 // Load translation files required by the page
54 $langs->loadlangs(array('users', 'projects'));
55 
56 
57 /*
58  * Actions
59  */
60 
61 // None
62 
63 
64 /*
65  * View
66  */
67 
68 $form = new Form($db);
69 $formother = new FormOther($db);
70 $userstatic = new User($db);
71 $companystatic = new Societe($db);
72 $contactstatic = new Contact($db);
73 $task = new Task($db);
74 
75 $arrayofcss = array('/includes/jsgantt/jsgantt.css');
76 
77 if (!empty($conf->use_javascript_ajax))
78 {
79  $arrayofjs = array(
80  '/includes/jsgantt/jsgantt.js',
81  '/projet/jsgantt_language.js.php?lang='.$langs->defaultlang
82  );
83 }
84 
85 //$title=$langs->trans("Gantt").($object->ref?' - '.$object->ref.' '.$object->name:'');
86 $title = $langs->trans("Gantt");
87 if (!empty($conf->global->MAIN_HTML_TITLE) && preg_match('/projectnameonly/', $conf->global->MAIN_HTML_TITLE) && $object->name) $title = ($object->ref ? $object->ref.' '.$object->name.' - ' : '').$langs->trans("Gantt");
88 $help_url = "EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos";
89 llxHeader("", $title, $help_url, '', 0, 0, $arrayofjs, $arrayofcss);
90 
91 if (($id > 0 && is_numeric($id)) || !empty($ref))
92 {
93  // To verify role of users
94  //$userAccess = $object->restrictedProjectArea($user,'read');
95  $userWrite = $object->restrictedProjectArea($user, 'write');
96  //$userDelete = $object->restrictedProjectArea($user,'delete');
97  //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete;
98 
99  $tab = 'tasks';
100 
101  $head = project_prepare_head($object);
102  print dol_get_fiche_head($head, $tab, $langs->trans("Project"), -1, ($object->public ? 'projectpub' : 'project'));
103 
104  $param = ($mode == 'mine' ? '&mode=mine' : '');
105 
106 
107 
108  // Project card
109 
110  $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
111 
112  $morehtmlref = '<div class="refidno">';
113  // Title
114  $morehtmlref .= $object->title;
115  // Thirdparty
116  if ($object->thirdparty->id > 0)
117  {
118  $morehtmlref .= '<br>'.$langs->trans('ThirdParty').' : '.$object->thirdparty->getNomUrl(1, 'project');
119  }
120  $morehtmlref .= '</div>';
121 
122  // Define a complementary filter for search of next/prev ref.
123  if (!$user->rights->projet->all->lire)
124  {
125  $objectsListId = $object->getProjectsAuthorizedForUser($user, 0, 0);
126  $object->next_prev_filter = " rowid in (".(count($objectsListId) ?join(',', array_keys($objectsListId)) : '0').")";
127  }
128 
129  dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
130 
131 
132  print '<div class="fichecenter">';
133  print '<div class="fichehalfleft">';
134  print '<div class="underbanner clearboth"></div>';
135 
136  print '<table class="border tableforfield centpercent">';
137 
138  // Usage
139  print '<tr><td class="tdtop">';
140  print $langs->trans("Usage");
141  print '</td>';
142  print '<td>';
143  if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES))
144  {
145  print '<input type="checkbox" disabled name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_opportunity ? ' checked="checked"' : '')).'"> ';
146  $htmltext = $langs->trans("ProjectFollowOpportunity");
147  print $form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext);
148  print '<br>';
149  }
150  if (empty($conf->global->PROJECT_HIDE_TASKS))
151  {
152  print '<input type="checkbox" disabled name="usage_task"'.(GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_task ? ' checked="checked"' : '')).'"> ';
153  $htmltext = $langs->trans("ProjectFollowTasks");
154  print $form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext);
155  print '<br>';
156  }
157  if (!empty($conf->global->PROJECT_BILL_TIME_SPENT))
158  {
159  print '<input type="checkbox" disabled name="usage_bill_time"'.(GETPOSTISSET('usage_bill_time') ? (GETPOST('usage_bill_time', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_bill_time ? ' checked="checked"' : '')).'"> ';
160  $htmltext = $langs->trans("ProjectBillTimeDescription");
161  print $form->textwithpicto($langs->trans("BillTime"), $htmltext);
162  print '<br>';
163  }
164  print '</td></tr>';
165 
166  // Visibility
167  print '<tr><td class="titlefield">'.$langs->trans("Visibility").'</td><td>';
168  if ($object->public) print $langs->trans('SharedProject');
169  else print $langs->trans('PrivateProject');
170  print '</td></tr>';
171 
172  // Date start - end
173  print '<tr><td>'.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").'</td><td>';
174  $start = dol_print_date($object->date_start, 'day');
175  print ($start ? $start : '?');
176  $end = dol_print_date($object->date_end, 'day');
177  print ' - ';
178  print ($end ? $end : '?');
179  if ($object->hasDelay()) print img_warning("Late");
180  print '</td></tr>';
181 
182  // Budget
183  print '<tr><td>'.$langs->trans("Budget").'</td><td>';
184  if (strcmp($object->budget_amount, '')) print price($object->budget_amount, '', $langs, 1, 0, 0, $conf->currency);
185  print '</td></tr>';
186 
187  // Other attributes
188  $cols = 2;
189  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
190 
191  print '</table>';
192 
193  print '</div>';
194  print '<div class="fichehalfright">';
195  print '<div class="ficheaddleft">';
196  print '<div class="underbanner clearboth"></div>';
197 
198  print '<table class="border tableforfield centpercent">';
199 
200  // Description
201  print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>';
202  print nl2br($object->description);
203  print '</td></tr>';
204 
205  // Categories
206  if ($conf->categorie->enabled) {
207  print '<tr><td class="valignmiddle">'.$langs->trans("Categories").'</td><td>';
208  print $form->showCategories($object->id, Categorie::TYPE_PROJECT, 1);
209  print "</td></tr>";
210  }
211 
212  print '</table>';
213 
214  print '</div>';
215  print '</div>';
216  print '</div>';
217 
218  print '<div class="clearboth"></div>';
219 
221 
222  print '<br>';
223 }
224 
225 // Link to create task
226 $linktocreatetaskParam = array();
227 $linktocreatetaskUserRight = false;
228 if ($user->rights->projet->all->creer || $user->rights->projet->creer) {
229  if ($object->public || $userWrite > 0) {
230  $linktocreatetaskUserRight = true;
231  } else {
232  $linktocreatetaskParam['attr']['title'] = $langs->trans("NotOwnerOfProject");
233  }
234 }
235 
236 $linktocreatetask = dolGetButtonTitle($langs->trans('AddTask'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/projet/tasks.php?id='.$object->id.'&action=create'.$param.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$object->id), '', $linktocreatetaskUserRight, $linktocreatetaskParam);
237 
238 $linktotasks = dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-list-alt paddingleft imgforviewmode', DOL_URL_ROOT.'/projet/tasks.php?id='.$object->id, '', 1, array('morecss'=>'reposition'));
239 $linktotasks .= dolGetButtonTitle($langs->trans('ViewGantt'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/projet/ganttview.php?id='.$object->id.'&withproject=1', '', 1, array('morecss'=>'reposition marginleftonly btnTitleSelected'));
240 
241 //print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, $linktotasks, $num, $totalnboflines, 'generic', 0, '', '', 0, 1);
242 print load_fiche_titre($title, $linktotasks.' &nbsp; '.$linktocreatetask, 'projecttask');
243 
244 
245 // Get list of tasks in tasksarray and taskarrayfiltered
246 // We need all tasks (even not limited to a user because a task to user
247 // can have a parent that is not affected to him).
248 $tasksarray = $task->getTasksArray(0, 0, ($object->id ? $object->id : $id), $socid, 0);
249 // We load also tasks limited to a particular user
250 //$tasksrole=($_REQUEST["mode"]=='mine' ? $task->getUserRolesForProjectsOrTasks(0,$user,$object->id,0) : '');
251 //var_dump($tasksarray);
252 //var_dump($tasksrole);
253 
254 
255 if (count($tasksarray) > 0)
256 {
257  // Show Gant diagram from $taskarray using JSGantt
258 
259  $dateformat = $langs->trans("FormatDateShortJQuery"); // Used by include ganttchart.inc.php later
260  $datehourformat = $langs->trans("FormatDateShortJQuery").' '.$langs->trans("FormatHourShortJQuery"); // Used by include ganttchart.inc.php later
261  $array_contacts = array();
262  $tasks = array();
263  $task_dependencies = array();
264  $taskcursor = 0;
265  foreach ($tasksarray as $key => $val) // Task array are sorted by "project, position, date"
266  {
267  $task->fetch($val->id, '');
268 
269  $idparent = ($val->fk_parent ? $val->fk_parent : '-'.$val->fk_project); // If start with -, id is a project id
270 
271  $tasks[$taskcursor]['task_id'] = $val->id;
272  $tasks[$taskcursor]['task_alternate_id'] = ($taskcursor + 1); // An id that has same order than position (required by ganttchart)
273  $tasks[$taskcursor]['task_project_id'] = $val->fk_project;
274  $tasks[$taskcursor]['task_parent'] = $idparent;
275 
276  $tasks[$taskcursor]['task_is_group'] = 0;
277  $tasks[$taskcursor]['task_css'] = 'gtaskblue';
278  $tasks[$taskcursor]['task_position'] = $val->rang;
279  $tasks[$taskcursor]['task_planned_workload'] = $val->planned_workload;
280 
281  if ($val->fk_parent != 0 && $task->hasChildren() > 0) {
282  $tasks[$taskcursor]['task_is_group'] = 1;
283  $tasks[$taskcursor]['task_css'] = 'ggroupblack';
284  //$tasks[$taskcursor]['task_css'] = 'gtaskblue';
285  } elseif ($task->hasChildren() > 0) {
286  $tasks[$taskcursor]['task_is_group'] = 1;
287  //$tasks[$taskcursor]['task_is_group'] = 0;
288  $tasks[$taskcursor]['task_css'] = 'ggroupblack';
289  //$tasks[$taskcursor]['task_css'] = 'gtaskblue';
290  }
291  $tasks[$taskcursor]['task_milestone'] = '0';
292  $tasks[$taskcursor]['task_percent_complete'] = $val->progress;
293  //$tasks[$taskcursor]['task_name']=$task->getNomUrl(1);
294  //print dol_print_date($val->date_start).dol_print_date($val->date_end).'<br>'."\n";
295  $tasks[$taskcursor]['task_name'] = $val->ref.' - '.$val->label;
296  $tasks[$taskcursor]['task_start_date'] = $val->date_start;
297  $tasks[$taskcursor]['task_end_date'] = $val->date_end;
298  $tasks[$taskcursor]['task_color'] = 'b4d1ea';
299 
300  $idofusers = $task->getListContactId('internal');
301  $idofcontacts = $task->getListContactId('external');
302  $s = '';
303  if (count($idofusers) > 0)
304  {
305  $s .= $langs->trans("Internals").': ';
306  $i = 0;
307  foreach ($idofusers as $valid)
308  {
309  $userstatic->fetch($valid);
310  if ($i) $s .= ', ';
311  $s .= $userstatic->login;
312  $i++;
313  }
314  }
315  //if (count($idofusers)>0 && (count($idofcontacts)>0)) $s.=' - ';
316  if (count($idofcontacts) > 0)
317  {
318  if ($s) $s .= ' - ';
319  $s .= $langs->trans("Externals").': ';
320  $i = 0;
321  $contactidfound = array();
322  foreach ($idofcontacts as $valid)
323  {
324  if (empty($contactidfound[$valid]))
325  {
326  $res = $contactstatic->fetch($valid);
327  if ($res > 0)
328  {
329  if ($i) $s .= ', ';
330  $s .= $contactstatic->getFullName($langs);
331  $contactidfound[$valid] = 1;
332  $i++;
333  }
334  }
335  }
336  }
337 
338  /* For JSGanttImproved */
339  //if ($s) $tasks[$taskcursor]['task_resources']=implode(',',$idofusers);
340  $tasks[$taskcursor]['task_resources'] = $s;
341  if ($s) $tasks[$taskcursor]['task_resources'] = '<a href="'.DOL_URL_ROOT.'/projet/tasks/contact.php?id='.$val->id.'&withproject=1" title="'.dol_escape_htmltag($s).'">'.$langs->trans("List").'</a>';
342  //print "xxx".$val->id.$tasks[$taskcursor]['task_resources'];
343  $tasks[$taskcursor]['note'] = $task->note_public;
344  $taskcursor++;
345  }
346 
347  // Search parent to set task_parent_alternate_id (requird by ganttchart)
348  foreach ($tasks as $tmpkey => $tmptask)
349  {
350  foreach ($tasks as $tmptask2)
351  {
352  if ($tmptask2['task_id'] == $tmptask['task_parent'])
353  {
354  $tasks[$tmpkey]['task_parent_alternate_id'] = $tmptask2['task_alternate_id'];
355  break;
356  }
357  }
358  if (empty($tasks[$tmpkey]['task_parent_alternate_id'])) $tasks[$tmpkey]['task_parent_alternate_id'] = $tasks[$tmpkey]['task_parent'];
359  }
360 
361  print "\n";
362 
363  if (!empty($conf->use_javascript_ajax))
364  {
365  //var_dump($_SESSION);
366 
367  // How the date for data are formated (format used bu jsgantt)
368  $dateformatinput = 'yyyy-mm-dd';
369  // How the date for data are formated (format used by dol_print_date)
370  $dateformatinput2 = 'standard';
371  //var_dump($dateformatinput);
372  //var_dump($dateformatinput2);
373 
374  $moreforfilter = '<div class="liste_titre liste_titre_bydiv centpercent">';
375 
376  $moreforfilter .= '<div class="divsearchfield">';
377  //$moreforfilter .= $langs->trans("TasksAssignedTo").': ';
378  //$moreforfilter .= $form->select_dolusers($tmpuser->id > 0 ? $tmpuser->id : '', 'search_user_id', 1);
379  $moreforfilter .= '&nbsp;';
380  $moreforfilter .= '</div>';
381 
382  $moreforfilter .= '</div>';
383 
384  print $moreforfilter;
385 
386  print '<div class="div-table-responsive">';
387 
388  print '<div id="tabs" class="gantt" style="width: 80vw;">'."\n";
389  include_once DOL_DOCUMENT_ROOT.'/projet/ganttchart.inc.php';
390  print '</div>'."\n";
391 
392  print '</div>';
393  } else {
394  $langs->load("admin");
395  print $langs->trans("AvailableOnlyIfJavascriptAndAjaxNotDisabled");
396  }
397 } else {
398  print '<div class="opacitymedium">'.$langs->trans("NoTasks").'</div>';
399 }
400 
401 // End of page
402 llxFooter();
403 $db->close();
GETPOST($paramname, $check= 'alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
Class to manage contact/addresses.
dolGetButtonTitle($label, $helpText= '', $iconClass= 'fa fa-file', $url= '', $id= '', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
Class to manage Dolibarr users.
Definition: user.class.php:44
img_warning($titlealt= 'default', $moreatt= '', $morecss= 'pictowarning')
Show warning logo.
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...
llxHeader()
Empty header.
Definition: wrapper.php:45
Class to manage generation of HTML components Only common components must be here.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage projects.
load_fiche_titre($titre, $morehtmlright= '', $picto= 'generic', $pictoisfullpath=0, $id= '', $morecssontable= '', $morehtmlcenter= '')
Load a title with picto.
Classe permettant la generation de composants html autre Only common components are here...
restrictedArea($user, $features, $objectid=0, $tableandshare= '', $feature2= '', $dbt_keyfield= 'fk_soc', $dbt_select= 'rowid', $isdraft=0)
Check permissions of a user to show a page and an object.
print $_SERVER["PHP_SELF"]
Edit parameters.
dol_get_fiche_head($links=array(), $active= '', $title= '', $notab=0, $picto= '', $pictoisfullpath=0, $morehtmlright= '', $morecss= '', $limittoshow=0, $moretabssuffix= '')
Show tabs of a record.
project_prepare_head(Project $project)
Prepare array with list of tabs.
Definition: project.lib.php:36
print
Draft customers invoices.
Definition: index.php:89
Class to manage tasks.
Definition: task.class.php:35
dol_print_date($time, $format= '', $tzoutput= 'auto', $outputlangs= '', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_get_fiche_end($notab=0)
Return tab footer of a card.
dol_banner_tab($object, $paramid, $morehtml= '', $shownav=1, $fieldid= 'rowid', $fieldref= 'ref', $morehtmlref= '', $moreparam= '', $nodbprefix=0, $morehtmlleft= '', $morehtmlstatus= '', $onlybanner=0, $morehtmlright= '')
Show tab footer of a card.
llxFooter()
Empty footer.
Definition: wrapper.php:59
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $keepmoretags= '', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields...