dolibarr  18.0.6
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)) {
47  $object->fetchComments();
48 }
49 
50 // Security check
51 $socid = 0;
52 //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.
53 $result = restrictedArea($user, 'projet', $id, 'projet&project');
54 
55 // Load translation files required by the page
56 $langs->loadlangs(array('users', 'projects'));
57 
58 
59 /*
60  * Actions
61  */
62 
63 // None
64 
65 
66 /*
67  * View
68  */
69 
70 $form = new Form($db);
71 $formother = new FormOther($db);
72 $userstatic = new User($db);
73 $companystatic = new Societe($db);
74 $contactstatic = new Contact($db);
75 $task = new Task($db);
76 
77 $arrayofcss = array('/includes/jsgantt/jsgantt.css');
78 
79 if (!empty($conf->use_javascript_ajax)) {
80  $arrayofjs = array(
81  '/includes/jsgantt/jsgantt.js',
82  '/projet/jsgantt_language.js.php?lang='.$langs->defaultlang
83  );
84 }
85 
86 //$title=$langs->trans("Gantt").($object->ref?' - '.$object->ref.' '.$object->name:'');
87 $title = $langs->trans("Gantt");
88 if (!empty($conf->global->MAIN_HTML_TITLE) && preg_match('/projectnameonly/', $conf->global->MAIN_HTML_TITLE) && $object->name) {
89  $title = ($object->ref ? $object->ref.' '.$object->name.' - ' : '').$langs->trans("Gantt");
90 }
91 $help_url = "EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos";
92 
93 llxHeader("", $title, $help_url, '', 0, 0, $arrayofjs, $arrayofcss);
94 
95 if (($id > 0 && is_numeric($id)) || !empty($ref)) {
96  // To verify role of users
97  //$userAccess = $object->restrictedProjectArea($user,'read');
98  $userWrite = $object->restrictedProjectArea($user, 'write');
99  //$userDelete = $object->restrictedProjectArea($user,'delete');
100  //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete;
101 
102  $tab = 'tasks';
103 
104  $head = project_prepare_head($object);
105  print dol_get_fiche_head($head, $tab, $langs->trans("Project"), -1, ($object->public ? 'projectpub' : 'project'));
106 
107  $param = ($mode == 'mine' ? '&mode=mine' : '');
108 
109 
110 
111  // Project card
112 
113  if (!empty($_SESSION['pageforbacktolist']) && !empty($_SESSION['pageforbacktolist']['project'])) {
114  $tmpurl = $_SESSION['pageforbacktolist']['project'];
115  $tmpurl = preg_replace('/__SOCID__/', $object->socid, $tmpurl);
116  $linkback = '<a href="'.$tmpurl.(preg_match('/\?/', $tmpurl) ? '&' : '?'). 'restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
117  } else {
118  $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
119  }
120 
121  $morehtmlref = '<div class="refidno">';
122  // Title
123  $morehtmlref .= $object->title;
124  // Thirdparty
125  if (!empty($object->thirdparty->id) && $object->thirdparty->id > 0) {
126  $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1, 'project');
127  }
128  $morehtmlref .= '</div>';
129 
130  // Define a complementary filter for search of next/prev ref.
131  if (empty($user->rights->projet->all->lire)) {
132  $objectsListId = $object->getProjectsAuthorizedForUser($user, 0, 0);
133  $object->next_prev_filter = "rowid IN (".$db->sanitize(count($objectsListId) ?join(',', array_keys($objectsListId)) : '0').")";
134  }
135 
136  dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
137 
138 
139  print '<div class="fichecenter">';
140  print '<div class="fichehalfleft">';
141  print '<div class="underbanner clearboth"></div>';
142 
143  print '<table class="border tableforfield centpercent">';
144 
145  // Usage
146  if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES) || empty($conf->global->PROJECT_HIDE_TASKS) || isModEnabled('eventorganization')) {
147  print '<tr><td class="tdtop">';
148  print $langs->trans("Usage");
149  print '</td>';
150  print '<td>';
151  if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) {
152  print '<input type="checkbox" disabled name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_opportunity ? ' checked="checked"' : '')).'"> ';
153  $htmltext = $langs->trans("ProjectFollowOpportunity");
154  print $form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext);
155  print '<br>';
156  }
157  if (empty($conf->global->PROJECT_HIDE_TASKS)) {
158  print '<input type="checkbox" disabled name="usage_task"'.(GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_task ? ' checked="checked"' : '')).'"> ';
159  $htmltext = $langs->trans("ProjectFollowTasks");
160  print $form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext);
161  print '<br>';
162  }
163  if (empty($conf->global->PROJECT_HIDE_TASKS) && !empty($conf->global->PROJECT_BILL_TIME_SPENT)) {
164  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"' : '')).'"> ';
165  $htmltext = $langs->trans("ProjectBillTimeDescription");
166  print $form->textwithpicto($langs->trans("BillTime"), $htmltext);
167  print '<br>';
168  }
169  if (isModEnabled('eventorganization')) {
170  print '<input type="checkbox" disabled name="usage_organize_event"'.(GETPOSTISSET('usage_organize_event') ? (GETPOST('usage_organize_event', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_organize_event ? ' checked="checked"' : '')).'"> ';
171  $htmltext = $langs->trans("EventOrganizationDescriptionLong");
172  print $form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext);
173  }
174  print '</td></tr>';
175  }
176 
177  // Visibility
178  print '<tr><td class="titlefield">'.$langs->trans("Visibility").'</td><td>';
179  if ($object->public) {
180  print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
181  print $langs->trans('SharedProject');
182  } else {
183  print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
184  print $langs->trans('PrivateProject');
185  }
186  print '</td></tr>';
187 
188  // Budget
189  print '<tr><td>'.$langs->trans("Budget").'</td><td>';
190  if (!is_null($object->budget_amount) && strcmp($object->budget_amount, '')) {
191  print price($object->budget_amount, '', $langs, 1, 0, 0, $conf->currency);
192  }
193  print '</td></tr>';
194 
195  // Date start - end project
196  print '<tr><td>'.$langs->trans("Dates").'</td><td>';
197  $start = dol_print_date($object->date_start, 'day');
198  print ($start ? $start : '?');
199  $end = dol_print_date($object->date_end, 'day');
200  print ' - ';
201  print ($end ? $end : '?');
202  if ($object->hasDelay()) {
203  print img_warning("Late");
204  }
205  print '</td></tr>';
206 
207  // Other attributes
208  $cols = 2;
209  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
210 
211  print '</table>';
212 
213  print '</div>';
214  print '<div class="fichehalfright">';
215  print '<div class="underbanner clearboth"></div>';
216 
217  print '<table class="border tableforfield centpercent">';
218 
219  // Description
220  print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>';
221  print nl2br($object->description);
222  print '</td></tr>';
223 
224  // Categories
225  if (isModEnabled('categorie')) {
226  print '<tr><td class="valignmiddle">'.$langs->trans("Categories").'</td><td>';
227  print $form->showCategories($object->id, Categorie::TYPE_PROJECT, 1);
228  print "</td></tr>";
229  }
230 
231  print '</table>';
232 
233  print '</div>';
234  print '</div>';
235 
236  print '<div class="clearboth"></div>';
237 
238  print dol_get_fiche_end();
239 
240  print '<br>';
241 }
242 
243 // Link to create task
244 $linktocreatetaskParam = array();
245 $linktocreatetaskUserRight = false;
246 if ($user->rights->projet->all->creer || $user->rights->projet->creer) {
247  if ($object->public || $userWrite > 0) {
248  $linktocreatetaskUserRight = true;
249  } else {
250  $linktocreatetaskParam['attr']['title'] = $langs->trans("NotOwnerOfProject");
251  }
252 }
253 
254 $linktocreatetask = dolGetButtonTitle($langs->trans('AddTask'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/projet/tasks.php?id='.$object->id.'&action=create'.$param.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$object->id), '', $linktocreatetaskUserRight, $linktocreatetaskParam);
255 
256 $linktotasks = dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars paddingleft imgforviewmode', DOL_URL_ROOT.'/projet/tasks.php?id='.$object->id, '', 1, array('morecss'=>'reposition'));
257 $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'));
258 
259 //print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, $linktotasks, $num, $totalnboflines, 'generic', 0, '', '', 0, 1);
260 print load_fiche_titre($title, $linktotasks.' &nbsp; '.$linktocreatetask, 'projecttask');
261 
262 
263 // Get list of tasks in tasksarray and taskarrayfiltered
264 // We need all tasks (even not limited to a user because a task to user
265 // can have a parent that is not affected to him).
266 $tasksarray = $task->getTasksArray(0, 0, ($object->id ? $object->id : $id), $socid, 0);
267 // We load also tasks limited to a particular user
268 //$tasksrole=($_REQUEST["mode"]=='mine' ? $task->getUserRolesForProjectsOrTasks(null, $user, $object->id, 0) : '');
269 //var_dump($tasksarray);
270 //var_dump($tasksrole);
271 
272 
273 if (count($tasksarray) > 0) {
274  // Show Gant diagram from $taskarray using JSGantt
275 
276  $dateformat = $langs->trans("FormatDateShortJQuery"); // Used by include ganttchart.inc.php later
277  $datehourformat = $langs->trans("FormatDateShortJQuery").' '.$langs->trans("FormatHourShortJQuery"); // Used by include ganttchart.inc.php later
278  $array_contacts = array();
279  $tasks = array();
280  $task_dependencies = array();
281  $taskcursor = 0;
282  foreach ($tasksarray as $key => $val) { // Task array are sorted by "project, position, date"
283  $task->fetch($val->id, '');
284 
285  $idparent = ($val->fk_task_parent ? $val->fk_task_parent : '-'.$val->fk_project); // If start with -, id is a project id
286 
287  $tasks[$taskcursor]['task_id'] = $val->id;
288  $tasks[$taskcursor]['task_alternate_id'] = ($taskcursor + 1); // An id that has same order than position (required by ganttchart)
289  $tasks[$taskcursor]['task_project_id'] = $val->fk_project;
290  $tasks[$taskcursor]['task_parent'] = $idparent;
291 
292  $tasks[$taskcursor]['task_is_group'] = 0;
293  $tasks[$taskcursor]['task_css'] = 'gtaskblue';
294  $tasks[$taskcursor]['task_position'] = $val->rang;
295  $tasks[$taskcursor]['task_planned_workload'] = $val->planned_workload;
296 
297  if ($val->fk_task_parent != 0 && $task->hasChildren() > 0) {
298  $tasks[$taskcursor]['task_is_group'] = 1;
299  $tasks[$taskcursor]['task_css'] = 'ggroupblack';
300  //$tasks[$taskcursor]['task_css'] = 'gtaskblue';
301  } elseif ($task->hasChildren() > 0) {
302  $tasks[$taskcursor]['task_is_group'] = 1;
303  //$tasks[$taskcursor]['task_is_group'] = 0;
304  $tasks[$taskcursor]['task_css'] = 'ggroupblack';
305  //$tasks[$taskcursor]['task_css'] = 'gtaskblue';
306  }
307  $tasks[$taskcursor]['task_milestone'] = '0';
308  $tasks[$taskcursor]['task_percent_complete'] = $val->progress;
309  //$tasks[$taskcursor]['task_name']=$task->getNomUrl(1);
310  //print dol_print_date($val->date_start).dol_print_date($val->date_end).'<br>'."\n";
311  $tasks[$taskcursor]['task_name'] = $val->ref.' - '.$val->label;
312  $tasks[$taskcursor]['task_start_date'] = $val->date_start;
313  $tasks[$taskcursor]['task_end_date'] = $val->date_end;
314  $tasks[$taskcursor]['task_color'] = 'b4d1ea';
315 
316  $idofusers = $task->getListContactId('internal');
317  $idofcontacts = $task->getListContactId('external');
318  $s = '';
319  if (count($idofusers) > 0) {
320  $s .= $langs->trans("Internals").': ';
321  $i = 0;
322  foreach ($idofusers as $valid) {
323  $userstatic->fetch($valid);
324  if ($i) {
325  $s .= ', ';
326  }
327  $s .= $userstatic->login;
328  $i++;
329  }
330  }
331  //if (count($idofusers)>0 && (count($idofcontacts)>0)) $s.=' - ';
332  if (count($idofcontacts) > 0) {
333  if ($s) {
334  $s .= ' - ';
335  }
336  $s .= $langs->trans("Externals").': ';
337  $i = 0;
338  $contactidfound = array();
339  foreach ($idofcontacts as $valid) {
340  if (empty($contactidfound[$valid])) {
341  $res = $contactstatic->fetch($valid);
342  if ($res > 0) {
343  if ($i) {
344  $s .= ', ';
345  }
346  $s .= $contactstatic->getFullName($langs);
347  $contactidfound[$valid] = 1;
348  $i++;
349  }
350  }
351  }
352  }
353 
354  /* For JSGanttImproved */
355  //if ($s) $tasks[$taskcursor]['task_resources']=implode(',',$idofusers);
356  $tasks[$taskcursor]['task_resources'] = $s;
357  if ($s) {
358  $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>';
359  }
360  //print "xxx".$val->id.$tasks[$taskcursor]['task_resources'];
361  $tasks[$taskcursor]['note'] = $task->note_public;
362  $taskcursor++;
363  }
364 
365  // Search parent to set task_parent_alternate_id (requird by ganttchart)
366  foreach ($tasks as $tmpkey => $tmptask) {
367  foreach ($tasks as $tmptask2) {
368  if ($tmptask2['task_id'] == $tmptask['task_parent']) {
369  $tasks[$tmpkey]['task_parent_alternate_id'] = $tmptask2['task_alternate_id'];
370  break;
371  }
372  }
373  if (empty($tasks[$tmpkey]['task_parent_alternate_id'])) {
374  $tasks[$tmpkey]['task_parent_alternate_id'] = $tasks[$tmpkey]['task_parent'];
375  }
376  }
377 
378  print "\n";
379 
380  if (!empty($conf->use_javascript_ajax)) {
381  //var_dump($_SESSION);
382 
383  // How the date for data are formated (format used bu jsgantt)
384  $dateformatinput = 'yyyy-mm-dd';
385  // How the date for data are formated (format used by dol_print_date)
386  $dateformatinput2 = 'standard';
387  //var_dump($dateformatinput);
388  //var_dump($dateformatinput2);
389 
390  $moreforfilter = '<div class="liste_titre liste_titre_bydiv centpercent">';
391 
392  $moreforfilter .= '<div class="divsearchfield">';
393  //$moreforfilter .= $langs->trans("TasksAssignedTo").': ';
394  //$moreforfilter .= $form->select_dolusers($tmpuser->id > 0 ? $tmpuser->id : '', 'search_user_id', 1);
395  $moreforfilter .= '&nbsp;';
396  $moreforfilter .= '</div>';
397 
398  $moreforfilter .= '</div>';
399 
400  print $moreforfilter;
401 
402  print '<div class="div-table-responsive">';
403 
404  print '<div id="tabs" class="gantt" style="width: 80vw;">'."\n";
405  include_once DOL_DOCUMENT_ROOT.'/projet/ganttchart.inc.php';
406  print '</div>'."\n";
407 
408  print '</div>';
409  } else {
410  $langs->load("admin");
411  print $langs->trans("AvailableOnlyIfJavascriptAndAjaxNotDisabled");
412  }
413 } else {
414  print '<div class="opacitymedium">'.$langs->trans("NoTasks").'</div>';
415 }
416 
417 // End of page
418 llxFooter();
419 $db->close();
if(GETPOST('button_removefilter_x', 'alpha')||GETPOST('button_removefilter.x', 'alpha')||GETPOST('button_removefilter', 'alpha')) if(GETPOST('button_search_x', 'alpha')||GETPOST('button_search.x', 'alpha')||GETPOST('button_search', 'alpha')) if($action=="save" &&empty($cancel)) $help_url
View.
Definition: agenda.php:118
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:56
llxFooter()
Empty footer.
Definition: wrapper.php:70
Class to manage contact/addresses.
Class to manage generation of HTML components Only common components must be here.
Classe permettant la generation de composants html autre Only common components are here.
Class to manage projects.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage tasks.
Definition: task.class.php:40
Class to manage Dolibarr users.
Definition: user.class.php:48
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
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.
load_fiche_titre($titre, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
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.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
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='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
isModEnabled($module)
Is Dolibarr module enabled.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
project_prepare_head(Project $project, $moreparam='')
Prepare array with list of tabs.
Definition: project.lib.php:39
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.