dolibarr 19.0.3
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
26require "../main.inc.php";
27require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
28require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
29require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
30require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
31require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
32require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
33require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
34require_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
45include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once
46if (getDolGlobalString('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
79if (!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");
88if (getDolGlobalString('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
93llxHeader("", $title, $help_url, '', 0, 0, $arrayofjs, $arrayofcss);
94
95if (($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 (!$user->hasRight('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 (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') || !getDolGlobalString('PROJECT_HIDE_TASKS') || isModEnabled('eventorganization')) {
147 print '<tr><td class="tdtop">';
148 print $langs->trans("Usage");
149 print '</td>';
150 print '<td>';
151 if (getDolGlobalString('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 (!getDolGlobalString('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 (!getDolGlobalString('PROJECT_HIDE_TASKS') && getDolGlobalString('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;
246if ($user->hasRight('projet', 'all', 'creer') || $user->hasRight('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);
260print 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
273if (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
418llxFooter();
419$db->close();
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader()
Empty header.
Definition wrapper.php:55
llxFooter()
Empty footer.
Definition wrapper.php:69
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.
Class to manage Dolibarr users.
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.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
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.
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.
Contact()
Old copy.
Definition index.php:572