dolibarr  17.0.4
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->entity = $object->entity; // Task have the same entity of project
340  $task->ref = $taskref;
341  $task->label = $label;
342  $task->description = $description;
343  $task->planned_workload = $planned_workload;
344  $task->fk_task_parent = $task_parent;
345  $task->date_c = dol_now();
346  $task->date_start = $date_start;
347  $task->date_end = $date_end;
348  $task->progress = $progress;
349  $task->budget_amount = $budget_amount;
350 
351  // Fill array 'array_options' with data from add form
352  $ret = $extrafields->setOptionalsFromPost(null, $task);
353 
354  $taskid = $task->create($user);
355 
356  if ($taskid > 0) {
357  $result = $task->add_contact(GETPOST("userid", 'int'), 'TASKEXECUTIVE', 'internal');
358  } else {
359  if ($db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
360  $langs->load("projects");
361  setEventMessages($langs->trans('NewTaskRefSuggested'), '', 'warnings');
362  $duplicate_code_error = true;
363  } else {
364  setEventMessages($task->error, $task->errors, 'errors');
365  }
366  $action = 'create';
367  $error++;
368  }
369  }
370 
371  if (!$error) {
372  if (!empty($backtopage)) {
373  header("Location: ".$backtopage);
374  exit;
375  } elseif (empty($projectid)) {
376  header("Location: ".DOL_URL_ROOT.'/projet/tasks/list.php'.(empty($mode) ? '' : '?mode='.$mode));
377  exit;
378  }
379  $id = $projectid;
380  }
381  } else {
382  if (!empty($backtopage)) {
383  header("Location: ".$backtopage);
384  exit;
385  } elseif (empty($id)) {
386  // We go back on task list
387  header("Location: ".DOL_URL_ROOT.'/projet/tasks/list.php'.(empty($mode) ? '' : '?mode='.$mode));
388  exit;
389  }
390  }
391 }
392 
393 
394 /*
395  * View
396  */
397 
398 $now = dol_now();
399 $form = new Form($db);
400 $formother = new FormOther($db);
401 $socstatic = new Societe($db);
402 $projectstatic = new Project($db);
403 $taskstatic = new Task($db);
404 $userstatic = new User($db);
405 
406 $title = $langs->trans("Tasks").' - '.$object->ref.' '.$object->name;
407 if (!empty($conf->global->MAIN_HTML_TITLE) && preg_match('/projectnameonly/', $conf->global->MAIN_HTML_TITLE) && $object->name) {
408  $title = $object->ref.' '.$object->name.' - '.$langs->trans("Tasks");
409 }
410 if ($action == 'create') {
411  $title = $langs->trans("NewTask");
412 }
413 $help_url = "EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos";
414 
415 llxHeader("", $title, $help_url);
416 
417 
418 if ($id > 0 || !empty($ref)) {
419  $result = $object->fetch($id, $ref);
420  if ($result < 0) {
421  setEventMessages(null, $object->errors, 'errors');
422  }
423  $result = $object->fetch_thirdparty();
424  if ($result < 0) {
425  setEventMessages(null, $object->errors, 'errors');
426  }
427  $result = $object->fetch_optionals();
428  if ($result < 0) {
429  setEventMessages(null, $object->errors, 'errors');
430  }
431 
432 
433  // To verify role of users
434  //$userAccess = $object->restrictedProjectArea($user,'read');
435  $userWrite = $object->restrictedProjectArea($user, 'write');
436  //$userDelete = $object->restrictedProjectArea($user,'delete');
437  //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete;
438 
439 
440  $tab = (GETPOSTISSET('tab') ? GETPOST('tab') : 'tasks');
441 
442  $head = project_prepare_head($object);
443  print dol_get_fiche_head($head, $tab, $langs->trans("Project"), -1, ($object->public ? 'projectpub' : 'project'));
444 
445  $param = '&id='.$object->id;
446  if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
447  $param .= '&contextpage='.urlencode($contextpage);
448  }
449  if ($search_user_id) {
450  $param .= '&search_user_id='.urlencode($search_user_id);
451  }
452  if ($search_taskref) {
453  $param .= '&search_taskref='.urlencode($search_taskref);
454  }
455  if ($search_tasklabel) {
456  $param .= '&search_tasklabel='.urlencode($search_tasklabel);
457  }
458  if ($search_taskdescription) {
459  $param .= '&search_taskdescription='.urlencode($search_taskdescription);
460  }
461  if ($search_dtstartday) {
462  $param .= '&search_dtstartday='.urlencode($search_dtstartday);
463  }
464  if ($search_dtstartmonth) {
465  $param .= '&search_dtstartmonth='.urlencode($search_dtstartmonth);
466  }
467  if ($search_dtstartyear) {
468  $param .= '&search_dtstartyear='.urlencode($search_dtstartyear);
469  }
470  if ($search_dtendday) {
471  $param .= '&search_dtendday='.urlencode($search_dtendday);
472  }
473  if ($search_dtendmonth) {
474  $param .= '&search_dtendmonth='.urlencode($search_dtendmonth);
475  }
476  if ($search_dtendyear) {
477  $param .= '&search_dtendyear='.urlencode($search_dtendyear);
478  }
479  if ($search_date_start_startmonth) {
480  $param .= '&search_date_start_startmonth='.urlencode($search_date_start_startmonth);
481  }
482  if ($search_date_start_startyear) {
483  $param .= '&search_date_start_startyear='.urlencode($search_date_start_startyear);
484  }
485  if ($search_date_start_startday) {
486  $param .= '&search_date_start_startday='.urlencode($search_date_start_startday);
487  }
488  if ($search_date_start_start) {
489  $param .= '&search_date_start_start='.urlencode($search_date_start_start);
490  }
491  if ($search_date_start_endmonth) {
492  $param .= '&search_date_start_endmonth='.urlencode($search_date_start_endmonth);
493  }
494  if ($search_date_start_endyear) {
495  $param .= '&search_date_start_endyear='.urlencode($search_date_start_endyear);
496  }
497  if ($search_date_start_endday) {
498  $param .= '&search_date_start_endday='.urlencode($search_date_start_endday);
499  }
500  if ($search_date_start_end) {
501  $param .= '&search_date_start_end='.urlencode($search_date_start_end);
502  }
503  if ($search_date_end_startmonth) {
504  $param .= '&search_date_end_startmonth='.urlencode($search_date_end_startmonth);
505  }
506  if ($search_date_end_startyear) {
507  $param .= '&search_date_end_startyear='.urlencode($search_date_end_startyear);
508  }
509  if ($search_date_end_startday) {
510  $param .= '&search_date_end_startday='.urlencode($search_date_end_startday);
511  }
512  if ($search_date_end_start) {
513  $param .= '&search_date_end_start='.urlencode($search_date_end_start);
514  }
515  if ($search_date_end_endmonth) {
516  $param .= '&search_date_end_endmonth='.urlencode($search_date_end_endmonth);
517  }
518  if ($search_date_end_endyear) {
519  $param .= '&search_date_end_endyear='.urlencode($search_date_end_endyear);
520  }
521  if ($search_date_end_endday) {
522  $param .= '&search_date_end_endday='.urlencode($search_date_end_endday);
523  }
524  if ($search_date_end_end) {
525  $param .= '&search_date_end_end=' . urlencode($search_date_end_end);
526  }
527  if ($search_planedworkload) {
528  $param .= '&search_planedworkload='.urlencode($search_planedworkload);
529  }
530  if ($search_timespend) {
531  $param .= '&search_timespend='.urlencode($search_timespend);
532  }
533  if ($search_progresscalc) {
534  $param .= '&search_progresscalc='.urlencode($search_progresscalc);
535  }
536  if ($search_progressdeclare) {
537  $param .= '&search_progressdeclare='.urlencode($search_progressdeclare);
538  }
539  if ($search_task_budget_amount) {
540  $param .= '&search_task_budget_amount='.urlencode($search_task_budget_amount);
541  }
542  if ($optioncss != '') {
543  $param .= '&optioncss='.urlencode($optioncss);
544  }
545  // Add $param from extra fields
546  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
547 
548  // Project card
549 
550  $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
551 
552  $morehtmlref = '<div class="refidno">';
553  // Title
554  $morehtmlref .= $object->title;
555  // Thirdparty
556  if (!empty($object->thirdparty->id) && $object->thirdparty->id > 0) {
557  $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1, 'project');
558  }
559  $morehtmlref .= '</div>';
560 
561  // Define a complementary filter for search of next/prev ref.
562  if (empty($user->rights->projet->all->lire)) {
563  $objectsListId = $object->getProjectsAuthorizedForUser($user, 0, 0);
564  $object->next_prev_filter = " rowid IN (".$db->sanitize(count($objectsListId) ?join(',', array_keys($objectsListId)) : '0').")";
565  }
566 
567  dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
568 
569  print '<div class="fichecenter">';
570  print '<div class="fichehalfleft">';
571  print '<div class="underbanner clearboth"></div>';
572 
573  print '<table class="border tableforfield centpercent">';
574 
575  // Usage
576  if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES) || empty($conf->global->PROJECT_HIDE_TASKS) || isModEnabled('eventorganization')) {
577  print '<tr><td class="tdtop">';
578  print $langs->trans("Usage");
579  print '</td>';
580  print '<td>';
581  if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) {
582  print '<input type="checkbox" disabled name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_opportunity ? ' checked="checked"' : '')).'"> ';
583  $htmltext = $langs->trans("ProjectFollowOpportunity");
584  print $form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext);
585  print '<br>';
586  }
587  if (empty($conf->global->PROJECT_HIDE_TASKS)) {
588  print '<input type="checkbox" disabled name="usage_task"'.(GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_task ? ' checked="checked"' : '')).'"> ';
589  $htmltext = $langs->trans("ProjectFollowTasks");
590  print $form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext);
591  print '<br>';
592  }
593  if (empty($conf->global->PROJECT_HIDE_TASKS) && !empty($conf->global->PROJECT_BILL_TIME_SPENT)) {
594  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"' : '')).'"> ';
595  $htmltext = $langs->trans("ProjectBillTimeDescription");
596  print $form->textwithpicto($langs->trans("BillTime"), $htmltext);
597  print '<br>';
598  }
599  if (isModEnabled('eventorganization')) {
600  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"' : '')).'"> ';
601  $htmltext = $langs->trans("EventOrganizationDescriptionLong");
602  print $form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext);
603  }
604  print '</td></tr>';
605  }
606 
607  // Visibility
608  print '<tr><td class="titlefield">'.$langs->trans("Visibility").'</td><td>';
609  if ($object->public) {
610  print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
611  print $langs->trans('SharedProject');
612  } else {
613  print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
614  print $langs->trans('PrivateProject');
615  }
616  print '</td></tr>';
617 
618  // Budget
619  print '<tr><td>'.$langs->trans("Budget").'</td><td>';
620  if (!is_null($object->budget_amount) && strcmp($object->budget_amount, '')) {
621  print '<span class="amount">'.price($object->budget_amount, '', $langs, 1, 0, 0, $conf->currency).'</span>';
622  }
623  print '</td></tr>';
624 
625  // Date start - end project
626  print '<tr><td>'.$langs->trans("Dates").'</td><td>';
627  $start = dol_print_date($object->date_start, 'day');
628  print ($start ? $start : '?');
629  $end = dol_print_date($object->date_end, 'day');
630  print ' - ';
631  print ($end ? $end : '?');
632  if ($object->hasDelay()) {
633  print img_warning("Late");
634  }
635  print '</td></tr>';
636 
637  // Other attributes
638  $cols = 2;
639  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
640 
641  print '</table>';
642 
643  print '</div>';
644  print '<div class="fichehalfright">';
645  print '<div class="underbanner clearboth"></div>';
646 
647  print '<table class="border tableforfield centpercent">';
648 
649  // Description
650  print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>';
651  print dol_htmlentitiesbr($object->description);
652  print '</td></tr>';
653 
654  // Categories
655  if (isModEnabled('categorie')) {
656  print '<tr><td class="valignmiddle">'.$langs->trans("Categories").'</td><td>';
657  print $form->showCategories($object->id, Categorie::TYPE_PROJECT, 1);
658  print "</td></tr>";
659  }
660 
661  print '</table>';
662 
663  print '</div>';
664  print '</div>';
665 
666  print '<div class="clearboth"></div>';
667 
668 
669  print dol_get_fiche_end();
670 }
671 
672 
673 if ($action == 'create' && $user->rights->projet->creer && (empty($object->thirdparty->id) || $userWrite > 0)) {
674  if ($id > 0 || !empty($ref)) {
675  print '<br>';
676  }
677 
678  print load_fiche_titre($langs->trans("NewTask"), '', 'projecttask');
679 
680  $projectoktoentertime = 1;
681  if ($object->id > 0 && $object->statut == Project::STATUS_CLOSED) {
682  $projectoktoentertime = 0;
683  print '<div class="warning">';
684  $langs->load("errors");
685  print $langs->trans("WarningProjectClosed");
686  print '</div>';
687  }
688 
689  if ($object->id > 0 && $object->statut == Project::STATUS_DRAFT) {
690  $projectoktoentertime = 0;
691  print '<div class="warning">';
692  $langs->load("errors");
693  print $langs->trans("WarningProjectDraft");
694  print '</div>';
695  }
696 
697  print '<form action="'.$_SERVER['PHP_SELF'].'" method="POST">';
698  print '<input type="hidden" name="token" value="'.newToken().'">';
699  print '<input type="hidden" name="action" value="createtask">';
700  print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
701  if (!empty($object->id)) {
702  print '<input type="hidden" name="id" value="'.$object->id.'">';
703  }
704 
705  print dol_get_fiche_head('');
706 
707  print '<table class="border centpercent">';
708 
709  $defaultref = '';
710  $obj = empty($conf->global->PROJECT_TASK_ADDON) ? 'mod_task_simple' : $conf->global->PROJECT_TASK_ADDON;
711  if (!empty($conf->global->PROJECT_TASK_ADDON) && is_readable(DOL_DOCUMENT_ROOT."/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.".php")) {
712  require_once DOL_DOCUMENT_ROOT."/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.'.php';
713  $modTask = new $obj;
714  $defaultref = $modTask->getNextValue($object->thirdparty, null);
715  }
716 
717  if (is_numeric($defaultref) && $defaultref <= 0) {
718  $defaultref = '';
719  }
720 
721  // Ref
722  print '<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("Ref").'</span></td><td>';
723  if (empty($duplicate_code_error)) {
724  print (GETPOSTISSET("ref") ? GETPOST("ref", 'alpha') : $defaultref);
725  } else {
726  print $defaultref;
727  }
728  print '<input type="hidden" name="taskref" value="'.(GETPOSTISSET("ref") ? GETPOST("ref", 'alpha') : $defaultref).'">';
729  print '</td></tr>';
730 
731  // Label
732  print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td><td>';
733  print '<input type="text" name="label" autofocus class="minwidth500 maxwidthonsmartphone" value="'.$label.'">';
734  print '</td></tr>';
735 
736  // Project
737  print '<tr><td class="fieldrequired">'.$langs->trans("ChildOfProjectTask").'</td><td>';
738  print img_picto('', 'project');
739  if ($projectoktoentertime) {
740  $formother->selectProjectTasks(GETPOST('task_parent'), empty($projectid) ? $object->id : $projectid, 'task_parent', 0, 0, 1, 1, 0, '0,1', 'maxwidth500 widthcentpercentminusxx');
741  } else {
742  $formother->selectProjectTasks(GETPOST('task_parent'), empty($projectid) ? $object->id : $projectid, 'task_parent', 0, 0, 1, 1, 0, '', 'maxwidth500 widthcentpercentminusxx');
743  }
744  print '</td></tr>';
745 
746  $contactsofproject = (empty($object->id) ? '' : $object->getListContactId('internal'));
747 
748  // Assigned to
749  print '<tr><td>'.$langs->trans("AffectedTo").'</td><td>';
750  if (is_array($contactsofproject) && count($contactsofproject)) {
751  print $form->select_dolusers($user->id, 'userid', 0, '', 0, '', $contactsofproject, 0, 0, 0, '', 0, '', 'maxwidth300');
752  } else {
753  if ($projectid > 0 || $object->id > 0) {
754  print '<span class="opacitymedium">'.$langs->trans("NoUserAssignedToTheProject").'</span>';
755  } else {
756  print $form->select_dolusers($user->id, 'userid', 0, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300');
757  }
758  }
759  print '</td></tr>';
760 
761  // Date start task
762  print '<tr><td>'.$langs->trans("DateStart").'</td><td>';
763  print $form->selectDate((!empty($date_start) ? $date_start : ''), 'dateo', 1, 1, 0, '', 1, 1);
764  print '</td></tr>';
765 
766  // Date end task
767  print '<tr><td>'.$langs->trans("DateEnd").'</td><td>';
768  print $form->selectDate((!empty($date_end) ? $date_end : -1), 'datee', -1, 1, 0, '', 1, 1);
769  print '</td></tr>';
770 
771  // Planned workload
772  print '<tr><td>'.$langs->trans("PlannedWorkload").'</td><td>';
773  print $form->select_duration('planned_workload', !empty($planned_workload) ? $planned_workload : 0, 0, 'text');
774  print '</td></tr>';
775 
776  // Progress
777  print '<tr><td>'.$langs->trans("ProgressDeclared").'</td><td colspan="3">';
778  print $formother->select_percent($progress, 'progress', 0, 5, 0, 100, 1);
779  print '</td></tr>';
780 
781  // Description
782  print '<tr><td class="tdtop">'.$langs->trans("Description").'</td>';
783  print '<td>';
784 
785  // WYSIWYG editor
786  include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
787  $cked_enabled = (!empty($conf->global->FCKEDITOR_ENABLE_SOCIETE) ? $conf->global->FCKEDITOR_ENABLE_SOCIETE : 0);
788  if (!empty($conf->global->MAIN_INPUT_DESC_HEIGHT)) {
789  $nbrows = $conf->global->MAIN_INPUT_DESC_HEIGHT;
790  }
791  $doleditor = new DolEditor('description', $object->description, '', 80, 'dolibarr_details', '', false, true, $cked_enabled, $nbrows);
792  print $doleditor->Create();
793 
794  print '</td></tr>';
795 
796  print '<tr><td>'.$langs->trans("Budget").'</td>';
797  print '<td><input size="5" type="text" name="budget_amount" value="'.dol_escape_htmltag(GETPOSTISSET('budget_amount') ? GETPOST('budget_amount') : '').'"></td>';
798  print '</tr>';
799 
800  // Other options
801  $parameters = array('arrayfields' => &$arrayfields);
802  $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $taskstatic, $action); // Note that $action and $object may have been modified by hook
803  print $hookmanager->resPrint;
804 
805  if (empty($reshook) && !empty($extrafields->attributes[$taskstatic->table_element]['label'])) {
806  print $taskstatic->showOptionals($extrafields, 'edit'); // Do not use $object here that is object of project but use $taskstatic
807  }
808 
809  print '</table>';
810 
811  print dol_get_fiche_end();
812 
813  print $form->buttonsSaveCancel("Add");
814 
815  print '</form>';
816 } elseif ($id > 0 || !empty($ref)) {
817  $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
818 
819  /*
820  * Projet card in view mode
821  */
822 
823  print '<br>';
824 
825  // Link to create task
826  $linktocreatetaskParam = array();
827  $linktocreatetaskUserRight = false;
828  if ($user->rights->projet->all->creer || $user->rights->projet->creer) {
829  if ($object->public || $userWrite > 0) {
830  $linktocreatetaskUserRight = true;
831  } else {
832  $linktocreatetaskParam['attr']['title'] = $langs->trans("NotOwnerOfProject");
833  }
834  }
835 
836  $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);
837 
838  print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'">';
839  print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
840  print '<input type="hidden" name="token" value="'.newToken().'">';
841  print '<input type="hidden" name="action" value="list">';
842  print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
843  print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
844  print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
845  print '<input type="hidden" name="page" value="'.$page.'">';
846  print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
847 
848  $title = $langs->trans("ListOfTasks");
849  $linktotasks = dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/projet/tasks.php?id='.$object->id, '', 1, array('morecss'=>'reposition btnTitleSelected'));
850  $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'));
851 
852  //print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, $linktotasks, $num, $totalnboflines, 'generic', 0, '', '', 0, 1);
853  print load_fiche_titre($title, $linktotasks.' &nbsp; '.$linktocreatetask, 'projecttask');
854 
855  // Get list of tasks in tasksarray and taskarrayfiltered
856  // 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).
857  $filteronthirdpartyid = $socid;
858  $tasksarray = $taskstatic->getTasksArray(0, 0, $object->id, $filteronthirdpartyid, 0, '', -1, $morewherefilter, 0, 0, $extrafields, 1, $search_array_options, 0, 1, $sortfield, $sortorder);
859 
860  // We load also tasks limited to a particular user
861  $tmpuser = new User($db);
862  if ($search_user_id > 0) {
863  $tmpuser->fetch($search_user_id);
864  }
865 
866  $tasksrole = ($tmpuser->id > 0 ? $taskstatic->getUserRolesForProjectsOrTasks(0, $tmpuser, $object->id, 0) : '');
867  //var_dump($tasksarray);
868  //var_dump($tasksrole);
869 
870  if (!empty($conf->use_javascript_ajax)) {
871  include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
872  }
873 
874  // Filter on categories
875  $moreforfilter = '';
876  if (count($tasksarray) > 0) {
877  $moreforfilter .= '<div class="divsearchfield">';
878  $moreforfilter .= img_picto('', 'user', 'class="pictofixedwidth"');
879  $moreforfilter .= $form->select_dolusers($tmpuser->id > 0 ? $tmpuser->id : '', 'search_user_id', $langs->trans("TasksAssignedTo"), null, 0, '', '');
880  $moreforfilter .= '</div>';
881  }
882  if ($moreforfilter) {
883  print '<div class="liste_titre liste_titre_bydiv centpercent">';
884  print $moreforfilter;
885  print '</div>';
886  }
887 
888  print '<div class="div-table-responsive">';
889  print '<table id="tablelines" class="tagtable nobottom liste'.($moreforfilter ? " listwithfilterbefore" : "").'">';
890 
891  // Fields title search
892  print '<tr class="liste_titre_filter">';
893 
894  if (!empty($arrayfields['t.ref']['checked'])) {
895  print '<td class="liste_titre">';
896  print '<input class="flat searchstring maxwidth50" type="text" name="search_taskref" value="'.dol_escape_htmltag($search_taskref).'">';
897  print '</td>';
898  }
899 
900  if (!empty($arrayfields['t.label']['checked'])) {
901  print '<td class="liste_titre">';
902  print '<input class="flat searchstring maxwidth100" type="text" name="search_tasklabel" value="'.dol_escape_htmltag($search_tasklabel).'">';
903  print '</td>';
904  }
905 
906  if (!empty($arrayfields['t.description']['checked'])) {
907  print '<td class="liste_titre">';
908  print '<input class="flat searchstring maxwidth100" type="text" name="search_taskdescription" value="'.dol_escape_htmltag($search_taskdescription).'">';
909  print '</td>';
910  }
911 
912  if (!empty($arrayfields['t.dateo']['checked'])) {
913  print '<td class="liste_titre center">';
914  /*print '<span class="nowraponall"><input class="flat valignmiddle width20" type="text" maxlength="2" name="search_dtstartday" value="'.$search_dtstartday.'">';
915  print '<input class="flat valignmiddle width20" type="text" maxlength="2" name="search_dtstartmonth" value="'.$search_dtstartmonth.'"></span>';
916  print $formother->selectyear($search_dtstartyear ? $search_dtstartyear : -1, 'search_dtstartyear', 1, 20, 5);*/
917  print '<div class="nowrap">';
918  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'));
919  print '</div>';
920  print '<div class="nowrap">';
921  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'));
922  print '</div>';
923  print '</td>';
924  }
925 
926  if (!empty($arrayfields['t.datee']['checked'])) {
927  print '<td class="liste_titre center">';
928  /*print '<span class="nowraponall"><input class="flat valignmiddle width20" type="text" maxlength="2" name="search_dtendday" value="'.$search_dtendday.'">';
929  print '<input class="flat valignmiddle width20" type="text" maxlength="2" name="search_dtendmonth" value="'.$search_dtendmonth.'"></span>';
930  print $formother->selectyear($search_dtendyear ? $search_dtendyear : -1, 'search_dtendyear', 1, 20, 5);*/
931  print '<div class="nowrap">';
932  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'));
933  print '</div>';
934  print '<div class="nowrap">';
935  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'));
936  print '</div>';
937  print '</td>';
938  }
939 
940  if (!empty($arrayfields['t.planned_workload']['checked'])) {
941  print '<td class="liste_titre right">';
942  print '<input class="flat" type="text" size="4" name="search_planedworkload" value="'.$search_planedworkload.'">';
943  print '</td>';
944  }
945 
946  if (!empty($arrayfields['t.duration_effective']['checked'])) {
947  print '<td class="liste_titre right">';
948  print '<input class="flat" type="text" size="4" name="search_timespend" value="'.$search_timespend.'">';
949  print '</td>';
950  }
951 
952  if (!empty($arrayfields['t.progress_calculated']['checked'])) {
953  print '<td class="liste_titre right">';
954  print '<input class="flat" type="text" size="4" name="search_progresscalc" value="'.$search_progresscalc.'">';
955  print '</td>';
956  }
957 
958  if (!empty($arrayfields['t.progress']['checked'])) {
959  print '<td class="liste_titre right">';
960  print '<input class="flat" type="text" size="4" name="search_progressdeclare" value="'.$search_progressdeclare.'">';
961  print '</td>';
962  }
963 
964  // progress resume not searchable
965  if (!empty($arrayfields['t.progress_summary']['checked'])) {
966  print '<td class="liste_titre right"></td>';
967  }
968 
969  if ($object->usage_bill_time) {
970  if (!empty($arrayfields['t.tobill']['checked'])) {
971  print '<td class="liste_titre right">';
972  print '</td>';
973  }
974 
975  if (!empty($arrayfields['t.billed']['checked'])) {
976  print '<td class="liste_titre right">';
977  print '</td>';
978  }
979  }
980  // Contacts of task, disabled because available by default jsut after
981  /*
982  if (!empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST)) {
983  print '<td class="liste_titre"></td>';
984  }
985  */
986 
987  if (!empty($arrayfields['t.budget_amount']['checked'])) {
988  print '<td class="liste_titre center">';
989  print '<input type="text" class="flat" name="search_task_budget_amount" value="'.$search_task_budget_amount.'" size="4">';
990  print '</td>';
991  }
992 
993  if (!empty($arrayfields['c.assigned']['checked'])) {
994  print '<td class="liste_titre right">';
995  print '</td>';
996  }
997 
998  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
999 
1000  // Action column
1001  print '<td class="liste_titre maxwidthsearch">';
1002  $searchpicto = $form->showFilterButtons();
1003  print $searchpicto;
1004  print '</td>';
1005  print "</tr>\n";
1006 
1007  print '<tr class="liste_titre nodrag nodrop">';
1008  // print '<td>'.$langs->trans("Project").'</td>';
1009  if (!empty($arrayfields['t.ref']['checked'])) {
1010  print_liste_field_titre($arrayfields['t.ref']['label'], $_SERVER["PHP_SELF"], 't.ref', '', $param, '', $sortfield, $sortorder, '');
1011  }
1012  if (!empty($arrayfields['t.label']['checked'])) {
1013  print_liste_field_titre($arrayfields['t.label']['label'], $_SERVER["PHP_SELF"], "t.label", '', $param, '', $sortfield, $sortorder, '');
1014  }
1015  if (!empty($arrayfields['t.description']['checked'])) {
1016  print_liste_field_titre($arrayfields['t.description']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, '');
1017  }
1018  if (!empty($arrayfields['t.dateo']['checked'])) {
1019  print_liste_field_titre($arrayfields['t.dateo']['label'], $_SERVER["PHP_SELF"], "t.dateo", '', $param, '', $sortfield, $sortorder, 'center ');
1020  }
1021  if (!empty($arrayfields['t.datee']['checked'])) {
1022  print_liste_field_titre($arrayfields['t.datee']['label'], $_SERVER["PHP_SELF"], "t.datee", '', $param, '', $sortfield, $sortorder, 'center ');
1023  }
1024  if (!empty($arrayfields['t.planned_workload']['checked'])) {
1025  print_liste_field_titre($arrayfields['t.planned_workload']['label'], $_SERVER["PHP_SELF"], "t.planned_workload", '', $param, '', $sortfield, $sortorder, 'right ', '', 1);
1026  }
1027  if (!empty($arrayfields['t.duration_effective']['checked'])) {
1028  print_liste_field_titre($arrayfields['t.duration_effective']['label'], $_SERVER["PHP_SELF"], "t.duration_effective", '', $param, '', $sortfield, $sortorder, 'right ', '', 1);
1029  }
1030  if (!empty($arrayfields['t.progress_calculated']['checked'])) {
1031  print_liste_field_titre($arrayfields['t.progress_calculated']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ', '', 1);
1032  }
1033  if (!empty($arrayfields['t.progress']['checked'])) {
1034  print_liste_field_titre($arrayfields['t.progress']['label'], $_SERVER["PHP_SELF"], "t.progress", '', $param, '', $sortfield, $sortorder, 'right ', '', 1);
1035  }
1036  if (!empty($arrayfields['t.progress_summary']['checked'])) {
1037  print_liste_field_titre($arrayfields['t.progress_summary']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ', '', 1);
1038  }
1039  if ($object->usage_bill_time) {
1040  if (!empty($arrayfields['t.tobill']['checked'])) {
1041  print_liste_field_titre($arrayfields['t.tobill']['label'], $_SERVER["PHP_SELF"], "t.tobill", '', $param, '', $sortfield, $sortorder, 'right ');
1042  }
1043  if (!empty($arrayfields['t.billed']['checked'])) {
1044  print_liste_field_titre($arrayfields['t.billed']['label'], $_SERVER["PHP_SELF"], "t.billed", '', $param, '', $sortfield, $sortorder, 'right ');
1045  }
1046  }
1047  // Contacts of task, disabled because available by default jsut after
1048  /*
1049  if (!empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST)) {
1050  print_liste_field_titre("TaskRessourceLinks", $_SERVER["PHP_SELF"], '', '', $param, $sortfield, $sortorder);
1051  }
1052  */
1053 
1054  if (!empty($arrayfields['t.budget_amount']['checked'])) {
1055  print_liste_field_titre($arrayfields['t.budget_amount']['label'], $_SERVER["PHP_SELF"], "t.budget_amount", "", $param, '', $sortfield, $sortorder, 'center ');
1056  }
1057 
1058  if (!empty($arrayfields['c.assigned']['checked'])) {
1059  print_liste_field_titre($arrayfields['c.assigned']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ', '');
1060  }
1061  // Extra fields
1062  $disablesortlink = 1;
1063  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
1064  // Hook fields
1065  $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder);
1066  $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook
1067  print $hookmanager->resPrint;
1068  print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
1069  print "</tr>\n";
1070 
1071  $nboftaskshown = 0;
1072  if (count($tasksarray) > 0) {
1073  // Show all lines in taskarray (recursive function to go down on tree)
1074  $j = 0; $level = 0;
1075  $nboftaskshown = projectLinesa($j, 0, $tasksarray, $level, true, 0, $tasksrole, $object->id, 1, $object->id, $filterprogresscalc, ($object->usage_bill_time ? 1 : 0), $arrayfields);
1076  } else {
1077  $colspan = count($arrayfields);
1078  if ($object->usage_bill_time) {
1079  $colspan += 2;
1080  }
1081  print '<tr class="oddeven"><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoTasks").'</span></td></tr>';
1082  }
1083 
1084  print "</table>";
1085  print '</div>';
1086 
1087  print '</form>';
1088 
1089 
1090  // Test if database is clean. If not we clean it.
1091  //print 'mode='.$_REQUEST["mode"].' $nboftaskshown='.$nboftaskshown.' count($tasksarray)='.count($tasksarray).' count($tasksrole)='.count($tasksrole).'<br>';
1092  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)
1093  if ($search_user_id == $user->id) {
1094  if ($nboftaskshown < count($tasksrole)) {
1095  include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
1096  cleanCorruptedTree($db, 'projet_task', 'fk_task_parent');
1097  }
1098  } else {
1099  if ($nboftaskshown < count($tasksarray) && !GETPOST('search_user_id', 'int')) {
1100  include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
1101  cleanCorruptedTree($db, 'projet_task', 'fk_task_parent');
1102  }
1103  }
1104  }
1105 }
1106 
1107 // End of page
1108 llxFooter();
1109 $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:47
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.
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
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.