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