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