dolibarr  13.0.2
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  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <https://www.gnu.org/licenses/>.
19  */
20 
27 require "../../main.inc.php";
28 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
29 require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
30 require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
31 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
32 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
33 
34 // Load translation files required by the page
35 $langs->loadLangs(array('projects', 'users', 'companies'));
36 
37 $action = GETPOST('action', 'aZ09');
38 $massaction = GETPOST('massaction', 'alpha');
39 $show_files = GETPOST('show_files', 'int');
40 $confirm = GETPOST('confirm', 'alpha');
41 $toselect = GETPOST('toselect', 'array');
42 
43 $id = GETPOST('id', 'int');
44 
45 $search_all = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'));
46 $search_categ = GETPOST("search_categ", 'alpha');
47 $search_project = GETPOST('search_project');
48 
49 $search_projectstatus = GETPOST('search_projectstatus');
50 if (!isset($search_projectstatus) || $search_projectstatus === '')
51 {
52  if ($search_all != '') $search_projectstatus = -1;
53  else $search_projectstatus = 1;
54 }
55 
56 $search_project_ref = GETPOST('search_project_ref');
57 $search_project_title = GETPOST('search_project_title');
58 $search_task_ref = GETPOST('search_task_ref');
59 $search_task_label = GETPOST('search_task_label');
60 $search_task_description = GETPOST('search_task_description');
61 $search_task_ref_parent = GETPOST('search_task_ref_parent');
62 $search_project_user = GETPOST('search_project_user');
63 $search_task_user = GETPOST('search_task_user');
64 $search_task_progress = GETPOST('search_task_progress');
65 $search_societe = GETPOST('search_societe');
66 
67 $mine = $_REQUEST['mode'] == 'mine' ? 1 : 0;
68 if ($mine) { $search_task_user = $user->id; $mine = 0; }
69 
70 $search_sday = GETPOST('search_sday', 'int');
71 $search_smonth = GETPOST('search_smonth', 'int');
72 $search_syear = GETPOST('search_syear', 'int');
73 $search_eday = GETPOST('search_eday', 'int');
74 $search_emonth = GETPOST('search_emonth', 'int');
75 $search_eyear = GETPOST('search_eyear', 'int');
76 
77 // Initialize context for list
78 $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'tasklist';
79 
80 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
81 $object = new Task($db);
82 $hookmanager->initHooks(array('tasklist'));
83 $extrafields = new ExtraFields($db);
84 
85 // fetch optionals attributes and labels
86 $extrafields->fetch_name_optionals_label($object->table_element);
87 $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
88 
89 // Security check
90 $socid = 0;
91 //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.
92 if (!$user->rights->projet->lire) accessforbidden();
93 
94 $diroutputmassaction = $conf->projet->dir_output.'/tasks/temp/massgeneration/'.$user->id;
95 
96 $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
97 $sortfield = GETPOST("sortfield", 'alpha');
98 $sortorder = GETPOST("sortorder", 'alpha');
99 $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
100 if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1
101 $offset = $limit * $page;
102 $pageprev = $page - 1;
103 $pagenext = $page + 1;
104 if (!$sortfield) $sortfield = 'p.ref';
105 if (!$sortorder) $sortorder = 'DESC';
106 
107 // List of fields to search into when doing a "search in all"
108 $fieldstosearchall = array(
109  't.ref'=>"Ref",
110  't.label'=>"Label",
111  't.description'=>"Description",
112  't.note_public'=>"NotePublic",
113 );
114 if (empty($user->socid)) $fieldstosearchall['t.note_private'] = "NotePrivate";
115 
116 $arrayfields = array(
117  't.fk_task_parent'=>array('label'=>$langs->trans("RefTaskParent"), 'checked'=>0, 'position'=>70),
118  't.ref'=>array('label'=>$langs->trans("RefTask"), 'checked'=>1, 'position'=>80),
119  't.label'=>array('label'=>$langs->trans("LabelTask"), 'checked'=>1, 'position'=>80),
120  't.description'=>array('label'=>$langs->trans("Description"), 'checked'=>0, 'position'=>80),
121  't.dateo'=>array('label'=>$langs->trans("DateStart"), 'checked'=>1, 'position'=>100),
122  't.datee'=>array('label'=>$langs->trans("Deadline"), 'checked'=>1, 'position'=>101),
123  'p.ref'=>array('label'=>$langs->trans("ProjectRef"), 'checked'=>1),
124  'p.title'=>array('label'=>$langs->trans("ProjectLabel"), 'checked'=>0),
125  's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>0),
126  'p.fk_statut'=>array('label'=>$langs->trans("ProjectStatus"), 'checked'=>1),
127  't.planned_workload'=>array('label'=>$langs->trans("PlannedWorkload"), 'checked'=>1, 'position'=>102),
128  't.duration_effective'=>array('label'=>$langs->trans("TimeSpent"), 'checked'=>1, 'position'=>103),
129  't.progress_calculated'=>array('label'=>$langs->trans("ProgressCalculated"), 'checked'=>1, 'position'=>104),
130  't.progress'=>array('label'=>$langs->trans("ProgressDeclared"), 'checked'=>1, 'position'=>105),
131  't.progress_summary'=>array('label'=>$langs->trans("TaskProgressSummary"), 'checked'=>1, 'position'=>106),
132  't.tobill'=>array('label'=>$langs->trans("TimeToBill"), 'checked'=>0, 'position'=>110),
133  't.billed'=>array('label'=>$langs->trans("TimeBilled"), 'checked'=>0, 'position'=>111),
134  't.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500),
135  't.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500),
136  //'t.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000),
137 );
138 // Extra fields
139 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
140 
141 $object->fields = dol_sort_array($object->fields, 'position');
142 $arrayfields = dol_sort_array($arrayfields, 'position');
143 
144 
145 /*
146  * Actions
147  */
148 
149 if (GETPOST('cancel', 'alpha')) { $action = 'list'; $massaction = ''; }
150 if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend' && $massaction != 'confirm_createbills') { $massaction = ''; }
151 
152 $parameters = array('socid'=>$socid);
153 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
154 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
155 
156 if (empty($reshook))
157 {
158  // Selection of new fields
159  include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
160 
161  // Purge search criteria
162  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
163  {
164  $search_all = "";
165  $search_categ = "";
166  $search_project = "";
167  $search_projectstatus = -1;
168  $search_project_ref = "";
169  $search_project_title = "";
170  $search_task_ref = "";
171  $search_task_label = "";
172  $search_task_description = "";
173  $search_task_ref_parent = "";
174  $search_task_progress = "";
175  $search_task_user = -1;
176  $search_project_user = -1;
177  $search_sday = '';
178  $search_smonth = '';
179  $search_syear = '';
180  $search_eday = '';
181  $search_emonth = '';
182  $search_eyear = '';
183  $toselect = '';
184  $search_array_options = array();
185  }
186 
187  // Mass actions
188  $objectclass = 'Task';
189  $objectlabel = 'Tasks';
190  $permissiontoread = $user->rights->projet->lire;
191  $permissiontodelete = $user->rights->projet->supprimer;
192  $uploaddir = $conf->projet->dir_output.'/tasks';
193  include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
194 }
195 
196 if (empty($search_projectstatus) && $search_projectstatus == '') $search_projectstatus = 1;
197 
198 
199 
200 
201 /*
202  * View
203  */
204 
205 $now = dol_now();
206 $form = new Form($db);
207 $formother = new FormOther($db);
208 $socstatic = new Societe($db);
209 $projectstatic = new Project($db);
210 $puser = new User($db);
211 $tuser = new User($db);
212 if ($search_project_user > 0) $puser->fetch($search_project_user);
213 if ($search_task_user > 0) $tuser->fetch($search_task_user);
214 
215 
216 $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
217 $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
218 
219 
220 $title = $langs->trans("Activities");
221 //if ($search_task_user == $user->id) $title=$langs->trans("MyActivities");
222 
223 if ($id)
224 {
225  $projectstatic->fetch($id);
226  $projectstatic->fetch_thirdparty();
227 }
228 
229 // Get list of project id allowed to user (in a string list separated by coma)
230 if (!$user->rights->projet->all->lire) $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, $socid);
231 //var_dump($projectsListId);
232 
233 // Get id of types of contacts for projects (This list never contains a lot of elements)
234 $listofprojectcontacttype = array();
235 $sql = "SELECT ctc.rowid, ctc.code FROM ".MAIN_DB_PREFIX."c_type_contact as ctc";
236 $sql .= " WHERE ctc.element = '".$db->escape($projectstatic->element)."'";
237 $sql .= " AND ctc.source = 'internal'";
238 $resql = $db->query($sql);
239 if ($resql)
240 {
241  while ($obj = $db->fetch_object($resql))
242  {
243  $listofprojectcontacttype[$obj->rowid] = $obj->code;
244  }
245 } else dol_print_error($db);
246 if (count($listofprojectcontacttype) == 0) $listofprojectcontacttype[0] = '0'; // To avoid sql syntax error if not found
247 // Get id of types of contacts for tasks (This list never contains a lot of elements)
248 $listoftaskcontacttype = array();
249 $sql = "SELECT ctc.rowid, ctc.code FROM ".MAIN_DB_PREFIX."c_type_contact as ctc";
250 $sql .= " WHERE ctc.element = '".$db->escape($object->element)."'";
251 $sql .= " AND ctc.source = 'internal'";
252 $resql = $db->query($sql);
253 if ($resql)
254 {
255  while ($obj = $db->fetch_object($resql))
256  {
257  $listoftaskcontacttype[$obj->rowid] = $obj->code;
258  }
259 } else dol_print_error($db);
260 if (count($listoftaskcontacttype) == 0) $listoftaskcontacttype[0] = '0'; // To avoid sql syntax error if not found
261 
262 $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.
263 $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,";
264 $sql .= " s.nom as name, s.rowid as socid,";
265 $sql .= " t.datec as date_creation, t.dateo as date_start, t.datee as date_end, t.tms as date_update,";
266 $sql .= " t.rowid as id, t.ref, t.label, t.planned_workload, t.duration_effective, t.progress, t.fk_statut, ";
267 $sql .= " t.description, t.fk_task_parent";
268 // We'll need these fields in order to filter by categ
269 if ($search_categ) $sql .= ", cs.fk_categorie, cs.fk_project";
270 // Add sum fields
271 if (!empty($arrayfields['t.tobill']['checked']) || !empty($arrayfields['t.billed']['checked']))
272 {
273  $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";
274 }
275 // Add fields from extrafields
276 if (!empty($extrafields->attributes[$object->table_element]['label'])) {
277  foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key.' as options_'.$key : '');
278 }
279 // Add fields from hooks
280 $parameters = array();
281 $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook
282 $sql .= $hookmanager->resPrint;
283 $sql .= " FROM ".MAIN_DB_PREFIX."projet as p";
284 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid";
285 // We'll need this table joined to the select in order to filter by categ
286 if (!empty($search_categ)) $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
287 $sql .= ", ".MAIN_DB_PREFIX."projet_task as t";
288 if (!empty($arrayfields['t.tobill']['checked']) || !empty($arrayfields['t.billed']['checked']))
289 {
290  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_time as tt ON tt.fk_task = t.rowid";
291 }
292 if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)";
293 if ($search_project_user > 0) $sql .= ", ".MAIN_DB_PREFIX."element_contact as ecp";
294 if ($search_task_user > 0) $sql .= ", ".MAIN_DB_PREFIX."element_contact as ect";
295 $sql .= " WHERE t.fk_projet = p.rowid";
296 $sql .= " AND p.entity IN (".getEntity('project').')';
297 if (!$user->rights->projet->all->lire) $sql .= " AND p.rowid IN (".($projectsListId ? $projectsListId : '0').")"; // public and assigned to projects, or restricted to company for external users
298 if (is_object($projectstatic) && $projectstatic->id > 0) $sql .= " AND p.rowid = ".$projectstatic->id;
299 // No need to check company, as filtering of projects must be done by getProjectsAuthorizedForUser
300 if ($socid) $sql .= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")";
301 if ($search_categ > 0) $sql .= " AND cs.fk_categorie = ".$db->escape($search_categ);
302 if ($search_categ == -2) $sql .= " AND cs.fk_categorie IS NULL";
303 if ($search_project_ref) $sql .= natural_search('p.ref', $search_project_ref);
304 if ($search_project_title) $sql .= natural_search('p.title', $search_project_title);
305 if ($search_task_ref) $sql .= natural_search('t.ref', $search_task_ref);
306 if ($search_task_label) $sql .= natural_search('t.label', $search_task_label);
307 if ($search_task_description) $sql .= natural_search('t.description', $search_task_description);
308 if ($search_task_ref_parent) $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).')';
309 if ($search_task_progress) $sql .= natural_search('t.progress', $search_task_progress, 1);
310 if ($search_societe) $sql .= natural_search('s.nom', $search_societe);
311 $sql .= dolSqlDateFilter('t.dateo', $search_sday, $search_smonth, $search_syear);
312 $sql .= dolSqlDateFilter('t.datee', $search_eday, $search_emonth, $search_eyear);
313 if ($search_all) $sql .= natural_search(array_keys($fieldstosearchall), $search_all);
314 if ($search_projectstatus >= 0)
315 {
316  if ($search_projectstatus == 99) $sql .= " AND p.fk_statut <> 2";
317  else $sql .= " AND p.fk_statut = ".$db->escape($search_projectstatus);
318 }
319 if ($search_public != '') $sql .= " AND p.public = ".$db->escape($search_public);
320 if ($search_project_user > 0) $sql .= " AND ecp.fk_c_type_contact IN (".join(',', array_keys($listofprojectcontacttype)).") AND ecp.element_id = p.rowid AND ecp.fk_socpeople = ".$search_project_user;
321 if ($search_task_user > 0) $sql .= " AND ect.fk_c_type_contact IN (".join(',', array_keys($listoftaskcontacttype)).") AND ect.element_id = t.rowid AND ect.fk_socpeople = ".$search_task_user;
322 // Add where from extra fields
323 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
324 // Add where from hooks
325 $parameters = array();
326 $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
327 $sql .= $hookmanager->resPrint;
328 if (!empty($arrayfields['t.tobill']['checked']) || !empty($arrayfields['t.billed']['checked']))
329 {
330  $sql .= " GROUP BY p.rowid, p.ref, p.title, p.fk_statut, p.datee, p.fk_opp_status, p.public, p.fk_user_creat,";
331  $sql .= " s.nom, s.rowid,";
332  $sql .= " t.datec, t.dateo, t.datee, t.tms,";
333  $sql .= " t.rowid, t.ref, t.label, t.planned_workload, t.duration_effective, t.progress, t.fk_statut";
334  if ($search_categ) $sql .= ", cs.fk_categorie, cs.fk_project";
335  // Add fields from extrafields
336  if (!empty($extrafields->attributes[$object->table_element]['label'])) {
337  foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key : '');
338  }
339 }
340 $sql .= $db->order($sortfield, $sortorder);
341 
342 $nbtotalofrecords = '';
343 if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
344 {
345  $result = $db->query($sql);
346  $nbtotalofrecords = $db->num_rows($result);
347  if (($page * $limit) > $nbtotalofrecords) // if total resultset is smaller then paging size (filtering), goto and load page 0
348  {
349  $page = 0;
350  $offset = 0;
351  }
352 }
353 
354 $sql .= $db->plimit($limit + 1, $offset);
355 
356 dol_syslog("list allowed project", LOG_DEBUG);
357 
358 $resql = $db->query($sql);
359 if (!$resql)
360 {
361  dol_print_error($db);
362  exit;
363 }
364 
365 $num = $db->num_rows($resql);
366 
367 $arrayofselected = is_array($toselect) ? $toselect : array();
368 
369 if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all)
370 {
371  $obj = $db->fetch_object($resql);
372  $id = $obj->id;
373  header("Location: ".DOL_URL_ROOT.'/projet/tasks/task.php?id='.$id.'&withproject=1');
374  exit;
375 }
376 
377 $help_url = "EN:Module_Projects|FR:Module_Projets|ES:M&oacute;dulo_Proyectos";
378 llxHeader("", $title, $help_url);
379 
380 $param = '';
381 if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.urlencode($contextpage);
382 if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.urlencode($limit);
383 if ($search_sday) $param .= '&search_sday='.urlencode($search_sday);
384 if ($search_smonth) $param .= '&search_smonth='.urlencode($search_smonth);
385 if ($search_syear) $param .= '&search_syear='.urlencode($search_syear);
386 if ($search_eday) $param .= '&search_eday='.urlencode($search_eday);
387 if ($search_emonth) $param .= '&search_emonth='.urlencode($search_emonth);
388 if ($search_eyear) $param .= '&search_eyear='.urlencode($search_eyear);
389 if ($socid) $param .= '&socid='.urlencode($socid);
390 if ($search_all != '') $param .= '&search_all='.urlencode($search_all);
391 if ($search_project_ref != '') $param .= '&search_project_ref='.urlencode($search_project_ref);
392 if ($search_project_title != '') $param .= '&search_project_title='.urlencode($search_project_title);
393 if ($search_task_ref != '') $param .= '&search_task_ref='.urlencode($search_ref);
394 if ($search_task_label != '') $param .= '&search_task_label='.urlencode($search_label);
395 if ($search_task_description != '') $param .= '&search_task_description='.urlencode($search_description);
396 if ($search_task_ref_parent != '') $param .= '&search_task_ref_parent='.urlencode($search_task_ref_parent);
397 if ($search_task_progress != '') $param .= '&search_task_progress='.urlencode($search_task_progress);
398 if ($search_societe != '') $param .= '&search_societe='.urlencode($search_societe);
399 if ($search_projectstatus != '') $param .= '&search_projectstatus='.urlencode($search_projectstatus);
400 if ((is_numeric($search_opp_status) && $search_opp_status >= 0) || in_array($search_opp_status, array('all', 'none'))) $param .= '&search_opp_status='.urlencode($search_opp_status);
401 if ($search_public != '') $param .= '&search_public='.urlencode($search_public);
402 if ($search_project_user != '') $param .= '&search_project_user='.urlencode($search_project_user);
403 if ($search_task_user > 0) $param .= '&search_task_user='.urlencode($search_task_user);
404 if ($optioncss != '') $param .= '&optioncss='.urlencode($optioncss);
405 // Add $param from extra fields
406 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
407 
408 // List of mass actions available
409 $arrayofmassactions = array(
410 // 'presend'=>$langs->trans("SendByMail"),
411 // 'builddoc'=>$langs->trans("PDFMerge"),
412 );
413 //if($user->rights->societe->creer) $arrayofmassactions['createbills']=$langs->trans("CreateInvoiceForThisCustomer");
414 if ($user->rights->societe->supprimer) $arrayofmassactions['predelete'] = '<span class="fa fa-trash paddingrightonly"></span>'.$langs->trans("Delete");
415 if (in_array($massaction, array('presend', 'predelete'))) $arrayofmassactions = array();
416 $massactionbutton = $form->selectMassAction('', $arrayofmassactions);
417 
418 $newcardbutton = dolGetButtonTitle($langs->trans('NewTask'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/projet/tasks.php?action=create', '', $user->rights->projet->creer);
419 
420 print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
421 if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
422 print '<input type="hidden" name="token" value="'.newToken().'">';
423 print '<input type="hidden" name="action" value="list">';
424 print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
425 print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
426 print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
427 print '<input type="hidden" name="type" value="'.$type.'">';
428 print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
429 
430 // Show description of content
431 $texthelp = '';
432 if ($search_task_user == $user->id) $texthelp .= $langs->trans("MyTasksDesc");
433 else {
434  if ($user->rights->projet->all->lire && !$socid) $texthelp .= $langs->trans("TasksOnProjectsDesc");
435  else $texthelp .= $langs->trans("TasksOnProjectsPublicDesc");
436 }
437 
438 print_barre_liste($form->textwithpicto($title, $texthelp), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'projecttask', 0, $newcardbutton, '', $limit, 0, 0, 1);
439 
440 $topicmail = "Information";
441 $modelmail = "task";
442 $objecttmp = new Task($db);
443 $trackid = 'tas'.$object->id;
444 include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
445 
446 if ($search_all)
447 {
448  foreach ($fieldstosearchall as $key => $val) $fieldstosearchall[$key] = $langs->trans($val);
449  print '<div class="divsearchfieldfilter">'.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'</div>';
450 }
451 
452 $morehtmlfilter = '';
453 
454 // Filter on categories
455 if (!empty($conf->categorie->enabled) && $user->rights->categorie->lire)
456 {
457  require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
458  $moreforfilter .= '<div class="divsearchfield">';
459  $moreforfilter .= $langs->trans('ProjectCategories').': ';
460  $moreforfilter .= $formother->select_categories('project', $search_categ, 'search_categ', 1, 'maxwidth300');
461  $moreforfilter .= '</div>';
462 }
463 
464 // If the user can view users
465 $moreforfilter .= '<div class="divsearchfield">';
466 $moreforfilter .= $langs->trans('ProjectsWithThisUserAsContact').' ';
467 $includeonly = '';
468 if (empty($user->rights->user->user->lire)) $includeonly = array($user->id);
469 $moreforfilter .= $form->select_dolusers($search_project_user ? $search_project_user : '', 'search_project_user', 1, '', 0, $includeonly, '', 0, 0, 0, '', 0, '', 'maxwidth200');
470 $moreforfilter .= '</div>';
471 
472 // If the user can view users
473 $moreforfilter .= '<div class="divsearchfield">';
474 $moreforfilter .= $langs->trans('TasksWithThisUserAsContact').': ';
475 $includeonly = '';
476 if (empty($user->rights->user->user->lire)) $includeonly = array($user->id);
477 $moreforfilter .= $form->select_dolusers($search_task_user, 'search_task_user', 1, '', 0, $includeonly, '', 0, 0, 0, '', 0, '', 'maxwidth200');
478 $moreforfilter .= '</div>';
479 
480 if (!empty($moreforfilter))
481 {
482  print '<div class="liste_titre liste_titre_bydiv centpercent">';
483  print $moreforfilter;
484  $parameters = array();
485  $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
486  print $hookmanager->resPrint;
487  print '</div>';
488 }
489 
490 if ($massactionbutton) $selectedfields .= $form->showCheckAddButtons('checkforselect', 1);
491 
492 print '<div class="div-table-responsive">';
493 print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'" id="tablelines3">'."\n";
494 
495 print '<tr class="liste_titre_filter">';
496 if (!empty($arrayfields['t.fk_task_parent']['checked']))
497 {
498  print '<td class="liste_titre">';
499  print '<input type="text" class="flat" name="search_task_ref_parent" value="'.dol_escape_htmltag($search_task_ref_parent).'" size="4">';
500  print '</td>';
501 }
502 if (!empty($arrayfields['t.ref']['checked']))
503 {
504  print '<td class="liste_titre">';
505  print '<input type="text" class="flat" name="search_task_ref" value="'.dol_escape_htmltag($search_task_ref).'" size="4">';
506  print '</td>';
507 }
508 if (!empty($arrayfields['t.label']['checked']))
509 {
510  print '<td class="liste_titre">';
511  print '<input type="text" class="flat" name="search_task_label" value="'.dol_escape_htmltag($search_task_label).'" size="8">';
512  print '</td>';
513 }
514 // Task Description
515 if (!empty($arrayfields['t.description']['checked']))
516 {
517  print '<td class="liste_titre">';
518  print '<input type="text" class="flat" name="search_task_description" value="'.dol_escape_htmltag($search_task_description).'" size="8">';
519  print '</td>';
520 }
521 // Start date
522 if (!empty($arrayfields['t.dateo']['checked']))
523 {
524  print '<td class="liste_titre center minwidth150">';
525  if (!empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat" type="text" size="1" maxlength="2" name="search_sday" value="'.$search_sday.'">';
526  print '<input class="flat" type="text" size="1" maxlength="2" name="search_smonth" value="'.$search_smonth.'">';
527  $formother->select_year($search_syear ? $search_syear : -1, 'search_syear', 1, 20, 5);
528  print '</td>';
529 }
530 // End date
531 if (!empty($arrayfields['t.datee']['checked']))
532 {
533  print '<td class="liste_titre center minwidth150">';
534  if (!empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) print '<input class="flat" type="text" size="1" maxlength="2" name="search_eday" value="'.$search_eday.'">';
535  print '<input class="flat" type="text" size="1" maxlength="2" name="search_emonth" value="'.$search_emonth.'">';
536  $formother->select_year($search_eyear ? $search_eyear : -1, 'search_eyear', 1, 20, 5);
537  print '</td>';
538 }
539 if (!empty($arrayfields['p.ref']['checked']))
540 {
541  print '<td class="liste_titre">';
542  print '<input type="text" class="flat" name="search_project_ref" value="'.$search_project_ref.'" size="4">';
543  print '</td>';
544 }
545 if (!empty($arrayfields['p.title']['checked']))
546 {
547  print '<td class="liste_titre">';
548  print '<input type="text" class="flat" name="search_project_title" value="'.$search_project_title.'" size="6">';
549  print '</td>';
550 }
551 if (!empty($arrayfields['s.nom']['checked']))
552 {
553  print '<td class="liste_titre">';
554  print '<input type="text" class="flat" name="search_societe" value="'.dol_escape_htmltag($search_societe).'" size="4">';
555  print '</td>';
556 }
557 if (!empty($arrayfields['p.fk_statut']['checked']))
558 {
559  print '<td class="liste_titre center">';
560  $arrayofstatus = array();
561  foreach ($projectstatic->statuts_short as $key => $val) $arrayofstatus[$key] = $langs->trans($val);
562  $arrayofstatus['99'] = $langs->trans("NotClosed").' ('.$langs->trans('Draft').'+'.$langs->trans('Opened').')';
563  print $form->selectarray('search_projectstatus', $arrayofstatus, $search_projectstatus, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100');
564  print '</td>';
565 }
566 if (!empty($arrayfields['t.planned_workload']['checked'])) print '<td class="liste_titre"></td>';
567 if (!empty($arrayfields['t.duration_effective']['checked'])) print '<td class="liste_titre"></td>';
568 if (!empty($arrayfields['t.progress_calculated']['checked'])) print '<td class="liste_titre"></td>';
569 if (!empty($arrayfields['t.progress']['checked']))
570 {
571  print '<td class="liste_titre center">';
572  print '<input type="text" class="flat" name="search_task_progress" value="'.$search_task_progress.'" size="4">';
573  print '</td>';
574 }
575 
576 if (!empty($arrayfields['t.progress_summary']['checked'])) print '<td class="liste_titre"></td>';
577 if (!empty($arrayfields['t.tobill']['checked'])) print '<td class="liste_titre"></td>';
578 if (!empty($arrayfields['t.billed']['checked'])) print '<td class="liste_titre"></td>';
579 // Extra fields
580 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
581 // Fields from hook
582 $parameters = array('arrayfields'=>$arrayfields);
583 $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook
584 print $hookmanager->resPrint;
585 if (!empty($arrayfields['t.datec']['checked']))
586 {
587  // Date creation
588  print '<td class="liste_titre">';
589  print '</td>';
590 }
591 if (!empty($arrayfields['t.tms']['checked']))
592 {
593  // Date modification
594  print '<td class="liste_titre">';
595  print '</td>';
596 }
597 // Action column
598 print '<td class="liste_titre maxwidthsearch">';
599 $searchpicto = $form->showFilterButtons();
600 print $searchpicto;
601 print '</td>';
602 print "</tr>\n";
603 
604 print '<tr class="liste_titre">';
605 if (!empty($arrayfields['t.fk_task_parent']['checked'])) print_liste_field_titre($arrayfields['t.fk_task_parent']['label'], $_SERVER["PHP_SELF"], "t.fk_task_parent", "", $param, "", $sortfield, $sortorder);
606 if (!empty($arrayfields['t.ref']['checked'])) print_liste_field_titre($arrayfields['t.ref']['label'], $_SERVER["PHP_SELF"], "t.ref", "", $param, "", $sortfield, $sortorder);
607 if (!empty($arrayfields['t.label']['checked'])) print_liste_field_titre($arrayfields['t.label']['label'], $_SERVER["PHP_SELF"], "t.label", "", $param, "", $sortfield, $sortorder);
608 if (!empty($arrayfields['t.description']['checked'])) print_liste_field_titre($arrayfields['t.description']['label'], $_SERVER["PHP_SELF"], "t.description", "", $param, "", $sortfield, $sortorder);
609 if (!empty($arrayfields['t.dateo']['checked'])) print_liste_field_titre($arrayfields['t.dateo']['label'], $_SERVER["PHP_SELF"], "t.dateo", "", $param, '', $sortfield, $sortorder, 'center ');
610 if (!empty($arrayfields['t.datee']['checked'])) print_liste_field_titre($arrayfields['t.datee']['label'], $_SERVER["PHP_SELF"], "t.datee", "", $param, '', $sortfield, $sortorder, 'center ');
611 if (!empty($arrayfields['p.ref']['checked'])) print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER["PHP_SELF"], "p.ref", "", $param, "", $sortfield, $sortorder);
612 if (!empty($arrayfields['p.title']['checked'])) print_liste_field_titre($arrayfields['p.title']['label'], $_SERVER["PHP_SELF"], "p.title", "", $param, "", $sortfield, $sortorder);
613 if (!empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER["PHP_SELF"], "s.nom", "", $param, "", $sortfield, $sortorder);
614 if (!empty($arrayfields['p.fk_statut']['checked'])) print_liste_field_titre($arrayfields['p.fk_statut']['label'], $_SERVER["PHP_SELF"], "p.fk_statut", "", $param, '', $sortfield, $sortorder, 'center ');
615 if (!empty($arrayfields['t.planned_workload']['checked'])) print_liste_field_titre($arrayfields['t.planned_workload']['label'], $_SERVER["PHP_SELF"], "t.planned_workload", "", $param, '', $sortfield, $sortorder, 'center ');
616 if (!empty($arrayfields['t.duration_effective']['checked'])) print_liste_field_titre($arrayfields['t.duration_effective']['label'], $_SERVER["PHP_SELF"], "t.duration_effective", "", $param, '', $sortfield, $sortorder, 'center ');
617 if (!empty($arrayfields['t.progress_calculated']['checked'])) print_liste_field_titre($arrayfields['t.progress_calculated']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', '', '', 'center ');
618 if (!empty($arrayfields['t.progress']['checked'])) print_liste_field_titre($arrayfields['t.progress']['label'], $_SERVER["PHP_SELF"], "t.progress", "", $param, '', $sortfield, $sortorder, 'center ');
619 if (!empty($arrayfields['t.progress_summary']['checked'])) print_liste_field_titre($arrayfields['t.progress_summary']['label'], $_SERVER["PHP_SELF"], "t.progress", "", $param, '', $sortfield, $sortorder, 'center ');
620 if (!empty($arrayfields['t.tobill']['checked'])) print_liste_field_titre($arrayfields['t.tobill']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'center ');
621 if (!empty($arrayfields['t.billed']['checked'])) print_liste_field_titre($arrayfields['t.billed']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'center ');
622 // Extra fields
623 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
624 // Hook fields
625 $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder);
626 $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook
627 print $hookmanager->resPrint;
628 if (!empty($arrayfields['t.datec']['checked'])) print_liste_field_titre($arrayfields['t.datec']['label'], $_SERVER["PHP_SELF"], "t.datec", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
629 if (!empty($arrayfields['t.tms']['checked'])) print_liste_field_titre($arrayfields['t.tms']['label'], $_SERVER["PHP_SELF"], "t.tms", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
630 print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
631 print "</tr>\n";
632 
633 
634 $plannedworkloadoutputformat = 'allhourmin';
635 $timespentoutputformat = 'allhourmin';
636 if (!empty($conf->global->PROJECT_PLANNED_WORKLOAD_FORMAT)) $plannedworkloadoutputformat = $conf->global->PROJECT_PLANNED_WORKLOAD_FORMAT;
637 if (!empty($conf->global->PROJECT_TIMES_SPENT_FORMAT)) $timespentoutputformat = $conf->global->PROJECT_TIME_SPENT_FORMAT;
638 
639 $i = 0;
640 $totalarray = array();
641 while ($i < min($num, $limit))
642 {
643  $obj = $db->fetch_object($resql);
644 
645  $object->id = $obj->id;
646  $object->ref = $obj->ref;
647  $object->label = $obj->label;
648  $object->description = $obj->description;
649  $object->fk_statut = $obj->fk_statut;
650  $object->progress = $obj->progress;
651  $object->date_start = $db->jdate($obj->date_start);
652  $object->date_end = $db->jdate($obj->date_end);
653  $object->planned_workload = $obj->planned_workload;
654  $object->duration_effective = $obj->duration_effective;
655  $object->fk_task_parent = $obj->fk_task_parent;
656 
657 
658  $projectstatic->id = $obj->projectid;
659  $projectstatic->ref = $obj->projectref;
660  $projectstatic->title = $obj->projecttitle;
661  $projectstatic->public = $obj->public;
662  $projectstatic->statut = $obj->projectstatus;
663  $projectstatic->datee = $db->jdate($obj->projectdatee);
664 
665  $userAccess = $projectstatic->restrictedProjectArea($user); // why this ?
666  if ($userAccess >= 0)
667  {
668  print '<tr data-rowid="'.$object->id.'" class="oddeven">';
669 
670  // Ref Parent
671  if (!empty($arrayfields['t.fk_task_parent']['checked'])) {
672  print '<td class="nowraponall">';
673  if (!empty($object->fk_task_parent)) {
674  $object_parent = new Task($db);
675  $result = $object_parent->fetch($object->fk_task_parent);
676  if ($result < 0) {
677  setEventMessage($object_parent->error, 'errors');
678  } else {
679  print $object_parent->getNomUrl(1, 'withproject');
680  if ($object_parent->hasDelay())
681  print img_warning("Late");
682  }
683  }
684  print '</td>';
685  if (!$i) $totalarray['nbfield']++;
686  }
687  // Ref
688  if (!empty($arrayfields['t.ref']['checked']))
689  {
690  print '<td class="nowraponall">';
691  print $object->getNomUrl(1, 'withproject');
692  if ($object->hasDelay()) print img_warning("Late");
693  print '</td>';
694  if (!$i) $totalarray['nbfield']++;
695  }
696  // Label
697  if (!empty($arrayfields['t.label']['checked']))
698  {
699  print '<td>';
700  print $object->label;
701  print '</td>';
702  if (!$i) $totalarray['nbfield']++;
703  }
704  // Description
705  if (!empty($arrayfields['t.description']['checked']))
706  {
707  print '<td>';
708  print $object->description;
709  print '</td>';
710  if (!$i) $totalarray['nbfield']++;
711  }
712  // Date start
713  if (!empty($arrayfields['t.dateo']['checked']))
714  {
715  print '<td class="center">';
716  print dol_print_date($db->jdate($obj->date_start), 'day');
717  print '</td>';
718  if (!$i) $totalarray['nbfield']++;
719  }
720  // Date end
721  if (!empty($arrayfields['t.datee']['checked']))
722  {
723  print '<td class="center">';
724  print dol_print_date($db->jdate($obj->date_end), 'day');
725  print '</td>';
726  if (!$i) $totalarray['nbfield']++;
727  }
728  // Project ref
729  if (!empty($arrayfields['p.ref']['checked']))
730  {
731  print '<td class="nowraponall tdoverflowmax150">';
732  print $projectstatic->getNomUrl(1, 'task');
733  if ($projectstatic->hasDelay()) print img_warning("Late");
734  print '</td>';
735  if (!$i) $totalarray['nbfield']++;
736  }
737  // Project title
738  if (!empty($arrayfields['p.title']['checked']))
739  {
740  print '<td>';
741  print dol_trunc($obj->projecttitle, 80);
742  print '</td>';
743  if (!$i) $totalarray['nbfield']++;
744  }
745  // Third party
746  if (!empty($arrayfields['s.nom']['checked']))
747  {
748  print '<td>';
749  if ($obj->socid)
750  {
751  $socstatic->id = $obj->socid;
752  $socstatic->name = $obj->name;
753  print $socstatic->getNomUrl(1);
754  } else {
755  print '&nbsp;';
756  }
757  print '</td>';
758  if (!$i) $totalarray['nbfield']++;
759  }
760  // Project status
761  if (!empty($arrayfields['p.fk_statut']['checked']))
762  {
763  print '<td class="center">';
764  print $projectstatic->getLibStatut(1);
765  print '</td>';
766  if (!$i) $totalarray['nbfield']++;
767  }
768 
769  // Planned workload
770  if (!empty($arrayfields['t.planned_workload']['checked']))
771  {
772  print '<td class="center">';
773  $fullhour = convertSecondToTime($obj->planned_workload, $plannedworkloadoutputformat);
774  $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
775  if ($obj->planned_workload != '')
776  {
777  print $fullhour;
778  // TODO Add delay taking account of working hours per day and working day per week
779  //if ($workingdelay != $fullhour) print '<br>('.$workingdelay.')';
780  }
781  //else print '--:--';
782  print '</td>';
783  if (!$i) $totalarray['nbfield']++;
784  if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 't.planned_workload';
785  $totalarray['val']['t.planned_workload'] += $obj->planned_workload;
786  if (!$i) $totalarray['totalplannedworkloadfield'] = $totalarray['nbfield'];
787  $totalarray['totalplannedworkload'] += $obj->planned_workload;
788  }
789  // Time spent
790  if (!empty($arrayfields['t.duration_effective']['checked']))
791  {
792  $showlineingray = 0; $showproject = 1;
793  print '<td class="center">';
794  if ($showlineingray) print '<i>';
795  else print '<a href="'.DOL_URL_ROOT.'/projet/tasks/time.php?id='.$object->id.($showproject ? '' : '&withproject=1').'">';
796  if ($obj->duration_effective) print convertSecondToTime($obj->duration_effective, $timespentoutputformat);
797  else print '--:--';
798  if ($showlineingray) print '</i>';
799  else print '</a>';
800  print '</td>';
801  if (!$i) $totalarray['nbfield']++;
802  if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 't.duration_effective';
803  $totalarray['val']['t.duration_effective'] += $obj->duration_effective;
804  if (!$i) $totalarray['totaldurationeffectivefield'] = $totalarray['nbfield'];
805  $totalarray['totaldurationeffective'] += $obj->duration_effective;
806  }
807  // Calculated progress
808  if (!empty($arrayfields['t.progress_calculated']['checked']))
809  {
810  print '<td class="center">';
811  if ($obj->planned_workload || $obj->duration_effective)
812  {
813  if ($obj->planned_workload) print round(100 * $obj->duration_effective / $obj->planned_workload, 2).' %';
814  else print $form->textwithpicto('', $langs->trans('WorkloadNotDefined'), 1, 'help');
815  }
816  print '</td>';
817  if (!$i) $totalarray['nbfield']++;
818  if (!$i) $totalarray['totalprogress_calculatedfield'] = $totalarray['nbfield'];
819  }
820  // Declared progress
821  if (!empty($arrayfields['t.progress']['checked']))
822  {
823  print '<td class="center">';
824  if ($obj->progress != '')
825  {
826  print getTaskProgressBadge($object);
827  }
828  print '</td>';
829  if (!$i) $totalarray['nbfield']++;
830  if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 't.progress';
831  $totalarray['val']['t.progress'] += ($obj->planned_workload * $obj->progress / 100);
832  if (!$i) $totalarray['totalprogress_declaredfield'] = $totalarray['nbfield'];
833  $totalarray['totaldurationdeclared'] += $obj->planned_workload * $obj->progress / 100;
834  }
835  // Progress summary
836  if (!empty($arrayfields['t.progress_summary']['checked']))
837  {
838  print '<td class="center">';
839  if ($obj->progress != '' && $obj->duration_effective) {
840  print getTaskProgressView($object, false, false);
841  }
842  print '</td>';
843  if (!$i) $totalarray['nbfield']++;
844  if (!$i) $totalarray['totalprogress_summary'] = $totalarray['nbfield'];
845  }
846  // Time not billed
847  if (!empty($arrayfields['t.tobill']['checked']))
848  {
849  print '<td class="center">';
850  if ($obj->usage_bill_time)
851  {
852  print convertSecondToTime($obj->tobill, 'allhourmin');
853  $totalarray['val']['t.tobill'] += $obj->tobill;
854  $totalarray['totaltobill'] += $obj->tobill;
855  } else {
856  print '<span class="opacitymedium">'.$langs->trans("NA").'</span>';
857  }
858  print '</td>';
859  if (!$i) $totalarray['nbfield']++;
860  if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 't.tobill';
861  if (!$i) $totalarray['totaltobillfield'] = $totalarray['nbfield'];
862  }
863  // Time billed
864  if (!empty($arrayfields['t.billed']['checked']))
865  {
866  print '<td class="center">';
867  if ($obj->usage_bill_time)
868  {
869  print convertSecondToTime($obj->billed, 'allhourmin');
870  $totalarray['val']['t.billed'] += $obj->billed;
871  $totalarray['totalbilled'] += $obj->billed;
872  } else {
873  print '<span class="opacitymedium">'.$langs->trans("NA").'</span>';
874  }
875  print '</td>';
876  if (!$i) $totalarray['nbfield']++;
877  if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 't.billed';
878  if (!$i) $totalarray['totalbilledfield'] = $totalarray['nbfield'];
879  }
880  // Extra fields
881  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
882  // Fields from hook
883  $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray);
884  $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook
885  print $hookmanager->resPrint;
886  // Date creation
887  if (!empty($arrayfields['t.datec']['checked']))
888  {
889  print '<td class="center">';
890  print dol_print_date($db->jdate($obj->date_creation), 'dayhour', 'tzuser');
891  print '</td>';
892  if (!$i) $totalarray['nbfield']++;
893  }
894  // Date modification
895  if (!empty($arrayfields['t.tms']['checked']))
896  {
897  print '<td class="center">';
898  print dol_print_date($db->jdate($obj->date_update), 'dayhour', 'tzuser');
899  print '</td>';
900  if (!$i) $totalarray['nbfield']++;
901  }
902  // Status
903  /*if (! empty($arrayfields['p.fk_statut']['checked']))
904  {
905  $projectstatic->statut = $obj->fk_statut;
906  print '<td class="right">'.$projectstatic->getLibStatut(5).'</td>';
907  }*/
908  // Action column
909  print '<td class="nowrap center">';
910  if ($massactionbutton || $massaction) // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
911  {
912  $selected = 0;
913  if (in_array($obj->id, $arrayofselected)) $selected = 1;
914  print '<input id="cb'.$obj->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->id.'"'.($selected ? ' checked="checked"' : '').'>';
915  }
916  print '</td>';
917  if (!$i) $totalarray['nbfield']++;
918 
919  print "</tr>\n";
920  }
921 
922  $i++;
923 }
924 // Show total line
925 if (isset($totalarray['totaldurationeffectivefield']) || isset($totalarray['totalplannedworkloadfield']) || isset($totalarray['totalprogress_calculatedfield'])
926  || isset($totalarray['totaltobill']) || isset($totalarray['totalbilled']))
927 {
928  print '<tr class="liste_total">';
929  $i = 0;
930  while ($i < $totalarray['nbfield'])
931  {
932  $i++;
933  if ($i == 1)
934  {
935  if ($num < $limit && empty($offset)) print '<td class="left">'.$langs->trans("Total").'</td>';
936  else print '<td class="left">'.$langs->trans("Totalforthispage").'</td>';
937  } elseif ($totalarray['totalplannedworkloadfield'] == $i) print '<td class="center">'.convertSecondToTime($totalarray['totalplannedworkload'], $plannedworkloadoutputformat).'</td>';
938  elseif ($totalarray['totaldurationeffectivefield'] == $i) print '<td class="center">'.convertSecondToTime($totalarray['totaldurationeffective'], $timespentoutputformat).'</td>';
939  elseif ($totalarray['totalprogress_calculatedfield'] == $i) print '<td class="center">'.($totalarray['totalplannedworkload'] > 0 ? round(100 * $totalarray['totaldurationeffective'] / $totalarray['totalplannedworkload'], 2).' %' : '').'</td>';
940  elseif ($totalarray['totalprogress_declaredfield'] == $i) print '<td class="center">'.($totalarray['totalplannedworkload'] > 0 ? round(100 * $totalarray['totaldurationdeclared'] / $totalarray['totalplannedworkload'], 2).' %' : '').'</td>';
941  elseif ($totalarray['totaltobillfield'] == $i) print '<td class="center">'.convertSecondToTime($totalarray['totaltobill'], $plannedworkloadoutputformat).'</td>';
942  elseif ($totalarray['totalbilledfield'] == $i) print '<td class="center">'.convertSecondToTime($totalarray['totalbilled'], $plannedworkloadoutputformat).'</td>';
943  else print '<td></td>';
944  }
945  print '</tr>';
946 }
947 
948 $db->free($resql);
949 
950 $parameters = array('sql' => $sql);
951 $reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters); // Note that $action and $object may have been modified by hook
952 print $hookmanager->resPrint;
953 
954 print "</table>";
955 print '</div>';
956 
957 print '</form>';
958 
959 // End of page
960 llxFooter();
961 $db->close();
GETPOST($paramname, $check= 'alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dolGetButtonTitle($label, $helpText= '', $iconClass= 'fa fa-file', $url= '', $id= '', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
dol_now($mode= 'auto')
Return date for now.
Class to manage Dolibarr users.
Definition: user.class.php:44
setEventMessage($mesgs, $style= 'mesgs')
Set event message in dol_events session object.
img_warning($titlealt= 'default', $moreatt= '', $morecss= 'pictowarning')
Show warning logo.
llxHeader()
Empty header.
Definition: wrapper.php:45
Class to manage standard extra fields.
setEventMessages($mesg, $mesgs, $style= 'mesgs', $messagekey= '')
Set event messages 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.
Class to manage generation of HTML components Only common components must be here.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname.
Class to manage third parties objects (customers, suppliers, prospects...)
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
Class to manage projects.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename= '', $restricttologhandler= '', $logcontext=null)
Write log message into outputs.
Classe permettant la generation de composants html autre Only common components are here...
if(!GETPOST('transkey', 'alphanohtml')&&!GETPOST('transphrase', 'alphanohtml')) else
View.
Definition: notice.php:44
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 ...
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...
dolSqlDateFilter($datefield, $day_date, $month_date, $year_date, $excludefirstand=0)
Generate a SQL string to make a filter into a range (for second of date until last second of date) ...
Definition: date.lib.php:281
getTaskProgressView($task, $label=true, $progressNumber=true, $hideOnProgressNull=false, $spaced=false)
print $_SERVER["PHP_SELF"]
Edit parameters.
getTaskProgressBadge($task, $label= '', $tooltip= '')
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
Draft customers invoices.
Definition: index.php:89
Class to manage tasks.
Definition: task.class.php:35
dol_print_date($time, $format= '', $tzoutput= 'auto', $outputlangs= '', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) if(!empty($conf->don->enabled)&&$user->rights->don->lire) if(!empty($conf->tax->enabled)&&$user->rights->tax->charges->lire) if(!empty($conf->facture->enabled)&&!empty($conf->commande->enabled)&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1232
dol_print_error($db= '', $error= '', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_trunc($string, $size=40, $trunc= 'right', $stringencoding= 'UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding &#39;...&#39; if string larger than length.
llxFooter()
Empty footer.
Definition: wrapper.php:59
if(!defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN'
Draft customers invoices.
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:180