ganttview.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  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 <http://www.gnu.org/licenses/>.
  18. */
  19. /**
  20. * \file htdocs/projet/ganttview.php
  21. * \ingroup projet
  22. * \brief Gantt diagramm of a project
  23. */
  24. require "../main.inc.php";
  25. require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
  26. require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
  27. require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
  28. require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
  29. require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
  30. require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
  31. require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
  32. $id=GETPOST('id','intcomma');
  33. $ref=GETPOST('ref','alpha');
  34. $mode = GETPOST('mode', 'alpha');
  35. $mine = ($mode == 'mine' ? 1 : 0);
  36. //if (! $user->rights->projet->all->lire) $mine=1; // Special for projects
  37. $object = new Project($db);
  38. include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once
  39. if(! empty($conf->global->PROJECT_ALLOW_COMMENT_ON_PROJECT) && method_exists($object, 'fetchComments') && empty($object->comments)) $object->fetchComments();
  40. // Security check
  41. $socid=0;
  42. //if ($user->societe_id > 0) $socid = $user->societe_id; // For external user, no check is done on company because readability is managed by public status of project and assignement.
  43. $result = restrictedArea($user, 'projet', $id, 'projet&project');
  44. // Load translation files required by the page
  45. $langs->loadlangs(array('users', 'projects'));
  46. /*
  47. * Actions
  48. */
  49. // None
  50. /*
  51. * View
  52. */
  53. $form=new Form($db);
  54. $formother=new FormOther($db);
  55. $userstatic=new User($db);
  56. $companystatic=new Societe($db);
  57. $contactstatic=new Contact($db);
  58. $task = new Task($db);
  59. $arrayofcss=array('/includes/jsgantt/jsgantt.css');
  60. if (! empty($conf->use_javascript_ajax))
  61. {
  62. $arrayofjs=array(
  63. '/includes/jsgantt/jsgantt.js',
  64. '/projet/jsgantt_language.js.php?lang='.$langs->defaultlang
  65. );
  66. }
  67. //$title=$langs->trans("Gantt").($object->ref?' - '.$object->ref.' '.$object->name:'');
  68. $title=$langs->trans("Gantt");
  69. 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");
  70. $help_url="EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos";
  71. llxHeader("",$title,$help_url,'',0,0,$arrayofjs,$arrayofcss);
  72. if (($id > 0 && is_numeric($id)) || ! empty($ref))
  73. {
  74. // To verify role of users
  75. //$userAccess = $object->restrictedProjectArea($user,'read');
  76. $userWrite = $object->restrictedProjectArea($user,'write');
  77. //$userDelete = $object->restrictedProjectArea($user,'delete');
  78. //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete;
  79. $tab='tasks';
  80. $head=project_prepare_head($object);
  81. dol_fiche_head($head, $tab, $langs->trans("Project"), -1, ($object->public?'projectpub':'project'));
  82. $param=($mode=='mine'?'&mode=mine':'');
  83. // Project card
  84. $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
  85. $morehtmlref='<div class="refidno">';
  86. // Title
  87. $morehtmlref.=$object->title;
  88. // Thirdparty
  89. if ($object->thirdparty->id > 0)
  90. {
  91. $morehtmlref.='<br>'.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1, 'project');
  92. }
  93. $morehtmlref.='</div>';
  94. // Define a complementary filter for search of next/prev ref.
  95. if (! $user->rights->projet->all->lire)
  96. {
  97. $objectsListId = $object->getProjectsAuthorizedForUser($user,0,0);
  98. $object->next_prev_filter=" rowid in (".(count($objectsListId)?join(',',array_keys($objectsListId)):'0').")";
  99. }
  100. dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
  101. print '<div class="fichecenter">';
  102. print '<div class="fichehalfleft">';
  103. print '<div class="underbanner clearboth"></div>';
  104. print '<table class="border" width="100%">';
  105. // Visibility
  106. print '<tr><td class="titlefield">'.$langs->trans("Visibility").'</td><td>';
  107. if ($object->public) print $langs->trans('SharedProject');
  108. else print $langs->trans('PrivateProject');
  109. print '</td></tr>';
  110. // Date start - end
  111. print '<tr><td>'.$langs->trans("DateStart").' - '.$langs->trans("DateEnd").'</td><td>';
  112. $start = dol_print_date($object->date_start,'day');
  113. print ($start?$start:'?');
  114. $end = dol_print_date($object->date_end,'day');
  115. print ' - ';
  116. print ($end?$end:'?');
  117. if ($object->hasDelay()) print img_warning("Late");
  118. print '</td></tr>';
  119. // Budget
  120. print '<tr><td>'.$langs->trans("Budget").'</td><td>';
  121. if (strcmp($object->budget_amount, '')) print price($object->budget_amount,'',$langs,1,0,0,$conf->currency);
  122. print '</td></tr>';
  123. // Other attributes
  124. $cols = 2;
  125. include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php';
  126. print '</table>';
  127. print '</div>';
  128. print '<div class="fichehalfright">';
  129. print '<div class="ficheaddleft">';
  130. print '<div class="underbanner clearboth"></div>';
  131. print '<table class="border" width="100%">';
  132. // Description
  133. print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>';
  134. print nl2br($object->description);
  135. print '</td></tr>';
  136. // Categories
  137. if($conf->categorie->enabled) {
  138. print '<tr><td valign="middle">'.$langs->trans("Categories").'</td><td>';
  139. print $form->showCategories($object->id,'project',1);
  140. print "</td></tr>";
  141. }
  142. print '</table>';
  143. print '</div>';
  144. print '</div>';
  145. print '</div>';
  146. print '<div class="clearboth"></div>';
  147. dol_fiche_end();
  148. print '<br>';
  149. }
  150. // Link to create task
  151. if ($user->rights->projet->all->creer || $user->rights->projet->creer)
  152. {
  153. if ($object->public || $userWrite > 0)
  154. {
  155. $linktocreatetask = '<a class="butActionNew" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=create'.$param.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$object->id).'">'.$langs->trans('AddTask').'<span class="fa fa-plus-circle valignmiddle"></span></a>';
  156. }
  157. else
  158. {
  159. $linktocreatetask = '<a class="butActionNewRefused" href="#" title="'.$langs->trans("NotOwnerOfProject").'">'.$langs->trans('AddTask').'<span class="fa fa-plus-circle valignmiddle"></span></a>';
  160. }
  161. }
  162. else
  163. {
  164. $linktocreatetask = '<a class="butActionNewRefused" href="#" title="'.$langs->trans("NotEnoughPermissions").'">'.$langs->trans('AddTask').'<span class="fa fa-plus-circle valignmiddle"></span></a>';
  165. }
  166. $linktolist='<a href="'.DOL_URL_ROOT.'/projet/tasks.php?id='.$object->id.'">'.$langs->trans("GoToListOfTasks").'<span class="paddingleft fa fa-list-ul valignmiddle"></span></a>';
  167. //print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, $linktotasks, $num, $totalnboflines, 'title_generic.png', 0, '', '', 0, 1);
  168. print load_fiche_titre($title, $linktolist.' &nbsp; '.$linktocreatetask, 'title_generic.png');
  169. // Get list of tasks in tasksarray and taskarrayfiltered
  170. // We need all tasks (even not limited to a user because a task to user
  171. // can have a parent that is not affected to him).
  172. $tasksarray=$task->getTasksArray(0, 0, ($object->id ? $object->id : $id), $socid, 0);
  173. // We load also tasks limited to a particular user
  174. //$tasksrole=($_REQUEST["mode"]=='mine' ? $task->getUserRolesForProjectsOrTasks(0,$user,$object->id,0) : '');
  175. //var_dump($tasksarray);
  176. //var_dump($tasksrole);
  177. if (count($tasksarray)>0)
  178. {
  179. // Show Gant diagram from $taskarray using JSGantt
  180. $dateformat=$langs->trans("FormatDateShortJQuery"); // Used by include ganttchart.inc.php later
  181. $datehourformat=$langs->trans("FormatDateShortJQuery").' '.$langs->trans("FormatHourShortJQuery"); // Used by include ganttchart.inc.php later
  182. $array_contacts=array();
  183. $tasks=array();
  184. $task_dependencies=array();
  185. $taskcursor=0;
  186. foreach($tasksarray as $key => $val) // Task array are sorted by "project, position, dateo"
  187. {
  188. $task->fetch($val->id, '');
  189. $idparent = ($val->fk_parent ? $val->fk_parent : '-'.$val->fk_project); // If start with -, id is a project id
  190. $tasks[$taskcursor]['task_id']=$val->id;
  191. $tasks[$taskcursor]['task_alternate_id']=($taskcursor+1); // An id that has same order than position (requird by ganttchart)
  192. $tasks[$taskcursor]['task_project_id']=$val->fk_project;
  193. $tasks[$taskcursor]['task_parent']=$idparent;
  194. $tasks[$taskcursor]['task_is_group'] = 0;
  195. $tasks[$taskcursor]['task_css'] = 'gtaskblue';
  196. $tasks[$taskcursor]['task_position'] = $val->rang;
  197. $tasks[$taskcursor]['task_planned_workload'] = $val->planned_workload;
  198. if ($val->fk_parent != 0 && $task->hasChildren()> 0){
  199. $tasks[$taskcursor]['task_is_group']=1;
  200. $tasks[$taskcursor]['task_css']='ggroupblack';
  201. //$tasks[$taskcursor]['task_css'] = 'gtaskblue';
  202. }
  203. elseif ($task->hasChildren()> 0) {
  204. $tasks[$taskcursor]['task_is_group'] = 1;
  205. //$tasks[$taskcursor]['task_is_group'] = 0;
  206. $tasks[$taskcursor]['task_css'] = 'ggroupblack';
  207. //$tasks[$taskcursor]['task_css'] = 'gtaskblue';
  208. }
  209. $tasks[$taskcursor]['task_milestone']='0';
  210. $tasks[$taskcursor]['task_percent_complete']=$val->progress;
  211. //$tasks[$taskcursor]['task_name']=$task->getNomUrl(1);
  212. //print dol_print_date($val->date_start).dol_print_date($val->date_end).'<br>'."\n";
  213. $tasks[$taskcursor]['task_name']=$val->ref.' - '.$val->label;
  214. $tasks[$taskcursor]['task_start_date']=$val->date_start;
  215. $tasks[$taskcursor]['task_end_date']=$val->date_end;
  216. $tasks[$taskcursor]['task_color']='b4d1ea';
  217. $idofusers=$task->getListContactId('internal');
  218. $idofcontacts=$task->getListContactId('external');
  219. $s='';
  220. if (count($idofusers)>0)
  221. {
  222. $s.=$langs->trans("Internals").': ';
  223. $i=0;
  224. foreach($idofusers as $valid)
  225. {
  226. $userstatic->fetch($valid);
  227. if ($i) $s.=', ';
  228. $s.=$userstatic->login;
  229. $i++;
  230. }
  231. }
  232. //if (count($idofusers)>0 && (count($idofcontacts)>0)) $s.=' - ';
  233. if (count($idofcontacts)>0)
  234. {
  235. if ($s) $s.=' - ';
  236. $s.=$langs->trans("Externals").': ';
  237. $i=0;
  238. $contactidfound=array();
  239. foreach($idofcontacts as $valid)
  240. {
  241. if (empty($contactidfound[$valid]))
  242. {
  243. $res = $contactstatic->fetch($valid);
  244. if ($res > 0)
  245. {
  246. if ($i) $s.=', ';
  247. $s.=$contactstatic->getFullName($langs);
  248. $contactidfound[$valid]=1;
  249. $i++;
  250. }
  251. }
  252. }
  253. }
  254. //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>';
  255. /* For JSGanttImproved */
  256. //if ($s) $tasks[$taskcursor]['task_resources']=implode(',',$idofusers);
  257. $tasks[$taskcursor]['task_resources'] = $s;
  258. //print "xxx".$val->id.$tasks[$taskcursor]['task_resources'];
  259. $tasks[$taskcursor]['note']=$task->note_public;
  260. $taskcursor++;
  261. }
  262. // Search parent to set task_parent_alternate_id (requird by ganttchart)
  263. foreach($tasks as $tmpkey => $tmptask)
  264. {
  265. foreach($tasks as $tmptask2)
  266. {
  267. if ($tmptask2['task_id'] == $tmptask['task_parent'])
  268. {
  269. $tasks[$tmpkey]['task_parent_alternate_id']=$tmptask2['task_alternate_id'];
  270. break;
  271. }
  272. }
  273. if (empty($tasks[$tmpkey]['task_parent_alternate_id'])) $tasks[$tmpkey]['task_parent_alternate_id'] = $tasks[$tmpkey]['task_parent'];
  274. }
  275. print "\n";
  276. if (! empty($conf->use_javascript_ajax))
  277. {
  278. //var_dump($_SESSION);
  279. // How the date for data are formated (format used bu jsgantt)
  280. $dateformatinput='yyyy-mm-dd';
  281. // How the date for data are formated (format used by dol_print_date)
  282. $dateformatinput2='standard';
  283. //var_dump($dateformatinput);
  284. //var_dump($dateformatinput2);
  285. print '<div class="div-table-responsive">';
  286. print '<div id="tabs" class="gantt" style="width: 80vw;">'."\n";
  287. include_once DOL_DOCUMENT_ROOT.'/projet/ganttchart.inc.php';
  288. print '</div>'."\n";
  289. print '</div>';
  290. }
  291. else
  292. {
  293. $langs->load("admin");
  294. print $langs->trans("AvailableOnlyIfJavascriptAndAjaxNotDisabled");
  295. }
  296. }
  297. else
  298. {
  299. print '<div class="opacitymedium">'.$langs->trans("NoTasks").'</div>';
  300. }
  301. // End of page
  302. llxFooter();
  303. $db->close();