dolibarr  x.y.z
tasks.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2019 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005-2017 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.'/core/class/html.formother.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
34 if (isModEnabled('categorie')) {
35  require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
36 }
37 
38 // Load translation files required by the page
39 $langsLoad=array('projects', 'users', 'companies');
40 if (isModEnabled('eventorganization')) {
41  $langsLoad[]='eventorganization';
42 }
43 
44 $langs->loadLangs($langsLoad);
45 
46 $action = GETPOST('action', 'aZ09');
47 $massaction = GETPOST('massaction', 'alpha');
48 $show_files = GETPOST('show_files', 'int');
49 $confirm = GETPOST('confirm', 'alpha');
50 $toselect = GETPOST('toselect', 'array');
51 
52 $id = GETPOST('id', 'int');
53 $ref = GETPOST('ref', 'alpha');
54 $taskref = GETPOST('taskref', 'alpha');
55 
56 // Load variable for pagination
57 $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
58 $sortfield = GETPOST('sortfield', 'aZ09comma');
59 $sortorder = GETPOST('sortorder', 'aZ09comma');
60 $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
61 if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
62  $page = 0;
63 } // If $page is not defined, or '' or -1 or if we click on clear filters
64 $offset = $limit * $page;
65 $pageprev = $page - 1;
66 $pagenext = $page + 1;
67 
68 $backtopage = GETPOST('backtopage', 'alpha');
69 $cancel = GETPOST('cancel', 'alpha');
70 
71 $search_user_id = GETPOST('search_user_id', 'int');
72 $search_taskref = GETPOST('search_taskref');
73 $search_tasklabel = GETPOST('search_tasklabel');
74 $search_taskdescription = GETPOST('search_taskdescription');
75 $search_dtstartday = GETPOST('search_dtstartday');
76 $search_dtstartmonth = GETPOST('search_dtstartmonth');
77 $search_dtstartyear = GETPOST('search_dtstartyear');
78 $search_dtendday = GETPOST('search_dtendday');
79 $search_dtendmonth = GETPOST('search_dtendmonth');
80 $search_dtendyear = GETPOST('search_dtendyear');
81 $search_planedworkload = GETPOST('search_planedworkload');
82 $search_timespend = GETPOST('search_timespend');
83 $search_progresscalc = GETPOST('search_progresscalc');
84 $search_progressdeclare = GETPOST('search_progressdeclare');
85 $search_task_budget_amount = GETPOST('search_task_budget_amount');
86 
87 $search_date_start_startmonth = GETPOST('search_date_start_startmonth', 'int');
88 $search_date_start_startyear = GETPOST('search_date_start_startyear', 'int');
89 $search_date_start_startday = GETPOST('search_date_start_startday', 'int');
90 $search_date_start_start = dol_mktime(0, 0, 0, $search_date_start_startmonth, $search_date_start_startday, $search_date_start_startyear); // Use tzserver
91 $search_date_start_endmonth = GETPOST('search_date_start_endmonth', 'int');
92 $search_date_start_endyear = GETPOST('search_date_start_endyear', 'int');
93 $search_date_start_endday = GETPOST('search_date_start_endday', 'int');
94 $search_date_start_end = dol_mktime(23, 59, 59, $search_date_start_endmonth, $search_date_start_endday, $search_date_start_endyear); // Use tzserver
95 
96 $search_date_end_startmonth = GETPOST('search_date_end_startmonth', 'int');
97 $search_date_end_startyear = GETPOST('search_date_end_startyear', 'int');
98 $search_date_end_startday = GETPOST('search_date_end_startday', 'int');
99 $search_date_end_start = dol_mktime(0, 0, 0, $search_date_end_startmonth, $search_date_end_startday, $search_date_end_startyear); // Use tzserver
100 $search_date_end_endmonth = GETPOST('search_date_end_endmonth', 'int');
101 $search_date_end_endyear = GETPOST('search_date_end_endyear', 'int');
102 $search_date_end_endday = GETPOST('search_date_end_endday', 'int');
103 $search_date_end_end = dol_mktime(23, 59, 59, $search_date_end_endmonth, $search_date_end_endday, $search_date_end_endyear); // Use tzserver
104 
105 $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'projecttasklist';
106 $optioncss = GETPOST('optioncss', 'aZ');
107 //if (! $user->rights->projet->all->lire) $mine=1; // Special for projects
108 
109 $object = new Project($db);
110 $taskstatic = new Task($db);
111 $extrafields = new ExtraFields($db);
112 
113 include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once
114 if (!empty($conf->global->PROJECT_ALLOW_COMMENT_ON_PROJECT) && method_exists($object, 'fetchComments') && empty($object->comments)) {
115  $object->fetchComments();
116 }
117 
118 if ($id > 0 || !empty($ref)) {
119  // fetch optionals attributes and labels
120  $extrafields->fetch_name_optionals_label($object->table_element);
121 }
122 $extrafields->fetch_name_optionals_label($taskstatic->table_element);
123 $search_array_options = $extrafields->getOptionalsFromPost($taskstatic->table_element, '', 'search_');
124 
125 
126 // Default sort order (if not yet defined by previous GETPOST)
127 if (!$sortfield) {
128  reset($object->fields); $sortfield="t.".key($object->fields);
129 } // Set here default search field. By default 1st field in definition. Reset is required to avoid key() to return null.
130 if (!$sortorder) {
131  $sortorder = "ASC";
132 }
133 
134 
135 // Security check
136 $socid = 0;
137 //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.
138 $result = restrictedArea($user, 'projet', $id, 'projet&project');
139 
140 $diroutputmassaction = $conf->project->dir_output.'/tasks/temp/massgeneration/'.$user->id;
141 
142 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
143 $hookmanager->initHooks(array('projecttaskscard', 'globalcard'));
144 
145 $progress = GETPOST('progress', 'int');
146 $budget_amount = GETPOST('budget_amount', 'int');
147 $label = GETPOST('label', 'alpha');
148 $description = GETPOST('description', 'restricthtml');
149 $planned_workloadhour = (GETPOST('planned_workloadhour', 'int') ?GETPOST('planned_workloadhour', 'int') : 0);
150 $planned_workloadmin = (GETPOST('planned_workloadmin', 'int') ?GETPOST('planned_workloadmin', 'int') : 0);
151 $planned_workload = $planned_workloadhour * 3600 + $planned_workloadmin * 60;
152 
153 // Definition of fields for list
154 $arrayfields = array(
155  't.ref'=>array('label'=>"RefTask", 'checked'=>1, 'position'=>1),
156  't.label'=>array('label'=>"LabelTask", 'checked'=>1, 'position'=>2),
157  't.description'=>array('label'=>"Description", 'checked'=>0, 'position'=>3),
158  't.dateo'=>array('label'=>"DateStart", 'checked'=>1, 'position'=>4),
159  't.datee'=>array('label'=>"Deadline", 'checked'=>1, 'position'=>5),
160  't.planned_workload'=>array('label'=>"PlannedWorkload", 'checked'=>1, 'position'=>6),
161  't.duration_effective'=>array('label'=>"TimeSpent", 'checked'=>1, 'position'=>7),
162  't.progress_calculated'=>array('label'=>"ProgressCalculated", 'checked'=>1, 'position'=>8),
163  't.progress'=>array('label'=>"ProgressDeclared", 'checked'=>1, 'position'=>9),
164  't.progress_summary'=>array('label'=>"TaskProgressSummary", 'checked'=>1, 'position'=>10),
165  't.budget_amount'=>array('label'=>"Budget", 'checked'=>0, 'position'=>11),
166  'c.assigned'=>array('label'=>"TaskRessourceLinks", 'checked'=>1, 'position'=>12),
167 );
168 if ($object->usage_bill_time) {
169  $arrayfields['t.tobill'] = array('label'=>$langs->trans("TimeToBill"), 'checked'=>0, 'position'=>11);
170  $arrayfields['t.billed'] = array('label'=>$langs->trans("TimeBilled"), 'checked'=>0, 'position'=>12);
171 }
172 
173 // Extra fields
174 $extrafieldsobjectkey = $taskstatic->table_element;
175 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
176 
177 $arrayfields = dol_sort_array($arrayfields, 'position');
178 
179 $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
180 
181 
182 /*
183  * Actions
184  */
185 
186 $parameters = array('id'=>$id);
187 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
188 if ($reshook < 0) {
189  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
190 }
191 
192 if (empty($reshook)) {
193  // Selection of new fields
194  include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
195 
196  // Purge search criteria
197  if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
198  $search_user_id = "";
199  $search_taskref = '';
200  $search_tasklabel = '';
201  $search_dtstartday = '';
202  $search_dtstartmonth = '';
203  $search_dtstartyear = '';
204  $search_dtendday = '';
205  $search_dtendmonth = '';
206  $search_dtendyear = '';
207  $search_planedworkload = '';
208  $search_timespend = '';
209  $search_progresscalc = '';
210  $search_progressdeclare = '';
211  $search_task_budget_amount = '';
212  $toselect = array();
213  $search_array_options = array();
214  $search_date_start_startmonth = "";
215  $search_date_start_startyear = "";
216  $search_date_start_startday = "";
217  $search_date_start_start = "";
218  $search_date_start_endmonth = "";
219  $search_date_start_endyear = "";
220  $search_date_start_endday = "";
221  $search_date_start_end = "";
222  $search_date_end_startmonth = "";
223  $search_date_end_startyear = "";
224  $search_date_end_startday = "";
225  $search_date_end_start = "";
226  $search_date_end_endmonth = "";
227  $search_date_end_endyear = "";
228  $search_date_end_endday = "";
229  $search_date_end_end = "";
230  }
231 
232  // Mass actions
233  $objectclass = 'Task';
234  $objectlabel = 'Tasks';
235  $permissiontoread = $user->rights->projet->lire;
236  $permissiontodelete = $user->rights->projet->supprimer;
237  $uploaddir = $conf->project->dir_output.'/tasks';
238  include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
239 }
240 
241 $morewherefilterarray = array();
242 
243 if (!empty($search_taskref)) {
244  $morewherefilterarray[] = natural_search('t.ref', $search_taskref, 0, 1);
245 }
246 
247 if (!empty($search_tasklabel)) {
248  $morewherefilterarray[] = natural_search('t.label', $search_tasklabel, 0, 1);
249 }
250 
251 $moresql = dolSqlDateFilter('t.dateo', $search_dtstartday, $search_dtstartmonth, $search_dtstartyear, 1);
252 if ($moresql) {
253  $morewherefilterarray[] = $moresql;
254 }
255 
256 $moresql = dolSqlDateFilter('t.datee', $search_dtendday, $search_dtendmonth, $search_dtendyear, 1);
257 if ($moresql) {
258  $morewherefilterarray[] = $moresql;
259 }
260 
261 if ($search_date_start_start) {
262  $morewherefilterarray[] = " t.dateo >= '".$db->idate($search_date_start_start)."'";
263 }
264 if ($search_date_start_end) {
265  $morewherefilterarray[] = " t.dateo <= '".$db->idate($search_date_start_end)."'";
266 }
267 
268 if ($search_date_end_start) {
269  $morewherefilterarray[] = " t.datee >= '".$db->idate($search_date_end_start)."'";
270 }
271 if ($search_date_end_end) {
272  $morewherefilterarray[] = " t.datee <= '".$db->idate($search_date_end_end)."'";
273 }
274 
275 if (!empty($search_planedworkload)) {
276  $morewherefilterarray[] = natural_search('t.planned_workload', $search_planedworkload, 1, 1);
277 }
278 
279 if (!empty($search_timespend)) {
280  $morewherefilterarray[] = natural_search('t.duration_effective', $search_timespend, 1, 1);
281 }
282 
283 if (!empty($search_progresscalc)) {
284  $filterprogresscalc = 'if '.natural_search('round(100 * $line->duration / $line->planned_workload,2)', $search_progresscalc, 1, 1).'{return 1;} else {return 0;}';
285 } else {
286  $filterprogresscalc = '';
287 }
288 
289 if (!empty($search_progressdeclare)) {
290  $morewherefilterarray[] = natural_search('t.progress', $search_progressdeclare, 1, 1);
291 }
292 
293 if ($search_task_budget_amount) {
294  $morewherefilterarray[]= natural_search('t.budget_amount', $search_task_budget_amount, 1, 1);
295 }
296 
297 $morewherefilter = '';
298 if (count($morewherefilterarray) > 0) {
299  $morewherefilter = ' AND '.implode(' AND ', $morewherefilterarray);
300 }
301 
302 if ($action == 'createtask' && $user->rights->projet->creer) {
303  $error = 0;
304 
305  // If we use user timezone, we must change also view/list to use user timezone everywhere
306  $date_start = dol_mktime(GETPOST('dateohour', 'int'), GETPOST('dateomin', 'int'), 0, GETPOST('dateomonth', 'int'), GETPOST('dateoday', 'int'), GETPOST('dateoyear', 'int'));
307  $date_end = dol_mktime(GETPOST('dateehour', 'int'), GETPOST('dateemin', 'int'), 0, GETPOST('dateemonth', 'int'), GETPOST('dateeday', 'int'), GETPOST('dateeyear', 'int'));
308 
309  if (!$cancel) {
310  if (empty($taskref)) {
311  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Ref")), null, 'errors');
312  $action = 'create';
313  $error++;
314  }
315  if (empty($label)) {
316  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
317  $action = 'create';
318  $error++;
319  } elseif (!GETPOST('task_parent')) {
320  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("ChildOfProjectTask")), null, 'errors');
321  $action = 'create';
322  $error++;
323  }
324 
325  if (!$error) {
326  $tmparray = explode('_', GETPOST('task_parent'));
327  $projectid = $tmparray[0];
328  if (empty($projectid)) {
329  $projectid = $id; // If projectid is ''
330  }
331  $task_parent = $tmparray[1];
332  if (empty($task_parent)) {
333  $task_parent = 0; // If task_parent is ''
334  }
335 
336  $task = new Task($db);
337 
338  $task->fk_project = $projectid;
339  $task->ref = $taskref;
340  $task->label = $label;
341  $task->description = $description;
342  $task->planned_workload = $planned_workload;
343  $task->fk_task_parent = $task_parent;
344  $task->date_c = dol_now();
345  $task->date_start = $date_start;
346  $task->date_end = $date_end;
347  $task->progress = $progress;
348  $task->budget_amount = $budget_amount;
349 
350  // Fill array 'array_options' with data from add form
351  $ret = $extrafields->setOptionalsFromPost(null, $task);
352 
353  $taskid = $task->create($user);
354 
355  if ($taskid > 0) {
356  $result = $task->add_contact(GETPOST("userid", 'int'), 'TASKEXECUTIVE', 'internal');
357  } else {
358  if ($db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
359  $langs->load("projects");
360  setEventMessages($langs->trans('NewTaskRefSuggested'), null, 'warnings');
361  $duplicate_code_error = true;
362  } else {
363  setEventMessages($task->error, $task->errors, 'errors');
364  }
365  $action = 'create';
366  $error++;
367  }
368  }
369 
370  if (!$error) {
371  if (!empty($backtopage)) {
372  header("Location: ".$backtopage);
373  exit;
374  } elseif (empty($projectid)) {
375  header("Location: ".DOL_URL_ROOT.'/projet/tasks/list.php'.(empty($mode) ? '' : '?mode='.$mode));
376  exit;
377  }
378  $id = $projectid;
379  }
380  } else {
381  if (!empty($backtopage)) {
382  header("Location: ".$backtopage);
383  exit;
384  } elseif (empty($id)) {
385  // We go back on task list
386  header("Location: ".DOL_URL_ROOT.'/projet/tasks/list.php'.(empty($mode) ? '' : '?mode='.$mode));
387  exit;
388  }
389  }
390 }
391 
392 
393 /*
394  * View
395  */
396 
397 $now = dol_now();
398 $form = new Form($db);
399 $formother = new FormOther($db);
400 $socstatic = new Societe($db);
401 $projectstatic = new Project($db);
402 $taskstatic = new Task($db);
403 $userstatic = new User($db);
404 
405 $title = $langs->trans("Tasks").' - '.$object->ref.' '.$object->name;
406 if (!empty($conf->global->MAIN_HTML_TITLE) && preg_match('/projectnameonly/', $conf->global->MAIN_HTML_TITLE) && $object->name) {
407  $title = $object->ref.' '.$object->name.' - '.$langs->trans("Tasks");
408 }
409 if ($action == 'create') {
410  $title = $langs->trans("NewTask");
411 }
412 $help_url = "EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos";
413 
414 llxHeader("", $title, $help_url);
415 
416 
417 if ($id > 0 || !empty($ref)) {
418  $result = $object->fetch($id, $ref);
419  if ($result < 0) {
420  setEventMessages(null, $object->errors, 'errors');
421  }
422  $result = $object->fetch_thirdparty();
423  if ($result < 0) {
424  setEventMessages(null, $object->errors, 'errors');
425  }
426  $result = $object->fetch_optionals();
427  if ($result < 0) {
428  setEventMessages(null, $object->errors, 'errors');
429  }
430 
431 
432  // To verify role of users
433  //$userAccess = $object->restrictedProjectArea($user,'read');
434  $userWrite = $object->restrictedProjectArea($user, 'write');
435  //$userDelete = $object->restrictedProjectArea($user,'delete');
436  //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete;
437 
438 
439  $tab = (GETPOSTISSET('tab') ? GETPOST('tab') : 'tasks');
440 
441  $head = project_prepare_head($object);
442  print dol_get_fiche_head($head, $tab, $langs->trans("Project"), -1, ($object->public ? 'projectpub' : 'project'));
443 
444  $param = '&id='.$object->id;
445  if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
446  $param .= '&contextpage='.urlencode($contextpage);
447  }
448  if ($search_user_id) {
449  $param .= '&search_user_id='.urlencode($search_user_id);
450  }
451  if ($search_taskref) {
452  $param .= '&search_taskref='.urlencode($search_taskref);
453  }
454  if ($search_tasklabel) {
455  $param .= '&search_tasklabel='.urlencode($search_tasklabel);
456  }
457  if ($search_taskdescription) {
458  $param .= '&search_taskdescription='.urlencode($search_taskdescription);
459  }
460  if ($search_dtstartday) {
461  $param .= '&search_dtstartday='.urlencode($search_dtstartday);
462  }
463  if ($search_dtstartmonth) {
464  $param .= '&search_dtstartmonth='.urlencode($search_dtstartmonth);
465  }
466  if ($search_dtstartyear) {
467  $param .= '&search_dtstartyear='.urlencode($search_dtstartyear);
468  }
469  if ($search_dtendday) {
470  $param .= '&search_dtendday='.urlencode($search_dtendday);
471  }
472  if ($search_dtendmonth) {
473  $param .= '&search_dtendmonth='.urlencode($search_dtendmonth);
474  }
475  if ($search_dtendyear) {
476  $param .= '&search_dtendyear='.urlencode($search_dtendyear);
477  }
478  if ($search_date_start_startmonth) {
479  $param .= '&search_date_start_startmonth='.urlencode($search_date_start_startmonth);
480  }
481  if ($search_date_start_startyear) {
482  $param .= '&search_date_start_startyear='.urlencode($search_date_start_startyear);
483  }
484  if ($search_date_start_startday) {
485  $param .= '&search_date_start_startday='.urlencode($search_date_start_startday);
486  }
487  if ($search_date_start_start) {
488  $param .= '&search_date_start_start='.urlencode($search_date_start_start);
489  }
490  if ($search_date_start_endmonth) {
491  $param .= '&search_date_start_endmonth='.urlencode($search_date_start_endmonth);
492  }
493  if ($search_date_start_endyear) {
494  $param .= '&search_date_start_endyear='.urlencode($search_date_start_endyear);
495  }
496  if ($search_date_start_endday) {
497  $param .= '&search_date_start_endday='.urlencode($search_date_start_endday);
498  }
499  if ($search_date_start_end) {
500  $param .= '&search_date_start_end='.urlencode($search_date_start_end);
501  }
502  if ($search_date_end_startmonth) {
503  $param .= '&search_date_end_startmonth='.urlencode($search_date_end_startmonth);
504  }
505  if ($search_date_end_startyear) {
506  $param .= '&search_date_end_startyear='.urlencode($search_date_end_startyear);
507  }
508  if ($search_date_end_startday) {
509  $param .= '&search_date_end_startday='.urlencode($search_date_end_startday);
510  }
511  if ($search_date_end_start) {
512  $param .= '&search_date_end_start='.urlencode($search_date_end_start);
513  }
514  if ($search_date_end_endmonth) {
515  $param .= '&search_date_end_endmonth='.urlencode($search_date_end_endmonth);
516  }
517  if ($search_date_end_endyear) {
518  $param .= '&search_date_end_endyear='.urlencode($search_date_end_endyear);
519  }
520  if ($search_date_end_endday) {
521  $param .= '&search_date_end_endday='.urlencode($search_date_end_endday);
522  }
523  if ($search_date_end_end) {
524  $param .= '&search_date_end_end=' . urlencode($search_date_end_end);
525  }
526  if ($search_planedworkload) {
527  $param .= '&search_planedworkload='.urlencode($search_planedworkload);
528  }
529  if ($search_timespend) {
530  $param .= '&search_timespend='.urlencode($search_timespend);
531  }
532  if ($search_progresscalc) {
533  $param .= '&search_progresscalc='.urlencode($search_progresscalc);
534  }
535  if ($search_progressdeclare) {
536  $param .= '&search_progressdeclare='.urlencode($search_progressdeclare);
537  }
538  if ($search_task_budget_amount) {
539  $param .= '&search_task_budget_amount='.urlencode($search_task_budget_amount);
540  }
541  if ($optioncss != '') {
542  $param .= '&optioncss='.urlencode($optioncss);
543  }
544  // Add $param from extra fields
545  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
546 
547  // Project card
548 
549  $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
550 
551  $morehtmlref = '<div class="refidno">';
552  // Title
553  $morehtmlref .= $object->title;
554  // Thirdparty
555  if (!empty($object->thirdparty->id) && $object->thirdparty->id > 0) {
556  $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1, 'project');
557  }
558  $morehtmlref .= '</div>';
559 
560  // Define a complementary filter for search of next/prev ref.
561  if (empty($user->rights->projet->all->lire)) {
562  $objectsListId = $object->getProjectsAuthorizedForUser($user, 0, 0);
563  $object->next_prev_filter = " rowid IN (".$db->sanitize(count($objectsListId) ?join(',', array_keys($objectsListId)) : '0').")";
564  }
565 
566  dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
567 
568  print '<div class="fichecenter">';
569  print '<div class="fichehalfleft">';
570  print '<div class="underbanner clearboth"></div>';
571 
572  print '<table class="border tableforfield centpercent">';
573 
574  // Usage
575  if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES) || empty($conf->global->PROJECT_HIDE_TASKS) || isModEnabled('eventorganization')) {
576  print '<tr><td class="tdtop">';
577  print $langs->trans("Usage");
578  print '</td>';
579  print '<td>';
580  if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) {
581  print '<input type="checkbox" disabled name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_opportunity ? ' checked="checked"' : '')).'"> ';
582  $htmltext = $langs->trans("ProjectFollowOpportunity");
583  print $form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext);
584  print '<br>';
585  }
586  if (empty($conf->global->PROJECT_HIDE_TASKS)) {
587  print '<input type="checkbox" disabled name="usage_task"'.(GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_task ? ' checked="checked"' : '')).'"> ';
588  $htmltext = $langs->trans("ProjectFollowTasks");
589  print $form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext);
590  print '<br>';
591  }
592  if (empty($conf->global->PROJECT_HIDE_TASKS) && !empty($conf->global->PROJECT_BILL_TIME_SPENT)) {
593  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"' : '')).'"> ';
594  $htmltext = $langs->trans("ProjectBillTimeDescription");
595  print $form->textwithpicto($langs->trans("BillTime"), $htmltext);
596  print '<br>';
597  }
598  if (isModEnabled('eventorganization')) {
599  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"' : '')).'"> ';
600  $htmltext = $langs->trans("EventOrganizationDescriptionLong");
601  print $form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext);
602  }
603  print '</td></tr>';
604  }
605 
606  // Visibility
607  print '<tr><td class="titlefield">'.$langs->trans("Visibility").'</td><td>';
608  if ($object->public) {
609  print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
610  print $langs->trans('SharedProject');
611  } else {
612  print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
613  print $langs->trans('PrivateProject');
614  }
615  print '</td></tr>';
616 
617  // Budget
618  print '<tr><td>'.$langs->trans("Budget").'</td><td>';
619  if (strcmp($object->budget_amount, '')) {
620  print '<span class="amount">'.price($object->budget_amount, '', $langs, 1, 0, 0, $conf->currency).'</span>';
621  }
622  print '</td></tr>';
623 
624  // Date start - end project
625  print '<tr><td>'.$langs->trans("Dates").'</td><td>';
626  $start = dol_print_date($object->date_start, 'day');
627  print ($start ? $start : '?');
628  $end = dol_print_date($object->date_end, 'day');
629  print ' - ';
630  print ($end ? $end : '?');
631  if ($object->hasDelay()) {
632  print img_warning("Late");
633  }
634  print '</td></tr>';
635 
636  // Other attributes
637  $cols = 2;
638  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
639 
640  print '</table>';
641 
642  print '</div>';
643  print '<div class="fichehalfright">';
644  print '<div class="underbanner clearboth"></div>';
645 
646  print '<table class="border tableforfield centpercent">';
647 
648  // Description
649  print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>';
650  print nl2br($object->description);
651  print '</td></tr>';
652 
653  // Categories
654  if (isModEnabled('categorie')) {
655  print '<tr><td class="valignmiddle">'.$langs->trans("Categories").'</td><td>';
656  print $form->showCategories($object->id, Categorie::TYPE_PROJECT, 1);
657  print "</td></tr>";
658  }
659 
660  print '</table>';
661 
662  print '</div>';
663  print '</div>';
664 
665  print '<div class="clearboth"></div>';
666 
667 
668  print dol_get_fiche_end();
669 }
670 
671 
672 if ($action == 'create' && $user->rights->projet->creer && (empty($object->thirdparty->id) || $userWrite > 0)) {
673  if ($id > 0 || !empty($ref)) {
674  print '<br>';
675  }
676 
677  print load_fiche_titre($langs->trans("NewTask"), '', 'projecttask');
678 
679  $projectoktoentertime = 1;
680  if ($object->id > 0 && $object->statut == Project::STATUS_CLOSED) {
681  $projectoktoentertime = 0;
682  print '<div class="warning">';
683  $langs->load("errors");
684  print $langs->trans("WarningProjectClosed");
685  print '</div>';
686  }
687 
688  if ($object->id > 0 && $object->statut == Project::STATUS_DRAFT) {
689  $projectoktoentertime = 0;
690  print '<div class="warning">';
691  $langs->load("errors");
692  print $langs->trans("WarningProjectDraft");
693  print '</div>';
694  }
695 
696  print '<form action="'.$_SERVER['PHP_SELF'].'" method="POST">';
697  print '<input type="hidden" name="token" value="'.newToken().'">';
698  print '<input type="hidden" name="action" value="createtask">';
699  print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
700  if (!empty($object->id)) {
701  print '<input type="hidden" name="id" value="'.$object->id.'">';
702  }
703 
704  print dol_get_fiche_head('');
705 
706  print '<table class="border centpercent">';
707 
708  $defaultref = '';
709  $obj = empty($conf->global->PROJECT_TASK_ADDON) ? 'mod_task_simple' : $conf->global->PROJECT_TASK_ADDON;
710  if (!empty($conf->global->PROJECT_TASK_ADDON) && is_readable(DOL_DOCUMENT_ROOT."/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.".php")) {
711  require_once DOL_DOCUMENT_ROOT."/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.'.php';
712  $modTask = new $obj;
713  $defaultref = $modTask->getNextValue($object->thirdparty, null);
714  }
715 
716  if (is_numeric($defaultref) && $defaultref <= 0) {
717  $defaultref = '';
718  }
719 
720  // Ref
721  print '<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("Ref").'</span></td><td>';
722  if (empty($duplicate_code_error)) {
723  print (GETPOSTISSET("ref") ? GETPOST("ref", 'alpha') : $defaultref);
724  } else {
725  print $defaultref;
726  }
727  print '<input type="hidden" name="taskref" value="'.(GETPOSTISSET("ref") ? GETPOST("ref", 'alpha') : $defaultref).'">';
728  print '</td></tr>';
729 
730  // Label
731  print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td><td>';
732  print '<input type="text" name="label" autofocus class="minwidth500 maxwidthonsmartphone" value="'.$label.'">';
733  print '</td></tr>';
734 
735  // Project
736  print '<tr><td class="fieldrequired">'.$langs->trans("ChildOfProjectTask").'</td><td>';
737  print img_picto('', 'project');
738  if ($projectoktoentertime) {
739  $formother->selectProjectTasks(GETPOST('task_parent'), empty($projectid) ? $object->id : $projectid, 'task_parent', 0, 0, 1, 1, 0, '0,1', 'maxwidth500 widthcentpercentminusxx');
740  } else {
741  $formother->selectProjectTasks(GETPOST('task_parent'), empty($projectid) ? $object->id : $projectid, 'task_parent', 0, 0, 1, 1, 0, '', 'maxwidth500 widthcentpercentminusxx');
742  }
743  print '</td></tr>';
744 
745  $contactsofproject = (empty($object->id) ? '' : $object->getListContactId('internal'));
746 
747  // Assigned to
748  print '<tr><td>'.$langs->trans("AffectedTo").'</td><td>';
749  if (is_array($contactsofproject) && count($contactsofproject)) {
750  print $form->select_dolusers($user->id, 'userid', 0, '', 0, '', $contactsofproject, 0, 0, 0, '', 0, '', 'maxwidth300');
751  } else {
752  if ($projectid > 0 || $object->id > 0) {
753  print '<span class="opacitymedium">'.$langs->trans("NoUserAssignedToTheProject").'</span>';
754  } else {
755  print $form->select_dolusers($user->id, 'userid', 0, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300');
756  }
757  }
758  print '</td></tr>';
759 
760  // Date start task
761  print '<tr><td>'.$langs->trans("DateStart").'</td><td>';
762  print $form->selectDate((!empty($date_start) ? $date_start : ''), 'dateo', 1, 1, 0, '', 1, 1);
763  print '</td></tr>';
764 
765  // Date end task
766  print '<tr><td>'.$langs->trans("DateEnd").'</td><td>';
767  print $form->selectDate((!empty($date_end) ? $date_end : -1), 'datee', -1, 1, 0, '', 1, 1);
768  print '</td></tr>';
769 
770  // Planned workload
771  print '<tr><td>'.$langs->trans("PlannedWorkload").'</td><td>';
772  print $form->select_duration('planned_workload', !empty($planned_workload) ? $planned_workload : 0, 0, 'text');
773  print '</td></tr>';
774 
775  // Progress
776  print '<tr><td>'.$langs->trans("ProgressDeclared").'</td><td colspan="3">';
777  print $formother->select_percent($progress, 'progress', 0, 5, 0, 100, 1);
778  print '</td></tr>';
779 
780  // Description
781  print '<tr><td class="tdtop">'.$langs->trans("Description").'</td>';
782  print '<td>';
783 
784  // WYSIWYG editor
785  include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
786  $cked_enabled = (!empty($conf->global->FCKEDITOR_ENABLE_SOCIETE) ? $conf->global->FCKEDITOR_ENABLE_SOCIETE : 0);
787  if (!empty($conf->global->MAIN_INPUT_DESC_HEIGHT)) {
788  $nbrows = $conf->global->MAIN_INPUT_DESC_HEIGHT;
789  }
790  $doleditor = new DolEditor('description', $object->description, '', 80, 'dolibarr_details', '', false, true, $cked_enabled, $nbrows);
791  print $doleditor->Create();
792 
793  print '</td></tr>';
794 
795  print '<tr><td>'.$langs->trans("Budget").'</td>';
796  print '<td><input size="5" type="text" name="budget_amount" value="'.dol_escape_htmltag(GETPOSTISSET('budget_amount') ? GETPOST('budget_amount') : '').'"></td>';
797  print '</tr>';
798 
799  // Other options
800  $parameters = array();
801  $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $taskstatic, $action); // Note that $action and $object may have been modified by hook
802  print $hookmanager->resPrint;
803 
804  if (empty($reshook) && !empty($extrafields->attributes[$taskstatic->table_element]['label'])) {
805  print $taskstatic->showOptionals($extrafields, 'edit'); // Do not use $object here that is object of project but use $taskstatic
806  }
807 
808  print '</table>';
809 
810  print dol_get_fiche_end();
811 
812  print $form->buttonsSaveCancel("Add");
813 
814  print '</form>';
815 } elseif ($id > 0 || !empty($ref)) {
816  $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
817 
818  /*
819  * Projet card in view mode
820  */
821 
822  print '<br>';
823 
824  // Link to create task
825  $linktocreatetaskParam = array();
826  $linktocreatetaskUserRight = false;
827  if ($user->rights->projet->all->creer || $user->rights->projet->creer) {
828  if ($object->public || $userWrite > 0) {
829  $linktocreatetaskUserRight = true;
830  } else {
831  $linktocreatetaskParam['attr']['title'] = $langs->trans("NotOwnerOfProject");
832  }
833  }
834 
835  $linktocreatetask = dolGetButtonTitle($langs->trans('AddTask'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/projet/tasks.php?action=create'.$param.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$object->id), '', $linktocreatetaskUserRight, $linktocreatetaskParam);
836 
837  print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'">';
838  print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
839  print '<input type="hidden" name="token" value="'.newToken().'">';
840  print '<input type="hidden" name="action" value="list">';
841  print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
842  print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
843  print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
844  print '<input type="hidden" name="page" value="'.$page.'">';
845  print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
846 
847  $title = $langs->trans("ListOfTasks");
848  $linktotasks = dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/projet/tasks.php?id='.$object->id, '', 1, array('morecss'=>'reposition btnTitleSelected'));
849  $linktotasks .= dolGetButtonTitle($langs->trans('ViewGantt'), '', 'fa fa-stream imgforviewmode', DOL_URL_ROOT.'/projet/ganttview.php?id='.$object->id.'&withproject=1', '', 1, array('morecss'=>'reposition marginleftonly'));
850 
851  //print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, $linktotasks, $num, $totalnboflines, 'generic', 0, '', '', 0, 1);
852  print load_fiche_titre($title, $linktotasks.' &nbsp; '.$linktocreatetask, 'projecttask');
853 
854  // Get list of tasks in tasksarray and taskarrayfiltered
855  // We need all tasks (even not limited to a user because a task to user can have a parent that is not affected to him).
856  $filteronthirdpartyid = $socid;
857  $tasksarray = $taskstatic->getTasksArray(0, 0, $object->id, $filteronthirdpartyid, 0, '', -1, $morewherefilter, 0, 0, $extrafields, 1, $search_array_options);
858 
859  // We load also tasks limited to a particular user
860  $tmpuser = new User($db);
861  if ($search_user_id > 0) {
862  $tmpuser->fetch($search_user_id);
863  }
864 
865  $tasksrole = ($tmpuser->id > 0 ? $taskstatic->getUserRolesForProjectsOrTasks(null, $tmpuser, $object->id, 0) : '');
866  //var_dump($tasksarray);
867  //var_dump($tasksrole);
868 
869  if (!empty($conf->use_javascript_ajax)) {
870  include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
871  }
872 
873  // Filter on categories
874  $moreforfilter = '';
875  if (count($tasksarray) > 0) {
876  $moreforfilter .= '<div class="divsearchfield">';
877  $moreforfilter .= img_picto('', 'user', 'class="pictofixedwidth"');
878  $moreforfilter .= $form->select_dolusers($tmpuser->id > 0 ? $tmpuser->id : '', 'search_user_id', $langs->trans("TasksAssignedTo"), null, 0, '', '');
879  $moreforfilter .= '</div>';
880  }
881  if ($moreforfilter) {
882  print '<div class="liste_titre liste_titre_bydiv centpercent">';
883  print $moreforfilter;
884  print '</div>';
885  }
886 
887  print '<div class="div-table-responsive">';
888  print '<table id="tablelines" class="tagtable nobottom liste'.($moreforfilter ? " listwithfilterbefore" : "").'">';
889 
890  // Fields title search
891  print '<tr class="liste_titre_filter">';
892 
893  if (!empty($arrayfields['t.ref']['checked'])) {
894  print '<td class="liste_titre">';
895  print '<input class="flat searchstring maxwidth50" type="text" name="search_taskref" value="'.dol_escape_htmltag($search_taskref).'">';
896  print '</td>';
897  }
898 
899  if (!empty($arrayfields['t.label']['checked'])) {
900  print '<td class="liste_titre">';
901  print '<input class="flat searchstring maxwidth100" type="text" name="search_tasklabel" value="'.dol_escape_htmltag($search_tasklabel).'">';
902  print '</td>';
903  }
904 
905  if (!empty($arrayfields['t.description']['checked'])) {
906  print '<td class="liste_titre">';
907  print '<input class="flat searchstring maxwidth100" type="text" name="search_taskdescription" value="'.dol_escape_htmltag($search_taskdescription).'">';
908  print '</td>';
909  }
910 
911  if (!empty($arrayfields['t.dateo']['checked'])) {
912  print '<td class="liste_titre center">';
913  /*print '<span class="nowraponall"><input class="flat valignmiddle width20" type="text" maxlength="2" name="search_dtstartday" value="'.$search_dtstartday.'">';
914  print '<input class="flat valignmiddle width20" type="text" maxlength="2" name="search_dtstartmonth" value="'.$search_dtstartmonth.'"></span>';
915  print $formother->selectyear($search_dtstartyear ? $search_dtstartyear : -1, 'search_dtstartyear', 1, 20, 5);*/
916  print '<div class="nowrap">';
917  print $form->selectDate($search_date_start_start ? $search_date_start_start : -1, 'search_date_start_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
918  print '</div>';
919  print '<div class="nowrap">';
920  print $form->selectDate($search_date_start_end ? $search_date_start_end : -1, 'search_date_start_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
921  print '</div>';
922  print '</td>';
923  }
924 
925  if (!empty($arrayfields['t.datee']['checked'])) {
926  print '<td class="liste_titre center">';
927  /*print '<span class="nowraponall"><input class="flat valignmiddle width20" type="text" maxlength="2" name="search_dtendday" value="'.$search_dtendday.'">';
928  print '<input class="flat valignmiddle width20" type="text" maxlength="2" name="search_dtendmonth" value="'.$search_dtendmonth.'"></span>';
929  print $formother->selectyear($search_dtendyear ? $search_dtendyear : -1, 'search_dtendyear', 1, 20, 5);*/
930  print '<div class="nowrap">';
931  print $form->selectDate($search_date_end_start ? $search_date_end_start : -1, 'search_date_end_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
932  print '</div>';
933  print '<div class="nowrap">';
934  print $form->selectDate($search_date_end_end ? $search_date_end_end : -1, 'search_date_end_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
935  print '</div>';
936  print '</td>';
937  }
938 
939  if (!empty($arrayfields['t.planned_workload']['checked'])) {
940  print '<td class="liste_titre right">';
941  print '<input class="flat" type="text" size="4" name="search_planedworkload" value="'.$search_planedworkload.'">';
942  print '</td>';
943  }
944 
945  if (!empty($arrayfields['t.duration_effective']['checked'])) {
946  print '<td class="liste_titre right">';
947  print '<input class="flat" type="text" size="4" name="search_timespend" value="'.$search_timespend.'">';
948  print '</td>';
949  }
950 
951  if (!empty($arrayfields['t.progress_calculated']['checked'])) {
952  print '<td class="liste_titre right">';
953  print '<input class="flat" type="text" size="4" name="search_progresscalc" value="'.$search_progresscalc.'">';
954  print '</td>';
955  }
956 
957  if (!empty($arrayfields['t.progress']['checked'])) {
958  print '<td class="liste_titre right">';
959  print '<input class="flat" type="text" size="4" name="search_progressdeclare" value="'.$search_progressdeclare.'">';
960  print '</td>';
961  }
962 
963  // progress resume not searchable
964  print '<td class="liste_titre right"></td>';
965 
966  if ($object->usage_bill_time) {
967  if (!empty($arrayfields['t.tobill']['checked'])) {
968  print '<td class="liste_titre right">';
969  print '</td>';
970  }
971 
972  if (!empty($arrayfields['t.billed']['checked'])) {
973  print '<td class="liste_titre right">';
974  print '</td>';
975  }
976  }
977  // Contacts of task, disabled because available by default jsut after
978  /*
979  if (!empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST)) {
980  print '<td class="liste_titre"></td>';
981  }
982  */
983 
984  if (!empty($arrayfields['t.budget_amount']['checked'])) {
985  print '<td class="liste_titre center">';
986  print '<input type="text" class="flat" name="search_task_budget_amount" value="'.$search_task_budget_amount.'" size="4">';
987  print '</td>';
988  }
989 
990  if (!empty($arrayfields['c.assigned']['checked'])) {
991  print '<td class="liste_titre right">';
992  print '</td>';
993  }
994 
995  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
996 
997  // Action column
998  print '<td class="liste_titre maxwidthsearch">';
999  $searchpicto = $form->showFilterButtons();
1000  print $searchpicto;
1001  print '</td>';
1002  print "</tr>\n";
1003 
1004  print '<tr class="liste_titre nodrag nodrop">';
1005  // print '<td>'.$langs->trans("Project").'</td>';
1006  if (!empty($arrayfields['t.ref']['checked'])) {
1007  print_liste_field_titre($arrayfields['t.ref']['label'], $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, '');
1008  }
1009  if (!empty($arrayfields['t.label']['checked'])) {
1010  print_liste_field_titre($arrayfields['t.label']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, '');
1011  }
1012  if (!empty($arrayfields['t.description']['checked'])) {
1013  print_liste_field_titre($arrayfields['t.description']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, '');
1014  }
1015  if (!empty($arrayfields['t.dateo']['checked'])) {
1016  print_liste_field_titre($arrayfields['t.dateo']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ');
1017  }
1018  if (!empty($arrayfields['t.datee']['checked'])) {
1019  print_liste_field_titre($arrayfields['t.datee']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ');
1020  }
1021  if (!empty($arrayfields['t.planned_workload']['checked'])) {
1022  print_liste_field_titre($arrayfields['t.planned_workload']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ', '', 1);
1023  }
1024  if (!empty($arrayfields['t.duration_effective']['checked'])) {
1025  print_liste_field_titre($arrayfields['t.duration_effective']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ', '', 1);
1026  }
1027  if (!empty($arrayfields['t.progress_calculated']['checked'])) {
1028  print_liste_field_titre($arrayfields['t.progress_calculated']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ', '', 1);
1029  }
1030  if (!empty($arrayfields['t.progress']['checked'])) {
1031  print_liste_field_titre($arrayfields['t.progress']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ', '', 1);
1032  }
1033  if (!empty($arrayfields['t.progress_summary']['checked'])) {
1034  print_liste_field_titre($arrayfields['t.progress_summary']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ', '', 1);
1035  }
1036  if ($object->usage_bill_time) {
1037  if (!empty($arrayfields['t.tobill']['checked'])) {
1038  print_liste_field_titre($arrayfields['t.tobill']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ');
1039  }
1040  if (!empty($arrayfields['t.billed']['checked'])) {
1041  print_liste_field_titre($arrayfields['t.billed']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ');
1042  }
1043  }
1044  // Contacts of task, disabled because available by default jsut after
1045  /*
1046  if (!empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST)) {
1047  print_liste_field_titre("TaskRessourceLinks", $_SERVER["PHP_SELF"], '', '', $param, $sortfield, $sortorder);
1048  }
1049  */
1050 
1051  if (!empty($arrayfields['t.budget_amount']['checked'])) {
1052  print_liste_field_titre($arrayfields['t.budget_amount']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'center ');
1053  }
1054 
1055  if (!empty($arrayfields['c.assigned']['checked'])) {
1056  print_liste_field_titre($arrayfields['c.assigned']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ', '');
1057  }
1058  // Extra fields
1059  $disablesortlink = 1;
1060  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
1061  // Hook fields
1062  $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder);
1063  $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook
1064  print $hookmanager->resPrint;
1065  print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
1066  print "</tr>\n";
1067 
1068  $nboftaskshown = 0;
1069  if (count($tasksarray) > 0) {
1070  // Show all lines in taskarray (recursive function to go down on tree)
1071  $j = 0; $level = 0;
1072  $nboftaskshown = projectLinesa($j, 0, $tasksarray, $level, true, 0, $tasksrole, $object->id, 1, $object->id, $filterprogresscalc, ($object->usage_bill_time ? 1 : 0), $arrayfields);
1073  } else {
1074  $colspan = 10;
1075  if ($object->usage_bill_time) {
1076  $colspan += 2;
1077  }
1078  print '<tr class="oddeven nobottom"><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoTasks").'</span></td></tr>';
1079  }
1080 
1081  print "</table>";
1082  print '</div>';
1083 
1084  print '</form>';
1085 
1086 
1087  // Test if database is clean. If not we clean it.
1088  //print 'mode='.$_REQUEST["mode"].' $nboftaskshown='.$nboftaskshown.' count($tasksarray)='.count($tasksarray).' count($tasksrole)='.count($tasksrole).'<br>';
1089  if (!empty($user->rights->projet->all->lire)) { // We make test to clean only if user has permission to see all (test may report false positive otherwise)
1090  if ($search_user_id == $user->id) {
1091  if ($nboftaskshown < count($tasksrole)) {
1092  include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
1093  cleanCorruptedTree($db, 'projet_task', 'fk_task_parent');
1094  }
1095  } else {
1096  if ($nboftaskshown < count($tasksarray) && !GETPOST('search_user_id', 'int')) {
1097  include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
1098  cleanCorruptedTree($db, 'projet_task', 'fk_task_parent');
1099  }
1100  }
1101  }
1102 }
1103 
1104 // End of page
1105 llxFooter();
1106 $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 a WYSIWYG editor.
Class to manage standard extra fields.
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.
const STATUS_CLOSED
Closed status.
const STATUS_DRAFT
Draft status.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage tasks.
Definition: task.class.php:38
Class to manage Dolibarr users.
Definition: user.class.php:45
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
dolSqlDateFilter($datefield, $day_date, $month_date, $year_date, $excludefirstand=0, $gm=false)
Generate a SQL string to make a filter into a range (for second of date until last second of date).
Definition: date.lib.php:358
cleanCorruptedTree($db, $tabletocleantree, $fieldfkparent)
Clean corrupted tree (orphelins linked to a not existing parent), record linked to themself and child...
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.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
load_fiche_titre($titre, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='')
Show tabs of a record.
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
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.
natural_search($fields, $value, $mode=0, $nofirstand=0)
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
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_now($mode='auto')
Return date for now.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by second index function, which produces ascending (default) or descending output...
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
isModEnabled($module)
Is Dolibarr module enabled.
projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$taskrole, $projectsListId='', $addordertick=0, $projectidfortotallink=0, $filterprogresscalc='', $showbilltime=0, $arrayfields=array())
Show task lines with a particular parent.
project_prepare_head(Project $project, $moreparam='')
Prepare array with list of tabs.
Definition: project.lib.php:38
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.