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