dolibarr  19.0.0-dev
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 if (GETPOST('cancel', 'alpha')) {
187  $action = 'list';
188  $massaction = '';
189 }
190 if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
191  $massaction = '';
192 }
193 
194 $parameters = array('id'=>$id);
195 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
196 if ($reshook < 0) {
197  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
198 }
199 
200 if (empty($reshook)) {
201  // Selection of new fields
202  include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
203 
204  // Purge search criteria
205  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
206  $search_user_id = "";
207  $search_taskref = '';
208  $search_tasklabel = '';
209  $search_dtstartday = '';
210  $search_dtstartmonth = '';
211  $search_dtstartyear = '';
212  $search_dtendday = '';
213  $search_dtendmonth = '';
214  $search_dtendyear = '';
215  $search_planedworkload = '';
216  $search_timespend = '';
217  $search_progresscalc = '';
218  $search_progressdeclare = '';
219  $search_task_budget_amount = '';
220  $toselect = array();
221  $search_array_options = array();
222  $search_date_start_startmonth = "";
223  $search_date_start_startyear = "";
224  $search_date_start_startday = "";
225  $search_date_start_start = "";
226  $search_date_start_endmonth = "";
227  $search_date_start_endyear = "";
228  $search_date_start_endday = "";
229  $search_date_start_end = "";
230  $search_date_end_startmonth = "";
231  $search_date_end_startyear = "";
232  $search_date_end_startday = "";
233  $search_date_end_start = "";
234  $search_date_end_endmonth = "";
235  $search_date_end_endyear = "";
236  $search_date_end_endday = "";
237  $search_date_end_end = "";
238  }
239 
240  // Mass actions
241  $objectclass = 'Task';
242  $objectlabel = 'Tasks';
243  $permissiontoread = $user->hasRight('projet', 'lire');
244  $permissiontodelete = $user->hasRight('projet', 'supprimer');
245  $uploaddir = $conf->project->dir_output.'/tasks';
246  include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
247 }
248 
249 $morewherefilterarray = array();
250 
251 if (!empty($search_taskref)) {
252  $morewherefilterarray[] = natural_search('t.ref', $search_taskref, 0, 1);
253 }
254 
255 if (!empty($search_tasklabel)) {
256  $morewherefilterarray[] = natural_search('t.label', $search_tasklabel, 0, 1);
257 }
258 
259 $moresql = dolSqlDateFilter('t.dateo', $search_dtstartday, $search_dtstartmonth, $search_dtstartyear, 1);
260 if ($moresql) {
261  $morewherefilterarray[] = $moresql;
262 }
263 
264 $moresql = dolSqlDateFilter('t.datee', $search_dtendday, $search_dtendmonth, $search_dtendyear, 1);
265 if ($moresql) {
266  $morewherefilterarray[] = $moresql;
267 }
268 
269 if ($search_date_start_start) {
270  $morewherefilterarray[] = " t.dateo >= '".$db->idate($search_date_start_start)."'";
271 }
272 if ($search_date_start_end) {
273  $morewherefilterarray[] = " t.dateo <= '".$db->idate($search_date_start_end)."'";
274 }
275 
276 if ($search_date_end_start) {
277  $morewherefilterarray[] = " t.datee >= '".$db->idate($search_date_end_start)."'";
278 }
279 if ($search_date_end_end) {
280  $morewherefilterarray[] = " t.datee <= '".$db->idate($search_date_end_end)."'";
281 }
282 
283 if (!empty($search_planedworkload)) {
284  $morewherefilterarray[] = natural_search('t.planned_workload', $search_planedworkload, 1, 1);
285 }
286 
287 if (!empty($search_timespend)) {
288  $morewherefilterarray[] = natural_search('t.duration_effective', $search_timespend, 1, 1);
289 }
290 
291 if (!empty($search_progressdeclare)) {
292  $morewherefilterarray[] = natural_search('t.progress', $search_progressdeclare, 1, 1);
293 }
294 if (!empty($search_progresscalc)) {
295  $morewherefilterarray[] = '(planned_workload IS NULL OR planned_workload = 0 OR '.natural_search('ROUND(100 * duration_effective / planned_workload, 2)', $search_progresscalc, 1, 1).')';
296  //natural_search('round(100 * $line->duration_effective / $line->planned_workload,2)', $filterprogresscalc, 1, 1).' {return 1;} else {return 0;}';
297 }
298 if ($search_task_budget_amount) {
299  $morewherefilterarray[]= natural_search('t.budget_amount', $search_task_budget_amount, 1, 1);
300 }
301 //var_dump($morewherefilterarray);
302 
303 $morewherefilter = '';
304 if (count($morewherefilterarray) > 0) {
305  $morewherefilter = ' AND '.implode(' AND ', $morewherefilterarray);
306 }
307 
308 if ($action == 'createtask' && $user->rights->projet->creer) {
309  $error = 0;
310 
311  // If we use user timezone, we must change also view/list to use user timezone everywhere
312  $date_start = dol_mktime(GETPOST('dateohour', 'int'), GETPOST('dateomin', 'int'), 0, GETPOST('dateomonth', 'int'), GETPOST('dateoday', 'int'), GETPOST('dateoyear', 'int'));
313  $date_end = dol_mktime(GETPOST('dateehour', 'int'), GETPOST('dateemin', 'int'), 0, GETPOST('dateemonth', 'int'), GETPOST('dateeday', 'int'), GETPOST('dateeyear', 'int'));
314 
315  if (!$cancel) {
316  if (empty($taskref)) {
317  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Ref")), null, 'errors');
318  $action = 'create';
319  $error++;
320  }
321  if (empty($label)) {
322  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
323  $action = 'create';
324  $error++;
325  } elseif (!GETPOST('task_parent')) {
326  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("ChildOfProjectTask")), null, 'errors');
327  $action = 'create';
328  $error++;
329  }
330 
331  if (!$error) {
332  $tmparray = explode('_', GETPOST('task_parent'));
333  $projectid = $tmparray[0];
334  if (empty($projectid)) {
335  $projectid = $id; // If projectid is ''
336  }
337  $task_parent = $tmparray[1];
338  if (empty($task_parent)) {
339  $task_parent = 0; // If task_parent is ''
340  }
341 
342  $task = new Task($db);
343 
344  $task->fk_project = $projectid;
345  $task->entity = $object->entity; // Task have the same entity of project
346  $task->ref = $taskref;
347  $task->label = $label;
348  $task->description = $description;
349  $task->planned_workload = $planned_workload;
350  $task->fk_task_parent = $task_parent;
351  $task->date_c = dol_now();
352  $task->date_start = $date_start;
353  $task->date_end = $date_end;
354  $task->progress = $progress;
355  $task->budget_amount = $budget_amount;
356 
357  // Fill array 'array_options' with data from add form
358  $ret = $extrafields->setOptionalsFromPost(null, $task);
359 
360  $taskid = $task->create($user);
361 
362  if ($taskid > 0) {
363  $result = $task->add_contact(GETPOST("userid", 'int'), 'TASKEXECUTIVE', 'internal');
364  } else {
365  if ($db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
366  $langs->load("projects");
367  setEventMessages($langs->trans('NewTaskRefSuggested'), null, 'warnings');
368  $duplicate_code_error = true;
369  } else {
370  setEventMessages($task->error, $task->errors, 'errors');
371  }
372  $action = 'create';
373  $error++;
374  }
375  }
376 
377  if (!$error) {
378  if (!empty($backtopage)) {
379  header("Location: ".$backtopage);
380  exit;
381  } elseif (empty($projectid)) {
382  header("Location: ".DOL_URL_ROOT.'/projet/tasks/list.php'.(empty($mode) ? '' : '?mode='.$mode));
383  exit;
384  }
385  $id = $projectid;
386  }
387  } else {
388  if (!empty($backtopage)) {
389  header("Location: ".$backtopage);
390  exit;
391  } elseif (empty($id)) {
392  // We go back on task list
393  header("Location: ".DOL_URL_ROOT.'/projet/tasks/list.php'.(empty($mode) ? '' : '?mode='.$mode));
394  exit;
395  }
396  }
397 }
398 
399 
400 /*
401  * View
402  */
403 
404 $now = dol_now();
405 $form = new Form($db);
406 $formother = new FormOther($db);
407 $socstatic = new Societe($db);
408 $projectstatic = new Project($db);
409 $taskstatic = new Task($db);
410 $userstatic = new User($db);
411 
412 $title = $langs->trans("Tasks").' - '.$object->ref.' '.$object->name;
413 if (!empty($conf->global->MAIN_HTML_TITLE) && preg_match('/projectnameonly/', $conf->global->MAIN_HTML_TITLE) && $object->name) {
414  $title = $object->ref.' '.$object->name.' - '.$langs->trans("Tasks");
415 }
416 if ($action == 'create') {
417  $title = $langs->trans("NewTask");
418 }
419 $help_url = "EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos";
420 
421 llxHeader("", $title, $help_url);
422 
423 $arrayofselected = is_array($toselect) ? $toselect : array();
424 
425 if ($id > 0 || !empty($ref)) {
426  $result = $object->fetch($id, $ref);
427  if ($result < 0) {
428  setEventMessages(null, $object->errors, 'errors');
429  }
430  $result = $object->fetch_thirdparty();
431  if ($result < 0) {
432  setEventMessages(null, $object->errors, 'errors');
433  }
434  $result = $object->fetch_optionals();
435  if ($result < 0) {
436  setEventMessages(null, $object->errors, 'errors');
437  }
438 
439 
440  // To verify role of users
441  //$userAccess = $object->restrictedProjectArea($user,'read');
442  $userWrite = $object->restrictedProjectArea($user, 'write');
443  //$userDelete = $object->restrictedProjectArea($user,'delete');
444  //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete;
445 
446 
447  $tab = (GETPOSTISSET('tab') ? GETPOST('tab') : 'tasks');
448 
449  $head = project_prepare_head($object);
450  print dol_get_fiche_head($head, $tab, $langs->trans("Project"), -1, ($object->public ? 'projectpub' : 'project'));
451 
452  $param = '&id='.$object->id;
453  if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
454  $param .= '&contextpage='.urlencode($contextpage);
455  }
456  if ($search_user_id) {
457  $param .= '&search_user_id='.urlencode($search_user_id);
458  }
459  if ($search_taskref) {
460  $param .= '&search_taskref='.urlencode($search_taskref);
461  }
462  if ($search_tasklabel) {
463  $param .= '&search_tasklabel='.urlencode($search_tasklabel);
464  }
465  if ($search_taskdescription) {
466  $param .= '&search_taskdescription='.urlencode($search_taskdescription);
467  }
468  if ($search_dtstartday) {
469  $param .= '&search_dtstartday='.urlencode($search_dtstartday);
470  }
471  if ($search_dtstartmonth) {
472  $param .= '&search_dtstartmonth='.urlencode($search_dtstartmonth);
473  }
474  if ($search_dtstartyear) {
475  $param .= '&search_dtstartyear='.urlencode($search_dtstartyear);
476  }
477  if ($search_dtendday) {
478  $param .= '&search_dtendday='.urlencode($search_dtendday);
479  }
480  if ($search_dtendmonth) {
481  $param .= '&search_dtendmonth='.urlencode($search_dtendmonth);
482  }
483  if ($search_dtendyear) {
484  $param .= '&search_dtendyear='.urlencode($search_dtendyear);
485  }
486  if ($search_date_start_startmonth) {
487  $param .= '&search_date_start_startmonth='.urlencode($search_date_start_startmonth);
488  }
489  if ($search_date_start_startyear) {
490  $param .= '&search_date_start_startyear='.urlencode($search_date_start_startyear);
491  }
492  if ($search_date_start_startday) {
493  $param .= '&search_date_start_startday='.urlencode($search_date_start_startday);
494  }
495  if ($search_date_start_start) {
496  $param .= '&search_date_start_start='.urlencode($search_date_start_start);
497  }
498  if ($search_date_start_endmonth) {
499  $param .= '&search_date_start_endmonth='.urlencode($search_date_start_endmonth);
500  }
501  if ($search_date_start_endyear) {
502  $param .= '&search_date_start_endyear='.urlencode($search_date_start_endyear);
503  }
504  if ($search_date_start_endday) {
505  $param .= '&search_date_start_endday='.urlencode($search_date_start_endday);
506  }
507  if ($search_date_start_end) {
508  $param .= '&search_date_start_end='.urlencode($search_date_start_end);
509  }
510  if ($search_date_end_startmonth) {
511  $param .= '&search_date_end_startmonth='.urlencode($search_date_end_startmonth);
512  }
513  if ($search_date_end_startyear) {
514  $param .= '&search_date_end_startyear='.urlencode($search_date_end_startyear);
515  }
516  if ($search_date_end_startday) {
517  $param .= '&search_date_end_startday='.urlencode($search_date_end_startday);
518  }
519  if ($search_date_end_start) {
520  $param .= '&search_date_end_start='.urlencode($search_date_end_start);
521  }
522  if ($search_date_end_endmonth) {
523  $param .= '&search_date_end_endmonth='.urlencode($search_date_end_endmonth);
524  }
525  if ($search_date_end_endyear) {
526  $param .= '&search_date_end_endyear='.urlencode($search_date_end_endyear);
527  }
528  if ($search_date_end_endday) {
529  $param .= '&search_date_end_endday='.urlencode($search_date_end_endday);
530  }
531  if ($search_date_end_end) {
532  $param .= '&search_date_end_end=' . urlencode($search_date_end_end);
533  }
534  if ($search_planedworkload) {
535  $param .= '&search_planedworkload='.urlencode($search_planedworkload);
536  }
537  if ($search_timespend) {
538  $param .= '&search_timespend='.urlencode($search_timespend);
539  }
540  if ($search_progresscalc) {
541  $param .= '&search_progresscalc='.urlencode($search_progresscalc);
542  }
543  if ($search_progressdeclare) {
544  $param .= '&search_progressdeclare='.urlencode($search_progressdeclare);
545  }
546  if ($search_task_budget_amount) {
547  $param .= '&search_task_budget_amount='.urlencode($search_task_budget_amount);
548  }
549  if ($optioncss != '') {
550  $param .= '&optioncss='.urlencode($optioncss);
551  }
552  // Add $param from extra fields
553  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
554 
555  $arrayofmassactions = array();
556  if ($user->hasRight('projet', 'creer')) {
557  $arrayofmassactions['preclonetasks'] = img_picto('', 'clone', 'class="pictofixedwidth"').$langs->trans("Clone");
558  }
559  if ($permissiontodelete) {
560  $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
561  }
562  if (in_array($massaction, array('presend', 'predelete'))) {
563  $arrayofmassactions = array();
564  }
565  $massactionbutton = $form->selectMassAction('', $arrayofmassactions);
566 
567  // Project card
568 
569  $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
570 
571  $morehtmlref = '<div class="refidno">';
572  // Title
573  $morehtmlref .= $object->title;
574  // Thirdparty
575  if (!empty($object->thirdparty->id) && $object->thirdparty->id > 0) {
576  $morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1, 'project');
577  }
578  $morehtmlref .= '</div>';
579 
580  // Define a complementary filter for search of next/prev ref.
581  if (empty($user->rights->projet->all->lire)) {
582  $objectsListId = $object->getProjectsAuthorizedForUser($user, 0, 0);
583  $object->next_prev_filter = " rowid IN (".$db->sanitize(count($objectsListId) ?join(',', array_keys($objectsListId)) : '0').")";
584  }
585 
586  dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
587 
588  print '<div class="fichecenter">';
589  print '<div class="fichehalfleft">';
590  print '<div class="underbanner clearboth"></div>';
591 
592  print '<table class="border tableforfield centpercent">';
593 
594  // Usage
595  if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES) || empty($conf->global->PROJECT_HIDE_TASKS) || isModEnabled('eventorganization')) {
596  print '<tr><td class="tdtop">';
597  print $langs->trans("Usage");
598  print '</td>';
599  print '<td>';
600  if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) {
601  print '<input type="checkbox" disabled name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_opportunity ? ' checked="checked"' : '')).'"> ';
602  $htmltext = $langs->trans("ProjectFollowOpportunity");
603  print $form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext);
604  print '<br>';
605  }
606  if (empty($conf->global->PROJECT_HIDE_TASKS)) {
607  print '<input type="checkbox" disabled name="usage_task"'.(GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') != '' ? ' checked="checked"' : '') : ($object->usage_task ? ' checked="checked"' : '')).'"> ';
608  $htmltext = $langs->trans("ProjectFollowTasks");
609  print $form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext);
610  print '<br>';
611  }
612  if (empty($conf->global->PROJECT_HIDE_TASKS) && !empty($conf->global->PROJECT_BILL_TIME_SPENT)) {
613  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"' : '')).'"> ';
614  $htmltext = $langs->trans("ProjectBillTimeDescription");
615  print $form->textwithpicto($langs->trans("BillTime"), $htmltext);
616  print '<br>';
617  }
618  if (isModEnabled('eventorganization')) {
619  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"' : '')).'"> ';
620  $htmltext = $langs->trans("EventOrganizationDescriptionLong");
621  print $form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext);
622  }
623  print '</td></tr>';
624  }
625 
626  // Visibility
627  print '<tr><td class="titlefield">'.$langs->trans("Visibility").'</td><td>';
628  if ($object->public) {
629  print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
630  print $langs->trans('SharedProject');
631  } else {
632  print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
633  print $langs->trans('PrivateProject');
634  }
635  print '</td></tr>';
636 
637  // Budget
638  print '<tr><td>'.$langs->trans("Budget").'</td><td>';
639  if (!is_null($object->budget_amount) && strcmp($object->budget_amount, '')) {
640  print '<span class="amount">'.price($object->budget_amount, '', $langs, 1, 0, 0, $conf->currency).'</span>';
641  }
642  print '</td></tr>';
643 
644  // Date start - end project
645  print '<tr><td>'.$langs->trans("Dates").'</td><td>';
646  $start = dol_print_date($object->date_start, 'day');
647  print ($start ? $start : '?');
648  $end = dol_print_date($object->date_end, 'day');
649  print ' - ';
650  print ($end ? $end : '?');
651  if ($object->hasDelay()) {
652  print img_warning("Late");
653  }
654  print '</td></tr>';
655 
656  // Other attributes
657  $cols = 2;
658  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
659 
660  print '</table>';
661 
662  print '</div>';
663  print '<div class="fichehalfright">';
664  print '<div class="underbanner clearboth"></div>';
665 
666  print '<table class="border tableforfield centpercent">';
667 
668  // Description
669  print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>';
670  print dol_htmlentitiesbr($object->description);
671  print '</td></tr>';
672 
673  // Categories
674  if (isModEnabled('categorie')) {
675  print '<tr><td class="valignmiddle">'.$langs->trans("Categories").'</td><td>';
676  print $form->showCategories($object->id, Categorie::TYPE_PROJECT, 1);
677  print "</td></tr>";
678  }
679 
680  print '</table>';
681 
682  print '</div>';
683  print '</div>';
684 
685  print '<div class="clearboth"></div>';
686 
687 
688  print dol_get_fiche_end();
689 }
690 
691 
692 if ($action == 'create' && $user->rights->projet->creer && (empty($object->thirdparty->id) || $userWrite > 0)) {
693  if ($id > 0 || !empty($ref)) {
694  print '<br>';
695  }
696 
697  print load_fiche_titre($langs->trans("NewTask"), '', 'projecttask');
698 
699  $projectoktoentertime = 1;
700  if ($object->id > 0 && $object->statut == Project::STATUS_CLOSED) {
701  $projectoktoentertime = 0;
702  print '<div class="warning">';
703  $langs->load("errors");
704  print $langs->trans("WarningProjectClosed");
705  print '</div>';
706  }
707 
708  if ($object->id > 0 && $object->statut == Project::STATUS_DRAFT) {
709  $projectoktoentertime = 0;
710  print '<div class="warning">';
711  $langs->load("errors");
712  print $langs->trans("WarningProjectDraft");
713  print '</div>';
714  }
715 
716  print '<form action="'.$_SERVER['PHP_SELF'].'" method="POST">';
717  print '<input type="hidden" name="token" value="'.newToken().'">';
718  print '<input type="hidden" name="action" value="createtask">';
719  print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
720  if (!empty($object->id)) {
721  print '<input type="hidden" name="id" value="'.$object->id.'">';
722  }
723 
724  print dol_get_fiche_head('');
725 
726  print '<table class="border centpercent">';
727 
728  $defaultref = '';
729  $obj = empty($conf->global->PROJECT_TASK_ADDON) ? 'mod_task_simple' : $conf->global->PROJECT_TASK_ADDON;
730  if (!empty($conf->global->PROJECT_TASK_ADDON) && is_readable(DOL_DOCUMENT_ROOT."/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.".php")) {
731  require_once DOL_DOCUMENT_ROOT."/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.'.php';
732  $modTask = new $obj;
733  $defaultref = $modTask->getNextValue($object->thirdparty, null);
734  }
735 
736  if (is_numeric($defaultref) && $defaultref <= 0) {
737  $defaultref = '';
738  }
739 
740  // Ref
741  print '<tr><td class="titlefieldcreate"><span class="fieldrequired">'.$langs->trans("Ref").'</span></td><td>';
742  if (empty($duplicate_code_error)) {
743  print (GETPOSTISSET("ref") ? GETPOST("ref", 'alpha') : $defaultref);
744  } else {
745  print $defaultref;
746  }
747  print '<input type="hidden" name="taskref" value="'.(GETPOSTISSET("ref") ? GETPOST("ref", 'alpha') : $defaultref).'">';
748  print '</td></tr>';
749 
750  // Label
751  print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td><td>';
752  print '<input type="text" name="label" autofocus class="minwidth500 maxwidthonsmartphone" value="'.$label.'">';
753  print '</td></tr>';
754 
755  // Project
756  print '<tr><td class="fieldrequired">'.$langs->trans("ChildOfProjectTask").'</td><td>';
757  print img_picto('', 'project', 'class="pictofixedwidth"');
758  if ($projectoktoentertime) {
759  $formother->selectProjectTasks(GETPOST('task_parent'), empty($projectid) ? $object->id : $projectid, 'task_parent', 0, 0, 1, 1, 0, '0,1', 'maxwidth500 widthcentpercentminusxx');
760  } else {
761  $formother->selectProjectTasks(GETPOST('task_parent'), empty($projectid) ? $object->id : $projectid, 'task_parent', 0, 0, 1, 1, 0, '', 'maxwidth500 widthcentpercentminusxx');
762  }
763  print '</td></tr>';
764 
765  $contactsofproject = (empty($object->id) ? '' : $object->getListContactId('internal'));
766 
767  // Assigned to
768  print '<tr><td>'.$langs->trans("AffectedTo").'</td><td>';
769  print img_picto('', 'user', 'class="pictofixedwidth"');
770  if (is_array($contactsofproject) && count($contactsofproject)) {
771  print $form->select_dolusers($user->id, 'userid', 0, '', 0, '', $contactsofproject, 0, 0, 0, '', 0, '', 'maxwidth300');
772  } else {
773  if ((isset($projectid) && $projectid > 0) || $object->id > 0) {
774  print '<span class="opacitymedium">'.$langs->trans("NoUserAssignedToTheProject").'</span>';
775  } else {
776  print $form->select_dolusers($user->id, 'userid', 0, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300');
777  }
778  }
779  print '</td></tr>';
780 
781  // Date start task
782  print '<tr><td>'.$langs->trans("DateStart").'</td><td>';
783  print img_picto('', 'action', 'class="pictofixedwidth"');
784  print $form->selectDate((!empty($date_start) ? $date_start : ''), 'dateo', 1, 1, 0, '', 1, 1);
785  print '</td></tr>';
786 
787  // Date end task
788  print '<tr><td>'.$langs->trans("DateEnd").'</td><td>';
789  print img_picto('', 'action', 'class="pictofixedwidth"');
790  print $form->selectDate((!empty($date_end) ? $date_end : -1), 'datee', -1, 1, 0, '', 1, 1);
791  print '</td></tr>';
792 
793  // Planned workload
794  print '<tr><td>'.$langs->trans("PlannedWorkload").'</td><td>';
795  print img_picto('', 'clock', 'class="pictofixedwidth"');
796  print $form->select_duration('planned_workload', !empty($planned_workload) ? $planned_workload : 0, 0, 'text');
797  print '</td></tr>';
798 
799  // Progress
800  print '<tr><td>'.$langs->trans("ProgressDeclared").'</td><td colspan="3">';
801  print img_picto('', 'fa-percent', 'class="pictofixedwidth"');
802  print $formother->select_percent($progress, 'progress', 0, 5, 0, 100, 1);
803  print '</td></tr>';
804 
805  // Description
806  print '<tr><td class="tdtop">'.$langs->trans("Description").'</td>';
807  print '<td>';
808 
809  // WYSIWYG editor
810  include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
811  $cked_enabled = (!empty($conf->global->FCKEDITOR_ENABLE_SOCIETE) ? $conf->global->FCKEDITOR_ENABLE_SOCIETE : 0);
812  $nbrows = 0;
813  if (!empty($conf->global->MAIN_INPUT_DESC_HEIGHT)) {
814  $nbrows = $conf->global->MAIN_INPUT_DESC_HEIGHT;
815  }
816  $doleditor = new DolEditor('description', $object->description, '', 80, 'dolibarr_details', '', false, true, $cked_enabled, $nbrows);
817  print $doleditor->Create();
818 
819  print '</td></tr>';
820 
821  print '<tr><td>'.$langs->trans("Budget").'</td><td>';
822  print img_picto('', 'currency', 'class="pictofixedwidth"');
823  print '<input size="8" type="text" name="budget_amount" value="'.dol_escape_htmltag(GETPOSTISSET('budget_amount') ? GETPOST('budget_amount') : '').'"></td>';
824  print '</tr>';
825 
826  // Other options
827  $parameters = array('arrayfields' => &$arrayfields);
828  $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $taskstatic, $action); // Note that $action and $object may have been modified by hook
829  print $hookmanager->resPrint;
830 
831  if (empty($reshook) && !empty($extrafields->attributes[$taskstatic->table_element]['label'])) {
832  print $taskstatic->showOptionals($extrafields, 'edit'); // Do not use $object here that is object of project but use $taskstatic
833  }
834 
835  print '</table>';
836 
837  print dol_get_fiche_end();
838 
839  print $form->buttonsSaveCancel("Add");
840 
841  print '</form>';
842 } elseif ($id > 0 || !empty($ref)) {
843  $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
844 
845  /*
846  * Projet card in view mode
847  */
848 
849  print '<br>';
850 
851  // Link to create task
852  $linktocreatetaskParam = array();
853  $linktocreatetaskUserRight = false;
854  if ($user->hasRight('projet', 'all', 'creer') || $user->hasRight('projet', 'creer')) {
855  if ($object->public || $userWrite > 0) {
856  $linktocreatetaskUserRight = true;
857  } else {
858  $linktocreatetaskParam['attr']['title'] = $langs->trans("NotOwnerOfProject");
859  }
860  }
861 
862  $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);
863 
864  print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'">';
865  print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
866  print '<input type="hidden" name="token" value="'.newToken().'">';
867  print '<input type="hidden" name="action" value="list">';
868  print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
869  print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
870  print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
871  print '<input type="hidden" name="page" value="'.$page.'">';
872  print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
873 
874  $title = $langs->trans("ListOfTasks");
875  $linktotasks = dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/projet/tasks.php?id='.$object->id, '', 1, array('morecss'=>'reposition btnTitleSelected'));
876  $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'));
877 
878  //print_barre_liste($title, 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, $linktotasks, $num, $totalnboflines, 'generic', 0, '', '', 0, 1);
879  print load_fiche_titre($title, $linktotasks.' &nbsp; '.$linktocreatetask, 'projecttask', '', '', '', $massactionbutton);
880 
881  $objecttmp = new Task($db);
882  $trackid = 'task'.$taskstatic->id;
883  include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
884 
885  // Get list of tasks in tasksarray and taskarrayfiltered
886  // 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).
887  $filteronthirdpartyid = $socid;
888  $tasksarray = $taskstatic->getTasksArray(0, 0, $object->id, $filteronthirdpartyid, 0, '', -1, $morewherefilter, 0, 0, $extrafields, 1, $search_array_options, 0, 1, $sortfield, $sortorder);
889 
890  // We load also tasks limited to a particular user
891  $tmpuser = new User($db);
892  if ($search_user_id > 0) {
893  $tmpuser->fetch($search_user_id);
894  }
895 
896  $tasksrole = ($tmpuser->id > 0 ? $taskstatic->getUserRolesForProjectsOrTasks(null, $tmpuser, $object->id, 0) : '');
897  //var_dump($tasksarray);
898  //var_dump($tasksrole);
899 
900  if (!empty($conf->use_javascript_ajax)) {
901  include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
902  }
903 
904  // Filter on assigned users
905  $moreforfilter = '';
906  $moreforfilter .= '<div class="divsearchfield">';
907  $moreforfilter .= img_picto('', 'user', 'class="pictofixedwidth"');
908  $moreforfilter .= $form->select_dolusers($tmpuser->id > 0 ? $tmpuser->id : '', 'search_user_id', $langs->trans("TasksAssignedTo"), null, 0, '', '');
909  $moreforfilter .= '</div>';
910  if ($moreforfilter) {
911  print '<div class="liste_titre liste_titre_bydiv centpercent">';
912  print $moreforfilter;
913  print '</div>';
914  }
915 
916  // Show the massaction checkboxes only when this page is not opend from the Extended POS
917  if ($massactionbutton && $contextpage != 'poslist') {
918  $selectedfields = $form->showCheckAddButtons('checkforselect', 1);
919  }
920 
921  print '<div class="div-table-responsive">';
922  print '<table id="tablelines" class="tagtable nobottom liste'.($moreforfilter ? " listwithfilterbefore" : "").'">';
923 
924  // Fields title search
925  print '<tr class="liste_titre_filter">';
926 
927  // Action column
928  if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
929  print '<td class="liste_titre maxwidthsearch">';
930  $searchpicto = $form->showFilterButtons();
931  print $searchpicto;
932  print '</td>';
933  }
934 
935  if (!empty($arrayfields['t.ref']['checked'])) {
936  print '<td class="liste_titre">';
937  print '<input class="flat searchstring maxwidth50" type="text" name="search_taskref" value="'.dol_escape_htmltag($search_taskref).'">';
938  print '</td>';
939  }
940 
941  if (!empty($arrayfields['t.label']['checked'])) {
942  print '<td class="liste_titre">';
943  print '<input class="flat searchstring maxwidth100" type="text" name="search_tasklabel" value="'.dol_escape_htmltag($search_tasklabel).'">';
944  print '</td>';
945  }
946 
947  if (!empty($arrayfields['t.description']['checked'])) {
948  print '<td class="liste_titre">';
949  print '<input class="flat searchstring maxwidth100" type="text" name="search_taskdescription" value="'.dol_escape_htmltag($search_taskdescription).'">';
950  print '</td>';
951  }
952 
953  if (!empty($arrayfields['t.dateo']['checked'])) {
954  print '<td class="liste_titre center">';
955  /*print '<span class="nowraponall"><input class="flat valignmiddle width20" type="text" maxlength="2" name="search_dtstartday" value="'.$search_dtstartday.'">';
956  print '<input class="flat valignmiddle width20" type="text" maxlength="2" name="search_dtstartmonth" value="'.$search_dtstartmonth.'"></span>';
957  print $formother->selectyear($search_dtstartyear ? $search_dtstartyear : -1, 'search_dtstartyear', 1, 20, 5);*/
958  print '<div class="nowrap">';
959  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'));
960  print '</div>';
961  print '<div class="nowrap">';
962  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'));
963  print '</div>';
964  print '</td>';
965  }
966 
967  if (!empty($arrayfields['t.datee']['checked'])) {
968  print '<td class="liste_titre center">';
969  /*print '<span class="nowraponall"><input class="flat valignmiddle width20" type="text" maxlength="2" name="search_dtendday" value="'.$search_dtendday.'">';
970  print '<input class="flat valignmiddle width20" type="text" maxlength="2" name="search_dtendmonth" value="'.$search_dtendmonth.'"></span>';
971  print $formother->selectyear($search_dtendyear ? $search_dtendyear : -1, 'search_dtendyear', 1, 20, 5);*/
972  print '<div class="nowrap">';
973  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'));
974  print '</div>';
975  print '<div class="nowrap">';
976  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'));
977  print '</div>';
978  print '</td>';
979  }
980 
981  if (!empty($arrayfields['t.planned_workload']['checked'])) {
982  print '<td class="liste_titre right">';
983  print '<input class="flat" type="text" size="4" name="search_planedworkload" value="'.$search_planedworkload.'">';
984  print '</td>';
985  }
986 
987  if (!empty($arrayfields['t.duration_effective']['checked'])) {
988  print '<td class="liste_titre right">';
989  print '<input class="flat" type="text" size="4" name="search_timespend" value="'.$search_timespend.'">';
990  print '</td>';
991  }
992 
993  if (!empty($arrayfields['t.progress_calculated']['checked'])) {
994  print '<td class="liste_titre right">';
995  print '<input class="flat" type="text" size="4" name="search_progresscalc" value="'.$search_progresscalc.'">';
996  print '</td>';
997  }
998 
999  if (!empty($arrayfields['t.progress']['checked'])) {
1000  print '<td class="liste_titre right">';
1001  print '<input class="flat" type="text" size="4" name="search_progressdeclare" value="'.$search_progressdeclare.'">';
1002  print '</td>';
1003  }
1004 
1005  // progress resume not searchable
1006  if (!empty($arrayfields['t.progress_summary']['checked'])) {
1007  print '<td class="liste_titre right"></td>';
1008  }
1009 
1010  if ($object->usage_bill_time) {
1011  if (!empty($arrayfields['t.tobill']['checked'])) {
1012  print '<td class="liste_titre right">';
1013  print '</td>';
1014  }
1015 
1016  if (!empty($arrayfields['t.billed']['checked'])) {
1017  print '<td class="liste_titre right">';
1018  print '</td>';
1019  }
1020  }
1021  // Contacts of task, disabled because available by default jsut after
1022  /*
1023  if (!empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST)) {
1024  print '<td class="liste_titre"></td>';
1025  }
1026  */
1027 
1028  if (!empty($arrayfields['t.budget_amount']['checked'])) {
1029  print '<td class="liste_titre center">';
1030  print '<input type="text" class="flat" name="search_task_budget_amount" value="'.$search_task_budget_amount.'" size="4">';
1031  print '</td>';
1032  }
1033 
1034  if (!empty($arrayfields['c.assigned']['checked'])) {
1035  print '<td class="liste_titre right">';
1036  print '</td>';
1037  }
1038 
1039  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
1040 
1041  print '<td class="liste_titre maxwidthsearch">&nbsp;</td>';
1042 
1043  // Action column
1044  if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1045  print '<td class="liste_titre maxwidthsearch">';
1046  $searchpicto = $form->showFilterButtons();
1047  print $searchpicto;
1048  print '</td>';
1049  }
1050 
1051  print "</tr>\n";
1052 
1053  print '<tr class="liste_titre nodrag nodrop">';
1054  // Action column
1055  if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1056  print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
1057  }
1058  // print '<td>'.$langs->trans("Project").'</td>';
1059  if (!empty($arrayfields['t.ref']['checked'])) {
1060  print_liste_field_titre($arrayfields['t.ref']['label'], $_SERVER["PHP_SELF"], 't.ref', '', $param, '', $sortfield, $sortorder, '');
1061  }
1062  if (!empty($arrayfields['t.label']['checked'])) {
1063  print_liste_field_titre($arrayfields['t.label']['label'], $_SERVER["PHP_SELF"], "t.label", '', $param, '', $sortfield, $sortorder, '');
1064  }
1065  if (!empty($arrayfields['t.description']['checked'])) {
1066  print_liste_field_titre($arrayfields['t.description']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, '');
1067  }
1068  if (!empty($arrayfields['t.dateo']['checked'])) {
1069  print_liste_field_titre($arrayfields['t.dateo']['label'], $_SERVER["PHP_SELF"], "t.dateo", '', $param, '', $sortfield, $sortorder, 'center ');
1070  }
1071  if (!empty($arrayfields['t.datee']['checked'])) {
1072  print_liste_field_titre($arrayfields['t.datee']['label'], $_SERVER["PHP_SELF"], "t.datee", '', $param, '', $sortfield, $sortorder, 'center ');
1073  }
1074  if (!empty($arrayfields['t.planned_workload']['checked'])) {
1075  print_liste_field_titre($arrayfields['t.planned_workload']['label'], $_SERVER["PHP_SELF"], "t.planned_workload", '', $param, '', $sortfield, $sortorder, 'right ', '', 1);
1076  }
1077  if (!empty($arrayfields['t.duration_effective']['checked'])) {
1078  print_liste_field_titre($arrayfields['t.duration_effective']['label'], $_SERVER["PHP_SELF"], "t.duration_effective", '', $param, '', $sortfield, $sortorder, 'right ', '', 1);
1079  }
1080  if (!empty($arrayfields['t.progress_calculated']['checked'])) {
1081  print_liste_field_titre($arrayfields['t.progress_calculated']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'right ', '', 1);
1082  }
1083  if (!empty($arrayfields['t.progress']['checked'])) {
1084  print_liste_field_titre($arrayfields['t.progress']['label'], $_SERVER["PHP_SELF"], "t.progress", '', $param, '', $sortfield, $sortorder, 'right ', '', 1);
1085  }
1086  if (!empty($arrayfields['t.progress_summary']['checked'])) {
1087  print_liste_field_titre($arrayfields['t.progress_summary']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ', '', 1);
1088  }
1089  if ($object->usage_bill_time) {
1090  if (!empty($arrayfields['t.tobill']['checked'])) {
1091  print_liste_field_titre($arrayfields['t.tobill']['label'], $_SERVER["PHP_SELF"], "t.tobill", '', $param, '', $sortfield, $sortorder, 'right ');
1092  }
1093  if (!empty($arrayfields['t.billed']['checked'])) {
1094  print_liste_field_titre($arrayfields['t.billed']['label'], $_SERVER["PHP_SELF"], "t.billed", '', $param, '', $sortfield, $sortorder, 'right ');
1095  }
1096  }
1097  // Contacts of task, disabled because available by default jsut after
1098  /*
1099  if (!empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST)) {
1100  print_liste_field_titre("TaskRessourceLinks", $_SERVER["PHP_SELF"], '', '', $param, $sortfield, $sortorder);
1101  }
1102  */
1103 
1104  if (!empty($arrayfields['t.budget_amount']['checked'])) {
1105  print_liste_field_titre($arrayfields['t.budget_amount']['label'], $_SERVER["PHP_SELF"], "t.budget_amount", "", $param, '', $sortfield, $sortorder, 'center ');
1106  }
1107 
1108  if (!empty($arrayfields['c.assigned']['checked'])) {
1109  print_liste_field_titre($arrayfields['c.assigned']['label'], $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'center ', '');
1110  }
1111  // Extra fields
1112  $disablesortlink = 1;
1113  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
1114  // Hook fields
1115  $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder);
1116  $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook
1117  print $hookmanager->resPrint;
1118  print '<td></td>';
1119  // Action column
1120  if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
1121  print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
1122  }
1123  print "</tr>\n";
1124 
1125  $nboftaskshown = 0;
1126  if (count($tasksarray) > 0) {
1127  // Show all lines in taskarray (recursive function to go down on tree)
1128  $j = 0; $level = 0;
1129  $nboftaskshown = projectLinesa($j, 0, $tasksarray, $level, true, 0, $tasksrole, $object->id, 1, $object->id, '', ($object->usage_bill_time ? 1 : 0), $arrayfields, $arrayofselected);
1130  } else {
1131  $colspan = count($arrayfields);
1132  if ($object->usage_bill_time) {
1133  $colspan += 2;
1134  }
1135  print '<tr class="oddeven"><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoTasks").'</span></td></tr>';
1136  }
1137 
1138  print "</table>";
1139  print '</div>';
1140 
1141  print '</form>';
1142 
1143 
1144  // Test if database is clean. If not we clean it.
1145  //print 'mode='.$_REQUEST["mode"].' $nboftaskshown='.$nboftaskshown.' count($tasksarray)='.count($tasksarray).' count($tasksrole)='.count($tasksrole).'<br>';
1146  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)
1147  if ($search_user_id == $user->id) {
1148  if ($nboftaskshown < count($tasksrole)) {
1149  include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
1150  cleanCorruptedTree($db, 'projet_task', 'fk_task_parent');
1151  }
1152  } else {
1153  if ($nboftaskshown < count($tasksarray) && !GETPOST('search_user_id', 'int')) {
1154  include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
1155  cleanCorruptedTree($db, 'projet_task', 'fk_task_parent');
1156  }
1157  }
1158  }
1159 }
1160 
1161 // End of page
1162 llxFooter();
1163 $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:40
Class to manage Dolibarr users.
Definition: user.class.php:48
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
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:359
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.
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
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...
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.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
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...
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$taskrole, $projectsListId='', $addordertick=0, $projectidfortotallink=0, $dummy='', $showbilltime=0, $arrayfields=array(), $arrayofselected=array())
Show task lines with a particular parent.
project_prepare_head(Project $project, $moreparam='')
Prepare array with list of tabs.
Definition: project.lib.php:39
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.