dolibarr  16.0.5
list.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2006-2019 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2006-2010 Regis Houssin <regis.houssin@inodbox.com>
5  * Copyright (C) 2018 Ferran Marcet <fmarcet@2byte.es>
6  * Copyright (C) 2021 Alexandre Spangaro <aspangaro@open-dsi.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 
28 require "../../main.inc.php";
29 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
30 require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
31 require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
32 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
33 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
34 
35 // Load translation files required by the page
36 $langs->loadLangs(array('projects', 'users', 'companies'));
37 
38 $action = GETPOST('action', 'aZ09');
39 $massaction = GETPOST('massaction', 'alpha');
40 $show_files = GETPOST('show_files', 'int');
41 $confirm = GETPOST('confirm', 'alpha');
42 $toselect = GETPOST('toselect', 'array');
43 $optioncss = GETPOST('optioncss', 'aZ09');
44 $mode = GETPOST('mode', 'aZ');
45 
46 $id = GETPOST('id', 'int');
47 
48 $search_all = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'));
49 $search_categ = GETPOST("search_categ", 'alpha');
50 
51 $search_projectstatus = GETPOST('search_projectstatus');
52 if (!isset($search_projectstatus) || $search_projectstatus === '') {
53  if ($search_all != '') {
54  $search_projectstatus = -1;
55  } else {
56  $search_projectstatus = 1;
57  }
58 }
59 
60 $search_project_ref = GETPOST('search_project_ref');
61 $search_project_title = GETPOST('search_project_title');
62 $search_task_ref = GETPOST('search_task_ref');
63 $search_task_label = GETPOST('search_task_label');
64 $search_task_description = GETPOST('search_task_description');
65 $search_task_ref_parent = GETPOST('search_task_ref_parent');
66 $search_project_user = GETPOST('search_project_user', 'int');
67 $search_task_user = GETPOST('search_task_user', 'int');
68 $search_task_progress = GETPOST('search_task_progress');
69 $search_task_budget_amount = GETPOST('search_task_budget_amount');
70 $search_societe = GETPOST('search_societe');
71 $search_opp_status = GETPOST("search_opp_status", 'alpha');
72 
73 $mine = GETPOST('mode', 'alpha') == 'mine' ? 1 : 0;
74 if ($mine) {
75  $search_task_user = $user->id;
76  $mine = 0;
77 }
78 $type = GETPOST('type');
79 
80 $search_date_startday = GETPOST('search_date_startday', 'int');
81 $search_date_startmonth = GETPOST('search_date_startmonth', 'int');
82 $search_date_startyear = GETPOST('search_date_startyear', 'int');
83 $search_date_endday = GETPOST('search_date_endday', 'int');
84 $search_date_endmonth = GETPOST('search_date_endmonth', 'int');
85 $search_date_endyear = GETPOST('search_date_endyear', 'int');
86 $search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear); // Use tzserver
87 $search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_endday, $search_date_endyear);
88 $search_datelimit_startday = GETPOST('search_datelimit_startday', 'int');
89 $search_datelimit_startmonth = GETPOST('search_datelimit_startmonth', 'int');
90 $search_datelimit_startyear = GETPOST('search_datelimit_startyear', 'int');
91 $search_datelimit_endday = GETPOST('search_datelimit_endday', 'int');
92 $search_datelimit_endmonth = GETPOST('search_datelimit_endmonth', 'int');
93 $search_datelimit_endyear = GETPOST('search_datelimit_endyear', 'int');
94 $search_datelimit_start = dol_mktime(0, 0, 0, $search_datelimit_startmonth, $search_datelimit_startday, $search_datelimit_startyear);
95 $search_datelimit_end = dol_mktime(23, 59, 59, $search_datelimit_endmonth, $search_datelimit_endday, $search_datelimit_endyear);
96 
97 // Initialize context for list
98 $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'tasklist';
99 
100 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
101 $object = new Task($db);
102 $hookmanager->initHooks(array('tasklist'));
103 $extrafields = new ExtraFields($db);
104 
105 // fetch optionals attributes and labels
106 $extrafields->fetch_name_optionals_label($object->table_element);
107 $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
108 
109 // Security check
110 $socid = 0;
111 //if ($user->socid > 0) $socid = $user->socid; // For external user, no check is done on company because readability is managed by public status of project and assignement.
112 if (!$user->rights->projet->lire) {
113  accessforbidden();
114 }
115 
116 $diroutputmassaction = $conf->project->dir_output.'/tasks/temp/massgeneration/'.$user->id;
117 
118 $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
119 $sortfield = GETPOST('sortfield', 'aZ09comma');
120 $sortorder = GETPOST('sortorder', 'aZ09comma');
121 $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
122 if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
123  // If $page is not defined, or '' or -1 or if we click on clear filters
124  $page = 0;
125 }
126 $offset = $limit * $page;
127 $pageprev = $page - 1;
128 $pagenext = $page + 1;
129 if (!$sortfield) {
130  $sortfield = 'p.ref';
131 }
132 if (!$sortorder) {
133  $sortorder = 'DESC';
134 }
135 
136 // List of fields to search into when doing a "search in all"
137 $fieldstosearchall = array(
138  't.ref'=>"Ref",
139  't.label'=>"Label",
140  't.description'=>"Description",
141  't.note_public'=>"NotePublic",
142 );
143 if (empty($user->socid)) {
144  $fieldstosearchall['t.note_private'] = "NotePrivate";
145 }
146 
147 $arrayfields = array(
148  't.fk_task_parent'=>array('label'=>"RefTaskParent", 'checked'=>0, 'position'=>70),
149  't.ref'=>array('label'=>"RefTask", 'checked'=>1, 'position'=>80),
150  't.label'=>array('label'=>"LabelTask", 'checked'=>1, 'position'=>80),
151  't.description'=>array('label'=>"Description", 'checked'=>0, 'position'=>80),
152  't.dateo'=>array('label'=>"DateStart", 'checked'=>1, 'position'=>100),
153  't.datee'=>array('label'=>"Deadline", 'checked'=>1, 'position'=>101),
154  'p.ref'=>array('label'=>"ProjectRef", 'checked'=>1),
155  'p.title'=>array('label'=>"ProjectLabel", 'checked'=>0),
156  's.nom'=>array('label'=>"ThirdParty", 'checked'=>0),
157  'p.fk_statut'=>array('label'=>"ProjectStatus", 'checked'=>1),
158  't.planned_workload'=>array('label'=>"PlannedWorkload", 'checked'=>1, 'position'=>102),
159  't.duration_effective'=>array('label'=>"TimeSpent", 'checked'=>1, 'position'=>103),
160  't.progress_calculated'=>array('label'=>"ProgressCalculated", 'checked'=>1, 'position'=>104),
161  't.progress'=>array('label'=>"ProgressDeclared", 'checked'=>1, 'position'=>105),
162  't.progress_summary'=>array('label'=>"TaskProgressSummary", 'checked'=>1, 'position'=>106),
163  't.budget_amount'=>array('label'=>"Budget", 'checked'=>0, 'position'=>107),
164  't.tobill'=>array('label'=>"TimeToBill", 'checked'=>0, 'position'=>110),
165  't.billed'=>array('label'=>"TimeBilled", 'checked'=>0, 'position'=>111),
166  't.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500),
167  't.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>500),
168  //'t.fk_statut'=>array('label'=>"Status", 'checked'=>1, 'position'=>1000),
169 );
170 // Extra fields
171 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
172 
173 $object->fields = dol_sort_array($object->fields, 'position');
174 $arrayfields = dol_sort_array($arrayfields, 'position');
175 
176 $permissiontoread = $user->rights->projet->lire;
177 $permissiontodelete = $user->rights->projet->supprimer;
178 
179 
180 /*
181  * Actions
182  */
183 
184 if (GETPOST('cancel', 'alpha')) {
185  $action = 'list';
186  $massaction = '';
187 }
188 if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
189  $massaction = '';
190 }
191 
192 $parameters = array('socid'=>$socid);
193 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
194 if ($reshook < 0) {
195  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
196 }
197 
198 if (empty($reshook)) {
199  // Selection of new fields
200  include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
201 
202  // Purge search criteria
203  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
204  $search_all = "";
205  $search_categ = "";
206  $search_projectstatus = -1;
207  $search_project_ref = "";
208  $search_project_title = "";
209  $search_task_ref = "";
210  $search_task_label = "";
211  $search_task_description = "";
212  $search_task_ref_parent = "";
213  $search_task_progress = "";
214  $search_task_budget_amount = "";
215  $search_task_user = -1;
216  $search_project_user = -1;
217  $search_date_startday = '';
218  $search_date_startmonth = '';
219  $search_date_startyear = '';
220  $search_date_endday = '';
221  $search_date_endmonth = '';
222  $search_date_endyear = '';
223  $search_date_start = '';
224  $search_date_end = '';
225  $search_datelimit_startday = '';
226  $search_datelimit_startmonth = '';
227  $search_datelimit_startyear = '';
228  $search_datelimit_endday = '';
229  $search_datelimit_endmonth = '';
230  $search_datelimit_endyear = '';
231  $search_datelimit_start = '';
232  $search_datelimit_end = '';
233  $toselect = array();
234  $search_array_options = array();
235  }
236 
237  // Mass actions
238  $objectclass = 'Task';
239  $objectlabel = 'Tasks';
240  $uploaddir = $conf->project->dir_output.'/tasks';
241  include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
242 }
243 
244 if (empty($search_projectstatus) && $search_projectstatus == '') {
245  $search_projectstatus = 1;
246 }
247 
248 
249 
250 
251 /*
252  * View
253  */
254 
255 $form = new Form($db);
256 
257 $now = dol_now();
258 
259 $help_url = "EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos";
260 $morejs = array();
261 $morecss = array();
262 
263 $formother = new FormOther($db);
264 $socstatic = new Societe($db);
265 $projectstatic = new Project($db);
266 $puser = new User($db);
267 $tuser = new User($db);
268 if ($search_project_user > 0) {
269  $puser->fetch($search_project_user);
270 }
271 if ($search_task_user > 0) {
272  $tuser->fetch($search_task_user);
273 }
274 
275 
276 $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
277 $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
278 
279 
280 $title = $langs->trans("Activities");
281 //if ($search_task_user == $user->id) $title=$langs->trans("MyActivities");
282 
283 if ($id) {
284  $projectstatic->fetch($id);
285  $projectstatic->fetch_thirdparty();
286 }
287 
288 // Get list of project id allowed to user (in a string list separated by coma)
289 if (empty($user->rights->projet->all->lire)) {
290  $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, $socid);
291 }
292 //var_dump($projectsListId);
293 
294 // Get id of types of contacts for projects (This list never contains a lot of elements)
295 $listofprojectcontacttype = array();
296 $sql = "SELECT ctc.rowid, ctc.code FROM ".MAIN_DB_PREFIX."c_type_contact as ctc";
297 $sql .= " WHERE ctc.element = '".$db->escape($projectstatic->element)."'";
298 $sql .= " AND ctc.source = 'internal'";
299 $resql = $db->query($sql);
300 if ($resql) {
301  while ($obj = $db->fetch_object($resql)) {
302  $listofprojectcontacttype[$obj->rowid] = $obj->code;
303  }
304 } else {
305  dol_print_error($db);
306 }
307 if (count($listofprojectcontacttype) == 0) {
308  $listofprojectcontacttype[0] = '0'; // To avoid sql syntax error if not found
309 }
310 // Get id of types of contacts for tasks (This list never contains a lot of elements)
311 $listoftaskcontacttype = array();
312 $sql = "SELECT ctc.rowid, ctc.code FROM ".MAIN_DB_PREFIX."c_type_contact as ctc";
313 $sql .= " WHERE ctc.element = '".$db->escape($object->element)."'";
314 $sql .= " AND ctc.source = 'internal'";
315 $resql = $db->query($sql);
316 if ($resql) {
317  while ($obj = $db->fetch_object($resql)) {
318  $listoftaskcontacttype[$obj->rowid] = $obj->code;
319  }
320 } else {
321  dol_print_error($db);
322 }
323 if (count($listoftaskcontacttype) == 0) {
324  $listoftaskcontacttype[0] = '0'; // To avoid sql syntax error if not found
325 }
326 
327 $distinct = 'DISTINCT'; // We add distinct until we are added a protection to be sure a contact of a project and task is assigned only once.
328 $sql = "SELECT ".$distinct." p.rowid as projectid, p.ref as projectref, p.title as projecttitle, p.fk_statut as projectstatus, p.datee as projectdatee, p.fk_opp_status, p.public, p.fk_user_creat as projectusercreate, p.usage_bill_time,";
329 $sql .= " s.nom as name, s.rowid as socid,";
330 $sql .= " t.datec as date_creation, t.dateo as date_start, t.datee as date_end, t.tms as date_update,";
331 $sql .= " t.rowid as id, t.ref, t.label, t.planned_workload, t.duration_effective, t.progress, t.fk_statut, ";
332 $sql .= " t.description, t.fk_task_parent";
333 $sql .= " ,t.budget_amount";
334 // We'll need these fields in order to filter by categ
335 if ($search_categ > 0) {
336  $sql .= ", cs.fk_categorie, cs.fk_project";
337 }
338 // Add sum fields
339 if (!empty($arrayfields['t.tobill']['checked']) || !empty($arrayfields['t.billed']['checked'])) {
340  $sql .= " , SUM(tt.task_duration * ".$db->ifsql("invoice_id IS NULL", "1", "0").") as tobill, SUM(tt.task_duration * ".$db->ifsql("invoice_id IS NULL", "0", "1").") as billed";
341 }
342 // Add fields from extrafields
343 if (!empty($extrafields->attributes[$object->table_element]['label'])) {
344  foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
345  $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
346  }
347 }
348 // Add fields from hooks
349 $parameters = array();
350 $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook
351 $sql .= $hookmanager->resPrint;
352 $sql .= " FROM ".MAIN_DB_PREFIX."projet as p";
353 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid";
354 // We'll need this table joined to the select in order to filter by categ
355 if ($search_categ > 0) {
356  $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_project as cs ON p.rowid = cs.fk_project"; // We'll need this table joined to the select in order to filter by categ
357 }
358 $sql .= ", ".MAIN_DB_PREFIX."projet_task as t";
359 if (!empty($arrayfields['t.tobill']['checked']) || !empty($arrayfields['t.billed']['checked'])) {
360  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_time as tt ON tt.fk_task = t.rowid";
361 }
362 if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
363  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)";
364 }
365 if ($search_project_user > 0) {
366  $sql .= ", ".MAIN_DB_PREFIX."element_contact as ecp";
367 }
368 if ($search_task_user > 0) {
369  $sql .= ", ".MAIN_DB_PREFIX."element_contact as ect";
370 }
371 $sql .= " WHERE t.fk_projet = p.rowid";
372 $sql .= " AND p.entity IN (".getEntity('project').')';
373 if (empty($user->rights->projet->all->lire)) {
374  $sql .= " AND p.rowid IN (".$db->sanitize($projectsListId ? $projectsListId : '0').")"; // public and assigned to projects, or restricted to company for external users
375 }
376 if (is_object($projectstatic) && $projectstatic->id > 0) {
377  $sql .= " AND p.rowid = ".((int) $projectstatic->id);
378 }
379 // No need to check company, as filtering of projects must be done by getProjectsAuthorizedForUser
380 if ($socid) {
381  $sql .= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".((int) $socid).")";
382 }
383 if ($search_categ > 0) {
384  $sql .= " AND cs.fk_categorie = ".((int) $search_categ);
385 }
386 if ($search_categ == -2) {
387  $sql .= " AND cs.fk_categorie IS NULL";
388 }
389 if ($search_project_ref) {
390  $sql .= natural_search('p.ref', $search_project_ref);
391 }
392 if ($search_project_title) {
393  $sql .= natural_search('p.title', $search_project_title);
394 }
395 if ($search_task_ref) {
396  $sql .= natural_search('t.ref', $search_task_ref);
397 }
398 if ($search_task_label) {
399  $sql .= natural_search('t.label', $search_task_label);
400 }
401 if ($search_task_description) {
402  $sql .= natural_search('t.description', $search_task_description);
403 }
404 if ($search_task_ref_parent) {
405  $sql .= ' AND t.fk_task_parent IN (SELECT ipt.rowid FROM '.MAIN_DB_PREFIX.'projet_task as ipt WHERE '.natural_search('ipt.ref', $search_task_ref_parent, 0, 1).')';
406 }
407 if ($search_task_progress) {
408  $sql .= natural_search('t.progress', $search_task_progress, 1);
409 }
410 if ($search_task_budget_amount) {
411  $sql .= natural_search('t.budget_amount', $search_task_budget_amount, 1);
412 }
413 if ($search_societe) {
414  $sql .= natural_search('s.nom', $search_societe);
415 }
416 if ($search_date_start) {
417  $sql .= " AND t.dateo >= '".$db->idate($search_date_start)."'";
418 }
419 if ($search_date_end) {
420  $sql .= " AND t.dateo <= '".$db->idate($search_date_end)."'";
421 }
422 if ($search_datelimit_start) {
423  $sql .= " AND t.datee >= '".$db->idate($search_datelimit_start)."'";
424 }
425 if ($search_datelimit_end) {
426  $sql .= " AND t.datee <= '".$db->idate($search_datelimit_end)."'";
427 }
428 if ($search_all) {
429  $sql .= natural_search(array_keys($fieldstosearchall), $search_all);
430 }
431 if ($search_projectstatus >= 0) {
432  if ($search_projectstatus == 99) {
433  $sql .= " AND p.fk_statut <> 2";
434  } else {
435  $sql .= " AND p.fk_statut = ".((int) $search_projectstatus);
436  }
437 }
438 if ($search_project_user > 0) {
439  $sql .= " AND ecp.fk_c_type_contact IN (".$db->sanitize(join(',', array_keys($listofprojectcontacttype))).") AND ecp.element_id = p.rowid AND ecp.fk_socpeople = ".((int) $search_project_user);
440 }
441 if ($search_task_user > 0) {
442  $sql .= " AND ect.fk_c_type_contact IN (".$db->sanitize(join(',', array_keys($listoftaskcontacttype))).") AND ect.element_id = t.rowid AND ect.fk_socpeople = ".((int) $search_task_user);
443 }
444 // Add where from extra fields
445 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
446 // Add where from hooks
447 $parameters = array();
448 $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook
449 $sql .= $hookmanager->resPrint;
450 if (!empty($arrayfields['t.tobill']['checked']) || !empty($arrayfields['t.billed']['checked'])) {
451  $sql .= " GROUP BY p.rowid, p.ref, p.title, p.fk_statut, p.datee, p.fk_opp_status, p.public, p.fk_user_creat,";
452  $sql .= " s.nom, s.rowid,";
453  $sql .= " t.datec, t.dateo, t.datee, t.tms,";
454  $sql .= " t.rowid, t.ref, t.label, t.planned_workload, t.duration_effective, t.progress,t.budget_amount, t.fk_statut";
455  if ($search_categ > 0) {
456  $sql .= ", cs.fk_categorie, cs.fk_project";
457  }
458  // Add fields from extrafields
459  if (!empty($extrafields->attributes[$object->table_element]['label'])) {
460  foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
461  $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key : '');
462  }
463  }
464 }
465 $sql .= $db->order($sortfield, $sortorder);
466 
467 $nbtotalofrecords = '';
468 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
469  $result = $db->query($sql);
470  $nbtotalofrecords = $db->num_rows($result);
471  if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
472  $page = 0;
473  $offset = 0;
474  }
475 }
476 
477 $sql .= $db->plimit($limit + 1, $offset);
478 
479 dol_syslog("list allowed project", LOG_DEBUG);
480 
481 $resql = $db->query($sql);
482 if (!$resql) {
483  dol_print_error($db);
484  exit;
485 }
486 
487 $num = $db->num_rows($resql);
488 
489 
490 // Direct jump if only one record found
491 if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all) {
492  $obj = $db->fetch_object($resql);
493  $id = $obj->id; // in select, task id has been aliases into 'id'
494  header("Location: ".DOL_URL_ROOT.'/projet/tasks/task.php?id='.$id.'&withproject=1');
495  exit;
496 }
497 
498 
499 // Output page
500 // --------------------------------------------------------------------
501 
502 llxHeader('', $title, $help_url);
503 
504 $arrayofselected = is_array($toselect) ? $toselect : array();
505 
506 $param = '';
507 if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
508  $param .= '&contextpage='.urlencode($contextpage);
509 }
510 if ($limit > 0 && $limit != $conf->liste_limit) {
511  $param .= '&limit='.urlencode($limit);
512 }
513 if ($search_date_startday) {
514  $param .= '&search_date_startday='.urlencode($search_date_startday);
515 }
516 if ($search_date_startmonth) {
517  $param .= '&search_date_startmonth='.urlencode($search_date_startmonth);
518 }
519 if ($search_date_startyear) {
520  $param .= '&search_date_startyear='.urlencode($search_date_startyear);
521 }
522 if ($search_date_endday) {
523  $param .= '&search_date_endday='.urlencode($search_date_endday);
524 }
525 if ($search_date_endmonth) {
526  $param .= '&search_date_endmonth='.urlencode($search_date_endmonth);
527 }
528 if ($search_date_endyear) {
529  $param .= '&search_date_endyear='.urlencode($search_date_endyear);
530 }
531 if ($search_datelimit_startday) {
532  $param .= '&search_datelimit_startday='.urlencode($search_datelimit_startday);
533 }
534 if ($search_datelimit_startmonth) {
535  $param .= '&search_datelimit_startmonth='.urlencode($search_datelimit_startmonth);
536 }
537 if ($search_datelimit_startyear) {
538  $param .= '&search_datelimit_startyear='.urlencode($search_datelimit_startyear);
539 }
540 if ($search_datelimit_endday) {
541  $param .= '&search_datelimit_endday='.urlencode($search_datelimit_endday);
542 }
543 if ($search_datelimit_endmonth) {
544  $param .= '&search_datelimit_endmonth='.urlencode($search_datelimit_endmonth);
545 }
546 if ($search_datelimit_endyear) {
547  $param .= '&search_datelimit_endyear='.urlencode($search_datelimit_endyear);
548 }
549 if ($search_task_budget_amount) {
550  $param .= '&search_task_budget_amount='.urlencode($search_task_budget_amount);
551 }
552 if ($socid) {
553  $param .= '&socid='.urlencode($socid);
554 }
555 if ($search_all != '') {
556  $param .= '&search_all='.urlencode($search_all);
557 }
558 if ($search_project_ref != '') {
559  $param .= '&search_project_ref='.urlencode($search_project_ref);
560 }
561 if ($search_project_title != '') {
562  $param .= '&search_project_title='.urlencode($search_project_title);
563 }
564 if ($search_task_ref != '') {
565  $param .= '&search_task_ref='.urlencode($search_task_ref);
566 }
567 if ($search_task_label != '') {
568  $param .= '&search_task_label='.urlencode($search_task_label);
569 }
570 if ($search_task_description != '') {
571  $param .= '&search_task_description='.urlencode($search_task_description);
572 }
573 if ($search_task_ref_parent != '') {
574  $param .= '&search_task_ref_parent='.urlencode($search_task_ref_parent);
575 }
576 if ($search_task_progress != '') {
577  $param .= '&search_task_progress='.urlencode($search_task_progress);
578 }
579 if ($search_societe != '') {
580  $param .= '&search_societe='.urlencode($search_societe);
581 }
582 if ($search_projectstatus != '') {
583  $param .= '&search_projectstatus='.urlencode($search_projectstatus);
584 }
585 if ((is_numeric($search_opp_status) && $search_opp_status >= 0) || in_array($search_opp_status, array('all', 'none'))) {
586  $param .= '&search_opp_status='.urlencode($search_opp_status);
587 }
588 if ($search_project_user != '') {
589  $param .= '&search_project_user='.urlencode($search_project_user);
590 }
591 if ($search_task_user > 0) {
592  $param .= '&search_task_user='.urlencode($search_task_user);
593 }
594 if ($optioncss != '') {
595  $param .= '&optioncss='.urlencode($optioncss);
596 }
597 // Add $param from extra fields
598 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
599 // Add $param from hooks
600 $parameters = array();
601 $reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook
602 $param .= $hookmanager->resPrint;
603 
604 // List of mass actions available
605 $arrayofmassactions = array(
606 // 'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
607 // 'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
608 );
609 //if($user->rights->societe->creer) $arrayofmassactions['createbills']=$langs->trans("CreateInvoiceForThisCustomer");
610 if ($permissiontodelete) {
611  $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
612 }
613 if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) {
614  $arrayofmassactions = array();
615 }
616 $massactionbutton = $form->selectMassAction('', $arrayofmassactions);
617 
618 $newcardbutton = dolGetButtonTitle($langs->trans('NewTask'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/projet/tasks.php?action=create', '', $user->rights->projet->creer);
619 
620 print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">'."\n";
621 if ($optioncss != '') {
622  print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
623 }
624 print '<input type="hidden" name="token" value="'.newToken().'">';
625 print '<input type="hidden" name="action" value="list">';
626 print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
627 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
628 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
629 if (!empty($type)) {
630  print '<input type="hidden" name="type" value="'.$type.'">';
631 }
632 print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
633 
634 // Show description of content
635 $texthelp = '';
636 if ($search_task_user == $user->id) {
637  $texthelp .= $langs->trans("MyTasksDesc");
638 } else {
639  if ($user->rights->projet->all->lire && !$socid) {
640  $texthelp .= $langs->trans("TasksOnProjectsDesc");
641  } else {
642  $texthelp .= $langs->trans("TasksOnProjectsPublicDesc");
643  }
644 }
645 
646 print_barre_liste($form->textwithpicto($title, $texthelp), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'projecttask', 0, $newcardbutton, '', $limit, 0, 0, 1);
647 
648 $topicmail = "Information";
649 $modelmail = "task";
650 $objecttmp = new Task($db);
651 $trackid = 'tas'.$object->id;
652 include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
653 
654 if ($search_all) {
655  foreach ($fieldstosearchall as $key => $val) {
656  $fieldstosearchall[$key] = $langs->trans($val);
657  }
658  print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'</div>';
659 }
660 
661 $moreforfilter = '';
662 
663 // Filter on categories
664 if (!empty($conf->categorie->enabled) && $user->rights->categorie->lire) {
665  require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
666  $moreforfilter .= '<div class="divsearchfield">';
667  $tmptitle = $langs->trans('ProjectCategories');
668  $moreforfilter .= img_picto($tmptitle, 'category', 'class="pictofixedwidth"').$formother->select_categories('project', $search_categ, 'search_categ', 0, $tmptitle, 'maxwidth300');
669  $moreforfilter .= '</div>';
670 }
671 
672 // If the user can view users
673 $moreforfilter .= '<div class="divsearchfield">';
674 $tmptitle = $langs->trans('ProjectsWithThisUserAsContact');
675 $includeonly = '';
676 if (empty($user->rights->user->user->lire)) {
677  $includeonly = array($user->id);
678 }
679 $moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$form->select_dolusers($search_project_user ? $search_project_user : '', 'search_project_user', $tmptitle, '', 0, $includeonly, '', 0, 0, 0, '', 0, '', 'maxwidth250');
680 $moreforfilter .= '</div>';
681 
682 // If the user can view users
683 $moreforfilter .= '<div class="divsearchfield">';
684 $tmptitle = $langs->trans('TasksWithThisUserAsContact');
685 $includeonly = '';
686 if (empty($user->rights->user->user->lire)) {
687  $includeonly = array($user->id);
688 }
689 $moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$form->select_dolusers($search_task_user, 'search_task_user', $tmptitle, '', 0, $includeonly, '', 0, 0, 0, '', 0, '', 'maxwidth250');
690 $moreforfilter .= '</div>';
691 
692 if (!empty($moreforfilter)) {
693  print '<div class="liste_titre liste_titre_bydiv centpercent">';
694  print $moreforfilter;
695  $parameters = array();
696  $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
697  print $hookmanager->resPrint;
698  print '</div>';
699 }
700 
701 if ($massactionbutton) {
702  $selectedfields .= $form->showCheckAddButtons('checkforselect', 1);
703 }
704 
705 print '<div class="div-table-responsive">';
706 print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'" id="tablelines3">'."\n";
707 
708 // Fields title search
709 // --------------------------------------------------------------------
710 print '<tr class="liste_titre_filter">';
711 if (!empty($arrayfields['t.fk_task_parent']['checked'])) {
712  print '<td class="liste_titre">';
713  print '<input type="text" class="flat" name="search_task_ref_parent" value="'.dol_escape_htmltag($search_task_ref_parent).'" size="4">';
714  print '</td>';
715 }
716 if (!empty($arrayfields['t.ref']['checked'])) {
717  print '<td class="liste_titre">';
718  print '<input type="text" class="flat" name="search_task_ref" value="'.dol_escape_htmltag($search_task_ref).'" size="4">';
719  print '</td>';
720 }
721 if (!empty($arrayfields['t.label']['checked'])) {
722  print '<td class="liste_titre">';
723  print '<input type="text" class="flat" name="search_task_label" value="'.dol_escape_htmltag($search_task_label).'" size="8">';
724  print '</td>';
725 }
726 // Task Description
727 if (!empty($arrayfields['t.description']['checked'])) {
728  print '<td class="liste_titre">';
729  print '<input type="text" class="flat" name="search_task_description" value="'.dol_escape_htmltag($search_task_description).'" size="8">';
730  print '</td>';
731 }
732 // Start date
733 if (!empty($arrayfields['t.dateo']['checked'])) {
734  print '<td class="liste_titre center">';
735  print '<div class="nowrap">';
736  print $form->selectDate($search_date_start ? $search_date_start : -1, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
737  print '</div>';
738  print '<div class="nowrap">';
739  print $form->selectDate($search_date_end ? $search_date_end : -1, 'search_date_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
740  print '</div>';
741  print '</td>';
742 }
743 // End date
744 if (!empty($arrayfields['t.datee']['checked'])) {
745  print '<td class="liste_titre center">';
746  print '<div class="nowrap">';
747  print $form->selectDate($search_datelimit_start ? $search_datelimit_start : -1, 'search_datelimit_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
748  print '</div>';
749  print '<div class="nowrap">';
750  print $form->selectDate($search_datelimit_end ? $search_datelimit_end : -1, 'search_datelimit_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
751  // TODO Add option late
752  //print '<br><input type="checkbox" name="search_option" value="late"'.($option == 'late' ? ' checked' : '').'> '.$langs->trans("Alert");
753  print '</div>';
754  print '</td>';
755 }
756 if (!empty($arrayfields['p.ref']['checked'])) {
757  print '<td class="liste_titre">';
758  print '<input type="text" class="flat" name="search_project_ref" value="'.$search_project_ref.'" size="4">';
759  print '</td>';
760 }
761 if (!empty($arrayfields['p.title']['checked'])) {
762  print '<td class="liste_titre">';
763  print '<input type="text" class="flat" name="search_project_title" value="'.$search_project_title.'" size="6">';
764  print '</td>';
765 }
766 if (!empty($arrayfields['s.nom']['checked'])) {
767  print '<td class="liste_titre">';
768  print '<input type="text" class="flat" name="search_societe" value="'.dol_escape_htmltag($search_societe).'" size="4">';
769  print '</td>';
770 }
771 if (!empty($arrayfields['p.fk_statut']['checked'])) {
772  print '<td class="liste_titre center">';
773  $arrayofstatus = array();
774  foreach ($projectstatic->statuts_short as $key => $val) {
775  $arrayofstatus[$key] = $langs->trans($val);
776  }
777  $arrayofstatus['99'] = $langs->trans("NotClosed").' ('.$langs->trans('Draft').'+'.$langs->trans('Opened').')';
778  print $form->selectarray('search_projectstatus', $arrayofstatus, $search_projectstatus, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100');
779  print '</td>';
780 }
781 if (!empty($arrayfields['t.planned_workload']['checked'])) {
782  print '<td class="liste_titre"></td>';
783 }
784 if (!empty($arrayfields['t.duration_effective']['checked'])) {
785  print '<td class="liste_titre"></td>';
786 }
787 if (!empty($arrayfields['t.progress_calculated']['checked'])) {
788  print '<td class="liste_titre"></td>';
789 }
790 if (!empty($arrayfields['t.progress']['checked'])) {
791  print '<td class="liste_titre center">';
792  print '<input type="text" class="flat" name="search_task_progress" value="'.$search_task_progress.'" size="4">';
793  print '</td>';
794 }
795 
796 if (!empty($arrayfields['t.progress_summary']['checked'])) {
797  print '<td class="liste_titre"></td>';
798 }
799 
800 if (!empty($arrayfields['t.budget_amount']['checked'])) {
801  print '<td class="liste_titre center">';
802  print '<input type="text" class="flat" name="search_task_budget_amount" value="'.$search_task_budget_amount.'" size="4">';
803  print '</td>';
804 }
805 
806 if (!empty($arrayfields['t.tobill']['checked'])) {
807  print '<td class="liste_titre"></td>';
808 }
809 if (!empty($arrayfields['t.billed']['checked'])) {
810  print '<td class="liste_titre"></td>';
811 }
812 // Extra fields
813 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
814 // Fields from hook
815 $parameters = array('arrayfields'=>$arrayfields);
816 $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook
817 print $hookmanager->resPrint;
818 if (!empty($arrayfields['t.datec']['checked'])) {
819  // Date creation
820  print '<td class="liste_titre">';
821  print '</td>';
822 }
823 if (!empty($arrayfields['t.tms']['checked'])) {
824  // Date modification
825  print '<td class="liste_titre">';
826  print '</td>';
827 }
828 // Action column
829 print '<td class="liste_titre maxwidthsearch">';
830 $searchpicto = $form->showFilterButtons();
831 print $searchpicto;
832 print '</td>';
833 print '</tr>'."\n";
834 
835 $totalarray = array(
836  'nbfield' => 0,
837  'val' => array(
838  't.planned_workload' => 0,
839  't.duration_effective' => 0,
840  't.progress' => 0,
841  't.budget_amount' => 0,
842  ),
843  'totalplannedworkload' => 0,
844  'totaldurationeffective' => 0,
845  'totaldurationdeclared' => 0,
846  'totaltobillfield' => 0,
847  'totalbilledfield' => 0,
848  'totalbudget_amountfield' => 0,
849  'totalbudgetamount' => 0,
850  'totaltobill' => 0,
851  'totalbilled' => 0,
852 );
853 
854 // Fields title label
855 // --------------------------------------------------------------------
856 print '<tr class="liste_titre">';
857 if (!empty($arrayfields['t.fk_task_parent']['checked'])) {
858  print_liste_field_titre($arrayfields['t.fk_task_parent']['label'], $_SERVER["PHP_SELF"], "t.fk_task_parent", "", $param, "", $sortfield, $sortorder);
859  $totalarray['nbfield']++;
860 }
861 if (!empty($arrayfields['t.ref']['checked'])) {
862  print_liste_field_titre($arrayfields['t.ref']['label'], $_SERVER["PHP_SELF"], "t.ref", "", $param, "", $sortfield, $sortorder);
863  $totalarray['nbfield']++;
864 }
865 if (!empty($arrayfields['t.label']['checked'])) {
866  print_liste_field_titre($arrayfields['t.label']['label'], $_SERVER["PHP_SELF"], "t.label", "", $param, "", $sortfield, $sortorder);
867  $totalarray['nbfield']++;
868 }
869 if (!empty($arrayfields['t.description']['checked'])) {
870  print_liste_field_titre($arrayfields['t.description']['label'], $_SERVER["PHP_SELF"], "t.description", "", $param, "", $sortfield, $sortorder);
871  $totalarray['nbfield']++;
872 }
873 if (!empty($arrayfields['t.dateo']['checked'])) {
874  print_liste_field_titre($arrayfields['t.dateo']['label'], $_SERVER["PHP_SELF"], "t.dateo", "", $param, '', $sortfield, $sortorder, 'center ');
875  $totalarray['nbfield']++;
876 }
877 if (!empty($arrayfields['t.datee']['checked'])) {
878  print_liste_field_titre($arrayfields['t.datee']['label'], $_SERVER["PHP_SELF"], "t.datee", "", $param, '', $sortfield, $sortorder, 'center ');
879  $totalarray['nbfield']++;
880 }
881 if (!empty($arrayfields['p.ref']['checked'])) {
882  print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER["PHP_SELF"], "p.ref", "", $param, "", $sortfield, $sortorder);
883  $totalarray['nbfield']++;
884 }
885 if (!empty($arrayfields['p.title']['checked'])) {
886  print_liste_field_titre($arrayfields['p.title']['label'], $_SERVER["PHP_SELF"], "p.title", "", $param, "", $sortfield, $sortorder);
887  $totalarray['nbfield']++;
888 }
889 if (!empty($arrayfields['s.nom']['checked'])) {
890  print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER["PHP_SELF"], "s.nom", "", $param, "", $sortfield, $sortorder);
891  $totalarray['nbfield']++;
892 }
893 if (!empty($arrayfields['p.fk_statut']['checked'])) {
894  print_liste_field_titre($arrayfields['p.fk_statut']['label'], $_SERVER["PHP_SELF"], "p.fk_statut", "", $param, '', $sortfield, $sortorder, 'center ');
895  $totalarray['nbfield']++;
896 }
897 if (!empty($arrayfields['t.planned_workload']['checked'])) {
898  print_liste_field_titre($arrayfields['t.planned_workload']['label'], $_SERVER["PHP_SELF"], "t.planned_workload", "", $param, '', $sortfield, $sortorder, 'center ');
899  $totalarray['nbfield']++;
900 }
901 if (!empty($arrayfields['t.duration_effective']['checked'])) {
902  print_liste_field_titre($arrayfields['t.duration_effective']['label'], $_SERVER["PHP_SELF"], "t.duration_effective", "", $param, '', $sortfield, $sortorder, 'center ');
903  $totalarray['nbfield']++;
904 }
905 if (!empty($arrayfields['t.progress_calculated']['checked'])) {
906  print_liste_field_titre($arrayfields['t.progress_calculated']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', '', '', 'center ');
907  $totalarray['nbfield']++;
908 }
909 if (!empty($arrayfields['t.progress']['checked'])) {
910  print_liste_field_titre($arrayfields['t.progress']['label'], $_SERVER["PHP_SELF"], "t.progress", "", $param, '', $sortfield, $sortorder, 'center ');
911  $totalarray['nbfield']++;
912 }
913 if (!empty($arrayfields['t.progress_summary']['checked'])) {
914  print_liste_field_titre($arrayfields['t.progress_summary']['label'], $_SERVER["PHP_SELF"], "t.progress", "", $param, '', $sortfield, $sortorder, 'center ');
915  $totalarray['nbfield']++;
916 }
917 if (!empty($arrayfields['t.budget_amount']['checked'])) {
918  print_liste_field_titre($arrayfields['t.budget_amount']['label'], $_SERVER["PHP_SELF"], "t.budget_amount", "", $param, '', $sortfield, $sortorder, 'center ');
919  $totalarray['nbfield']++;
920 }
921 if (!empty($arrayfields['t.tobill']['checked'])) {
922  print_liste_field_titre($arrayfields['t.tobill']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'center ');
923  $totalarray['nbfield']++;
924 }
925 if (!empty($arrayfields['t.billed']['checked'])) {
926  print_liste_field_titre($arrayfields['t.billed']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'center ');
927  $totalarray['nbfield']++;
928 }
929 // Extra fields
930 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
931 // Hook fields
932 $parameters = array(
933  'arrayfields' => $arrayfields,
934  'param' => $param,
935  'sortfield' => $sortfield,
936  'sortorder' => $sortorder,
937  'totalarray' => &$totalarray,
938 );
939 $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook
940 print $hookmanager->resPrint;
941 if (!empty($arrayfields['t.datec']['checked'])) {
942  print_liste_field_titre($arrayfields['t.datec']['label'], $_SERVER["PHP_SELF"], "t.datec", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
943  $totalarray['nbfield']++;
944 }
945 if (!empty($arrayfields['t.tms']['checked'])) {
946  print_liste_field_titre($arrayfields['t.tms']['label'], $_SERVER["PHP_SELF"], "t.tms", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
947  $totalarray['nbfield']++;
948 }
949 print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
950 $totalarray['nbfield']++;
951 print '</tr>'."\n";
952 
953 $plannedworkloadoutputformat = 'allhourmin';
954 $timespentoutputformat = 'allhourmin';
955 if (!empty($conf->global->PROJECT_PLANNED_WORKLOAD_FORMAT)) {
956  $plannedworkloadoutputformat = $conf->global->PROJECT_PLANNED_WORKLOAD_FORMAT;
957 }
958 if (!empty($conf->global->PROJECT_TIMES_SPENT_FORMAT)) {
959  $timespentoutputformat = $conf->global->PROJECT_TIME_SPENT_FORMAT;
960 }
961 
962 // Loop on record
963 // --------------------------------------------------------------------
964 $i = 0;
965 $savnbfield = $totalarray['nbfield'];
966 $totalarray['nbfield'] = 0;
967 $imaxinloop = ($limit ? min($num, $limit) : $num);
968 while ($i < $imaxinloop) {
969  $obj = $db->fetch_object($resql);
970  if (empty($obj)) {
971  break; // Should not happen
972  }
973 
974  // Store properties in $object
975  $object->id = $obj->id;
976  $object->ref = $obj->ref;
977  $object->label = $obj->label;
978  $object->description = $obj->description;
979  $object->fk_statut = $obj->fk_statut;
980  $object->progress = $obj->progress;
981  $object->budget_amount = $obj->budget_amount;
982  $object->date_start = $db->jdate($obj->date_start);
983  $object->date_end = $db->jdate($obj->date_end);
984  $object->planned_workload = $obj->planned_workload;
985  $object->duration_effective = $obj->duration_effective;
986  $object->fk_task_parent = $obj->fk_task_parent;
987 
988  $projectstatic->id = $obj->projectid;
989  $projectstatic->ref = $obj->projectref;
990  $projectstatic->title = $obj->projecttitle;
991  $projectstatic->public = $obj->public;
992  $projectstatic->statut = $obj->projectstatus;
993  $projectstatic->datee = $db->jdate($obj->projectdatee);
994 
995  if ($mode == 'kanban') {
996  if ($i == 0) {
997  print '<tr><td colspan="'.$savnbfield.'">';
998  print '<div class="box-flex-container">';
999  }
1000  // Output Kanban
1001  print $object->getKanbanView('');
1002  if ($i == ($imaxinloop - 1)) {
1003  print '</div>';
1004  print '</td></tr>';
1005  }
1006  } else {
1007  $userAccess = $projectstatic->restrictedProjectArea($user); // why this ?
1008  if ($userAccess >= 0) {
1009  print '<tr data-rowid="'.$object->id.'" class="oddeven">';
1010 
1011  // Ref Parent
1012  if (!empty($arrayfields['t.fk_task_parent']['checked'])) {
1013  print '<td class="nowraponall">';
1014  if (!empty($object->fk_task_parent)) {
1015  $object_parent = new Task($db);
1016  $result = $object_parent->fetch($object->fk_task_parent);
1017  if ($result < 0) {
1018  setEventMessage($object_parent->error, 'errors');
1019  } else {
1020  print $object_parent->getNomUrl(1, 'withproject');
1021  if ($object_parent->hasDelay()) {
1022  print img_warning("Late");
1023  }
1024  }
1025  }
1026  print '</td>';
1027  if (!$i) {
1028  $totalarray['nbfield']++;
1029  }
1030  }
1031  // Ref
1032  if (!empty($arrayfields['t.ref']['checked'])) {
1033  print '<td class="nowraponall">';
1034  print $object->getNomUrl(1, 'withproject');
1035  if ($object->hasDelay()) {
1036  print img_warning("Late");
1037  }
1038  print '</td>';
1039  if (!$i) {
1040  $totalarray['nbfield']++;
1041  }
1042  }
1043  // Label
1044  if (!empty($arrayfields['t.label']['checked'])) {
1045  print '<td class="tdoverflowmax200" title="'.dol_escape_htmltag($object->label).'">';
1046  print dol_escape_htmltag($object->label);
1047  print '</td>';
1048  if (!$i) {
1049  $totalarray['nbfield']++;
1050  }
1051  }
1052  // Description
1053  if (!empty($arrayfields['t.description']['checked'])) {
1054  print '<td>';
1055  print dolGetFirstLineOfText($object->description, 5);
1056  print '</td>';
1057  if (!$i) {
1058  $totalarray['nbfield']++;
1059  }
1060  }
1061  // Date start
1062  if (!empty($arrayfields['t.dateo']['checked'])) {
1063  print '<td class="center">';
1064  print dol_print_date($db->jdate($obj->date_start), 'day');
1065  print '</td>';
1066  if (!$i) {
1067  $totalarray['nbfield']++;
1068  }
1069  }
1070  // Date end
1071  if (!empty($arrayfields['t.datee']['checked'])) {
1072  print '<td class="center">';
1073  print dol_print_date($db->jdate($obj->date_end), 'day');
1074  print '</td>';
1075  if (!$i) {
1076  $totalarray['nbfield']++;
1077  }
1078  }
1079  // Project ref
1080  if (!empty($arrayfields['p.ref']['checked'])) {
1081  print '<td class="nowraponall tdoverflowmax150">';
1082  print $projectstatic->getNomUrl(1, 'task');
1083  if ($projectstatic->hasDelay()) {
1084  print img_warning("Late");
1085  }
1086  print '</td>';
1087  if (!$i) {
1088  $totalarray['nbfield']++;
1089  }
1090  }
1091  // Project title
1092  if (!empty($arrayfields['p.title']['checked'])) {
1093  print '<td>';
1094  print dol_trunc($obj->projecttitle, 80);
1095  print '</td>';
1096  if (!$i) {
1097  $totalarray['nbfield']++;
1098  }
1099  }
1100  // Third party
1101  if (!empty($arrayfields['s.nom']['checked'])) {
1102  print '<td>';
1103  if ($obj->socid) {
1104  $socstatic->id = $obj->socid;
1105  $socstatic->name = $obj->name;
1106  print $socstatic->getNomUrl(1);
1107  } else {
1108  print '&nbsp;';
1109  }
1110  print '</td>';
1111  if (!$i) {
1112  $totalarray['nbfield']++;
1113  }
1114  }
1115  // Project status
1116  if (!empty($arrayfields['p.fk_statut']['checked'])) {
1117  print '<td class="center">';
1118  print $projectstatic->getLibStatut(1);
1119  print '</td>';
1120  if (!$i) {
1121  $totalarray['nbfield']++;
1122  }
1123  }
1124 
1125  // Planned workload
1126  if (!empty($arrayfields['t.planned_workload']['checked'])) {
1127  print '<td class="center">';
1128  $fullhour = convertSecondToTime($obj->planned_workload, $plannedworkloadoutputformat);
1129  $workingdelay = convertSecondToTime($obj->planned_workload, 'all', 86400, 7); // TODO Replace 86400 and 7 to take account working hours per day and working day per weeks
1130  if ($obj->planned_workload != '') {
1131  print $fullhour;
1132  // TODO Add delay taking account of working hours per day and working day per week
1133  //if ($workingdelay != $fullhour) print '<br>('.$workingdelay.')';
1134  }
1135  //else print '--:--';
1136  print '</td>';
1137  if (!$i) {
1138  $totalarray['nbfield']++;
1139  }
1140  if (!$i) {
1141  $totalarray['pos'][$totalarray['nbfield']] = 't.planned_workload';
1142  }
1143  $totalarray['val']['t.planned_workload'] += $obj->planned_workload;
1144  if (!$i) {
1145  $totalarray['totalplannedworkloadfield'] = $totalarray['nbfield'];
1146  }
1147  $totalarray['totalplannedworkload'] += $obj->planned_workload;
1148  }
1149  // Time spent
1150  if (!empty($arrayfields['t.duration_effective']['checked'])) {
1151  $showlineingray = 0; $showproject = 1;
1152  print '<td class="center">';
1153  if ($showlineingray) {
1154  print '<i>';
1155  } else {
1156  print '<a href="'.DOL_URL_ROOT.'/projet/tasks/time.php?id='.$object->id.($showproject ? '' : '&withproject=1').'">';
1157  }
1158  if ($obj->duration_effective) {
1159  print convertSecondToTime($obj->duration_effective, $timespentoutputformat);
1160  } else {
1161  print '--:--';
1162  }
1163  if ($showlineingray) {
1164  print '</i>';
1165  } else {
1166  print '</a>';
1167  }
1168  print '</td>';
1169  if (!$i) {
1170  $totalarray['nbfield']++;
1171  }
1172  if (!$i) {
1173  $totalarray['pos'][$totalarray['nbfield']] = 't.duration_effective';
1174  }
1175  $totalarray['val']['t.duration_effective'] += $obj->duration_effective;
1176  if (!$i) {
1177  $totalarray['totaldurationeffectivefield'] = $totalarray['nbfield'];
1178  }
1179  $totalarray['totaldurationeffective'] += $obj->duration_effective;
1180  }
1181  // Calculated progress
1182  if (!empty($arrayfields['t.progress_calculated']['checked'])) {
1183  print '<td class="center">';
1184  if ($obj->planned_workload || $obj->duration_effective) {
1185  if ($obj->planned_workload) {
1186  print round(100 * $obj->duration_effective / $obj->planned_workload, 2).' %';
1187  } else {
1188  print $form->textwithpicto('', $langs->trans('WorkloadNotDefined'), 1, 'help');
1189  }
1190  }
1191  print '</td>';
1192  if (!$i) {
1193  $totalarray['nbfield']++;
1194  }
1195  if (!$i) {
1196  $totalarray['totalprogress_calculatedfield'] = $totalarray['nbfield'];
1197  }
1198  }
1199  // Declared progress
1200  if (!empty($arrayfields['t.progress']['checked'])) {
1201  print '<td class="center">';
1202  if ($obj->progress != '') {
1203  print getTaskProgressBadge($object);
1204  }
1205  print '</td>';
1206  if (!$i) {
1207  $totalarray['nbfield']++;
1208  }
1209  if (!$i) {
1210  $totalarray['pos'][$totalarray['nbfield']] = 't.progress';
1211  }
1212  $totalarray['val']['t.progress'] += ($obj->planned_workload * $obj->progress / 100);
1213  if (!$i) {
1214  $totalarray['totalprogress_declaredfield'] = $totalarray['nbfield'];
1215  }
1216  $totalarray['totaldurationdeclared'] += $obj->planned_workload * $obj->progress / 100;
1217  }
1218  // Progress summary
1219  if (!empty($arrayfields['t.progress_summary']['checked'])) {
1220  print '<td class="center">';
1221  if ($obj->progress != '' && $obj->duration_effective) {
1222  print getTaskProgressView($object, false, false);
1223  }
1224  print '</td>';
1225  if (!$i) {
1226  $totalarray['nbfield']++;
1227  }
1228  if (!$i) {
1229  $totalarray['totalprogress_summary'] = $totalarray['nbfield'];
1230  }
1231  }
1232  // Budget for task
1233  if (!empty($arrayfields['t.budget_amount']['checked'])) {
1234  print '<td class="center">';
1235  if ($object->budget_amount) {
1236  print '<span class="amount">'.price($object->budget_amount, 0, $langs, 1, 0, 0, $conf->currency).'</span>';
1237  }
1238  print '</td>';
1239  if (!$i) {
1240  $totalarray['nbfield']++;
1241  }
1242  if (!$i) {
1243  $totalarray['pos'][$totalarray['nbfield']] = 't.budget_amount';
1244  }
1245  $totalarray['val']['t.budget_amount'] += $obj->budget_amount;
1246  if (!$i) {
1247  $totalarray['totalbudget_amountfield'] = $totalarray['nbfield'];
1248  }
1249  $totalarray['totalbudgetamount'] += $obj->budget_amount;
1250  }
1251  // Time not billed
1252  if (!empty($arrayfields['t.tobill']['checked'])) {
1253  print '<td class="center">';
1254  if ($obj->usage_bill_time) {
1255  print convertSecondToTime($obj->tobill, 'allhourmin');
1256  $totalarray['val']['t.tobill'] += $obj->tobill;
1257  $totalarray['totaltobill'] += $obj->tobill;
1258  } else {
1259  print '<span class="opacitymedium">'.$langs->trans("NA").'</span>';
1260  }
1261  print '</td>';
1262  if (!$i) {
1263  $totalarray['nbfield']++;
1264  }
1265  if (!$i) {
1266  $totalarray['pos'][$totalarray['nbfield']] = 't.tobill';
1267  }
1268  if (!$i) {
1269  $totalarray['totaltobillfield'] = $totalarray['nbfield'];
1270  }
1271  }
1272  // Time billed
1273  if (!empty($arrayfields['t.billed']['checked'])) {
1274  print '<td class="center">';
1275  if ($obj->usage_bill_time) {
1276  print convertSecondToTime($obj->billed, 'allhourmin');
1277  $totalarray['val']['t.billed'] += $obj->billed;
1278  $totalarray['totalbilled'] += $obj->billed;
1279  } else {
1280  print '<span class="opacitymedium">'.$langs->trans("NA").'</span>';
1281  }
1282  print '</td>';
1283  if (!$i) {
1284  $totalarray['nbfield']++;
1285  }
1286  if (!$i) {
1287  $totalarray['pos'][$totalarray['nbfield']] = 't.billed';
1288  }
1289  if (!$i) {
1290  $totalarray['totalbilledfield'] = $totalarray['nbfield'];
1291  }
1292  }
1293  // Extra fields
1294  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
1295  // Fields from hook
1296  $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray);
1297  $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook
1298  print $hookmanager->resPrint;
1299  // Date creation
1300  if (!empty($arrayfields['t.datec']['checked'])) {
1301  print '<td class="center">';
1302  print dol_print_date($db->jdate($obj->date_creation), 'dayhour', 'tzuser');
1303  print '</td>';
1304  if (!$i) {
1305  $totalarray['nbfield']++;
1306  }
1307  }
1308  // Date modification
1309  if (!empty($arrayfields['t.tms']['checked'])) {
1310  print '<td class="center">';
1311  print dol_print_date($db->jdate($obj->date_update), 'dayhour', 'tzuser');
1312  print '</td>';
1313  if (!$i) {
1314  $totalarray['nbfield']++;
1315  }
1316  }
1317  // Status
1318  /*if (! empty($arrayfields['p.fk_statut']['checked']))
1319  {
1320  $projectstatic->statut = $obj->fk_statut;
1321  print '<td class="right">'.$projectstatic->getLibStatut(5).'</td>';
1322  }*/
1323  // Action column
1324  print '<td class="nowrap center">';
1325  if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
1326  $selected = 0;
1327  if (in_array($object->id, $arrayofselected)) {
1328  $selected = 1;
1329  }
1330  print '<input id="cb'.$object->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$object->id.'"'.($selected ? ' checked="checked"' : '').'>';
1331  }
1332  print '</td>';
1333  if (!$i) {
1334  $totalarray['nbfield']++;
1335  }
1336 
1337  print '</tr>'."\n";
1338  }
1339  }
1340 
1341  $i++;
1342 }
1343 
1344 // Show total line
1345 if (isset($totalarray['totaldurationeffectivefield']) || isset($totalarray['totalplannedworkloadfield']) || isset($totalarray['totalprogress_calculatedfield'])
1346  || isset($totalarray['totaltobill']) || isset($totalarray['totalbilled']) || isset($totalarray['totalbudget'])) {
1347  print '<tr class="liste_total">';
1348  $i = 0;
1349  while ($i < $totalarray['nbfield']) {
1350  $i++;
1351  if ($i == 1) {
1352  if ($num < $limit && empty($offset)) {
1353  print '<td class="left">'.$langs->trans("Total").'</td>';
1354  } else {
1355  print '<td class="left">'.$langs->trans("Totalforthispage").'</td>';
1356  }
1357  } elseif ($totalarray['totalplannedworkloadfield'] == $i) {
1358  print '<td class="center">'.convertSecondToTime($totalarray['totalplannedworkload'], $plannedworkloadoutputformat).'</td>';
1359  } elseif ($totalarray['totaldurationeffectivefield'] == $i) {
1360  print '<td class="center">'.convertSecondToTime($totalarray['totaldurationeffective'], $timespentoutputformat).'</td>';
1361  } elseif ($totalarray['totalprogress_calculatedfield'] == $i) {
1362  print '<td class="center">'.($totalarray['totalplannedworkload'] > 0 ? round(100 * $totalarray['totaldurationeffective'] / $totalarray['totalplannedworkload'], 2).' %' : '').'</td>';
1363  } elseif ($totalarray['totalprogress_declaredfield'] == $i) {
1364  print '<td class="center">'.($totalarray['totalplannedworkload'] > 0 ? round(100 * $totalarray['totaldurationdeclared'] / $totalarray['totalplannedworkload'], 2).' %' : '').'</td>';
1365  } elseif ($totalarray['totaltobillfield'] == $i) {
1366  print '<td class="center">'.convertSecondToTime($totalarray['totaltobill'], $plannedworkloadoutputformat).'</td>';
1367  } elseif ($totalarray['totalbilledfield'] == $i) {
1368  print '<td class="center">'.convertSecondToTime($totalarray['totalbilled'], $plannedworkloadoutputformat).'</td>';
1369  } elseif ($totalarray['totalbudget_amountfield'] == $i) {
1370  print '<td class="center">'.price($totalarray['totalbudgetamount'], 0, $langs, 1, 0, 0, $conf->currency).'</td>';
1371  } else {
1372  print '<td></td>';
1373  }
1374  }
1375  print '</tr>';
1376 }
1377 
1378 $db->free($resql);
1379 
1380 $parameters = array('arrayfields'=>$arrayfields, 'sql' => $sql);
1381 $reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters); // Note that $action and $object may have been modified by hook
1382 print $hookmanager->resPrint;
1383 
1384 print '</table>'."\n";
1385 print '</div>'."\n";
1386 
1387 print '</form>'."\n";
1388 
1389 // End of page
1390 llxFooter();
1391 $db->close();
Societe
Class to manage third parties objects (customers, suppliers, prospects...)
Definition: societe.class.php:48
dol_escape_htmltag
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields.
Definition: functions.lib.php:1468
dol_trunc
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
Definition: functions.lib.php:3805
llxFooter
llxFooter()
Empty footer.
Definition: wrapper.php:73
Project
Class to manage projects.
Definition: project.class.php:35
GETPOST
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
Definition: functions.lib.php:484
dol_print_error
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
Definition: functions.lib.php:4844
dol_sort_array
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by second index function, which produces ascending (default) or descending output...
Definition: functions.lib.php:8385
img_warning
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
Definition: functions.lib.php:4521
Task
Class to manage tasks.
Definition: task.class.php:37
$form
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:142
FormOther
Classe permettant la generation de composants html autre Only common components are here.
Definition: html.formother.class.php:39
$help_url
if(GETPOST('button_removefilter_x', 'alpha')||GETPOST('button_removefilter.x', 'alpha')||GETPOST('button_removefilter', 'alpha')) if(GETPOST('button_search_x', 'alpha')||GETPOST('button_search.x', 'alpha')||GETPOST('button_search', 'alpha')) if($action=="save" &&empty($cancel)) $help_url
View.
Definition: agenda.php:116
convertSecondToTime
convertSecondToTime($iSecond, $format='all', $lengthOfDay=86400, $lengthOfWeek=7)
Return, in clear text, value of a number of seconds in days, hours and minutes.
Definition: date.lib.php:236
getTaskProgressView
getTaskProgressView($task, $label=true, $progressNumber=true, $hideOnProgressNull=false, $spaced=false)
Definition: project.lib.php:2723
dol_print_date
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
Definition: functions.lib.php:2514
img_picto
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
Definition: functions.lib.php:3880
dolGetButtonTitle
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.
Definition: functions.lib.php:10605
dol_syslog
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
Definition: functions.lib.php:1603
setEventMessage
setEventMessage($mesgs, $style='mesgs')
Set event message in dol_events session object.
Definition: functions.lib.php:8108
print_barre_liste
print_barre_liste($titre, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $hideselectlimit=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
Definition: functions.lib.php:5257
getTaskProgressBadge
getTaskProgressBadge($task, $label='', $tooltip='')
Definition: project.lib.php:2855
User
Class to manage Dolibarr users.
Definition: user.class.php:44
GETPOSTISSET
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
Definition: functions.lib.php:386
print_liste_field_titre
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
Definition: functions.lib.php:5026
natural_search
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...
Definition: functions.lib.php:9420
ExtraFields
Class to manage standard extra fields.
Definition: extrafields.class.php:39
Form
Class to manage generation of HTML components Only common components must be here.
Definition: html.form.class.php:52
dol_now
dol_now($mode='auto')
Return date for now.
Definition: functions.lib.php:2845
$resql
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire)||(isModEnabled('supplier_invoice') && $user->rights->supplier_invoice->lire)) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:742
setEventMessages
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
Definition: functions.lib.php:8137
dolGetFirstLineOfText
dolGetFirstLineOfText($text, $nboflines=1, $charset='UTF-8')
Return first line of text.
Definition: functions.lib.php:6907
accessforbidden
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program Calling this function terminate execution ...
Definition: security.lib.php:933
dol_mktime
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
Definition: functions.lib.php:2757
llxHeader
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOCSRFCHECK')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:59