dolibarr  x.y.z
time.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2006-2021 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2010-2012 Regis Houssin <regis.houssin@inodbox.com>
5  * Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es>
6  * Copyright (C) 2018 Ferran Marcet <fmarcet@2byte.es>
7  * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
8  * Copyright (C) 2019-2021 Christophe Battarel <christophe@altairis.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <https://www.gnu.org/licenses/>.
22  */
23 
30 // Load Dolibarr environment
31 require '../../main.inc.php';
32 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
34 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
35 require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
36 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
37 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
38 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
39 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formintervention.class.php';
40 
41 // Load translation files required by the page
42 $langsLoad=array('projects', 'bills', 'orders', 'companies');
43 if (isModEnabled('eventorganization')) {
44  $langsLoad[]='eventorganization';
45 }
46 
47 $langs->loadLangs($langsLoad);
48 
49 $action = GETPOST('action', 'alpha');
50 $massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists)
51 $confirm = GETPOST('confirm', 'alpha');
52 $cancel = GETPOST('cancel', 'alpha');
53 $toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list
54 $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'timespentlist'; // To manage different context of search
55 $backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
56 $optioncss = GETPOST('optioncss', 'alpha');
57 $mode = GETPOST('mode', 'alpha');
58 
59 $id = GETPOST('id', 'int');
60 $projectid = GETPOST('projectid', 'int');
61 $ref = GETPOST('ref', 'alpha');
62 $withproject = GETPOST('withproject', 'int');
63 $project_ref = GETPOST('project_ref', 'alpha');
64 $tab = GETPOST('tab', 'aZ09');
65 
66 $search_day = GETPOST('search_day', 'int');
67 $search_month = GETPOST('search_month', 'int');
68 $search_year = GETPOST('search_year', 'int');
69 $search_datehour = '';
70 $search_datewithhour = '';
71 $search_date_startday = GETPOST('search_date_startday', 'int');
72 $search_date_startmonth = GETPOST('search_date_startmonth', 'int');
73 $search_date_startyear = GETPOST('search_date_startyear', 'int');
74 $search_date_endday = GETPOST('search_date_endday', 'int');
75 $search_date_endmonth = GETPOST('search_date_endmonth', 'int');
76 $search_date_endyear = GETPOST('search_date_endyear', 'int');
77 $search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear); // Use tzserver
78 $search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_endday, $search_date_endyear);
79 $search_note = GETPOST('search_note', 'alpha');
80 $search_duration = GETPOST('search_duration', 'int');
81 $search_value = GETPOST('search_value', 'int');
82 $search_task_ref = GETPOST('search_task_ref', 'alpha');
83 $search_task_label = GETPOST('search_task_label', 'alpha');
84 $search_user = GETPOST('search_user', 'int');
85 $search_valuebilled = GETPOST('search_valuebilled', 'int');
86 $search_product_ref = GETPOST('search_product_ref', 'alpha');
87 $search_company = GETPOST('$search_company', 'alpha');
88 $search_company_alias = GETPOST('$search_company_alias', 'alpha');
89 $search_project_ref = GETPOST('$search_project_ref', 'alpha');
90 $search_project_label = GETPOST('$search_project_label', 'alpha');
91 $search_timespent_starthour = GETPOSTINT("search_timespent_duration_starthour");
92 $search_timespent_startmin = GETPOSTINT("search_timespent_duration_startmin");
93 $search_timespent_endhour = GETPOSTINT("search_timespent_duration_endhour");
94 $search_timespent_endmin = GETPOSTINT("search_timespent_duration_endmin");
95 
96 $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
97 $sortfield = GETPOST('sortfield', 'aZ09comma');
98 $sortorder = GETPOST('sortorder', 'aZ09comma');
99 $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
100 if (empty($page) || $page == -1) {
101  $page = 0;
102 } // If $page is not defined, or '' or -1
103 $offset = $limit * $page;
104 $pageprev = $page - 1;
105 $pagenext = $page + 1;
106 if (!$sortfield) {
107  $sortfield = 't.task_date,t.task_datehour,t.rowid';
108 }
109 if (!$sortorder) {
110  $sortorder = 'DESC,DESC,DESC';
111 }
112 
113 $childids = $user->getAllChildIds(1);
114 
115 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
116 //$object = new TaskTime($db);
117 $hookmanager->initHooks(array('projecttasktime', 'globalcard'));
118 
119 $object = new Task($db);
120 $extrafields = new ExtraFields($db);
121 $projectstatic = new Project($db);
122 
123 // fetch optionals attributes and labels
124 $extrafields->fetch_name_optionals_label($projectstatic->table_element);
125 $extrafields->fetch_name_optionals_label($object->table_element);
126 
127 // Load task
128 if ($id > 0 || $ref) {
129  $object->fetch($id, $ref);
130 }
131 
132 
133 // Security check
134 $socid = 0;
135 //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.
136 if (!$user->rights->projet->lire) {
137  accessforbidden();
138 }
139 
140 if ($object->fk_project > 0) {
141  restrictedArea($user, 'projet', $object->fk_project, 'projet&project');
142 } else {
143  restrictedArea($user, 'projet', null, 'projet&project');
144  // We check user has permission to see all tasks of all users
145  if (empty($projectid) && !$user->hasRight('projet', 'all', 'lire')) {
146  $search_user = $user->id;
147  }
148 }
149 
150 
151 
152 /*
153  * Actions
154  */
155 
156 if (GETPOST('cancel', 'alpha')) {
157  $action = '';
158 }
159 if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend' && $massaction != 'confirm_generateinvoice' && $massaction != 'confirm_generateinter') {
160  $massaction = '';
161 }
162 
163 $parameters = array('socid'=>$socid, 'projectid'=>$projectid);
164 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
165 if ($reshook < 0) {
166  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
167 }
168 
169 include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
170 
171 // Purge search criteria
172 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
173  $search_day = '';
174  $search_month = '';
175  $search_year = '';
176  $search_date = '';
177  $search_datehour = '';
178  $search_datewithhour = '';
179  $search_note = '';
180  $search_duration = '';
181  $search_value = '';
182  $search_date_creation = '';
183  $search_date_update = '';
184  $search_date_startday = '';
185  $search_date_startmonth = '';
186  $search_date_startyear = '';
187  $search_date_endday = '';
188  $search_date_endmonth = '';
189  $search_date_endyear = '';
190  $search_date_start = '';
191  $search_date_end = '';
192  $search_task_ref = '';
193  $search_company = '';
194  $search_company_alias = '';
195  $search_project_ref = '';
196  $search_project_label = '';
197  $search_task_label = '';
198  $search_user = -1;
199  $search_valuebilled = '';
200  $search_product_ref = '';
201  $toselect = array();
202  $search_array_options = array();
203  $search_timespent_starthour = '';
204  $search_timespent_startmin = '';
205  $search_timespent_endhour = '';
206  $search_timespent_endmin = '';
207  $action = '';
208 }
209 
210 if ($action == 'addtimespent' && $user->rights->projet->time) {
211  $error = 0;
212 
213  $timespent_durationhour = GETPOST('timespent_durationhour', 'int');
214  $timespent_durationmin = GETPOST('timespent_durationmin', 'int');
215  if (empty($timespent_durationhour) && empty($timespent_durationmin)) {
216  setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Duration")), null, 'errors');
217  $error++;
218  }
219  if (!GETPOST("userid", 'int')) {
220  $langs->load("errors");
221  setEventMessages($langs->trans('ErrorUserNotAssignedToTask'), null, 'errors');
222  $error++;
223  }
224 
225  if (!$error) {
226  if ($id || $ref) {
227  $object->fetch($id, $ref);
228  } else {
229  if (!GETPOST('taskid', 'int') || GETPOST('taskid', 'int') < 0) {
230  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Task")), null, 'errors');
231  $action = 'createtime';
232  $error++;
233  } else {
234  $object->fetch(GETPOST('taskid', 'int'));
235  }
236  }
237 
238  if (!$error) {
239  $object->fetch_projet();
240 
241  if (empty($object->project->statut)) {
242  setEventMessages($langs->trans("ProjectMustBeValidatedFirst"), null, 'errors');
243  $action = 'createtime';
244  $error++;
245  } else {
246  $object->timespent_note = GETPOST("timespent_note", 'alpha');
247  if (GETPOST('progress', 'int') > 0) {
248  $object->progress = GETPOST('progress', 'int'); // If progress is -1 (not defined), we do not change value
249  }
250  $object->timespent_duration = GETPOSTINT("timespent_durationhour") * 60 * 60; // We store duration in seconds
251  $object->timespent_duration += (GETPOSTINT('timespent_durationmin') ? GETPOSTINT('timespent_durationmin') : 0) * 60; // We store duration in seconds
252  if (GETPOST("timehour") != '' && GETPOST("timehour") >= 0) { // If hour was entered
253  $object->timespent_date = dol_mktime(GETPOST("timehour", 'int'), GETPOST("timemin", 'int'), 0, GETPOST("timemonth", 'int'), GETPOST("timeday", 'int'), GETPOST("timeyear", 'int'));
254  $object->timespent_withhour = 1;
255  } else {
256  $object->timespent_date = dol_mktime(12, 0, 0, GETPOST("timemonth", 'int'), GETPOST("timeday", 'int'), GETPOST("timeyear", 'int'));
257  }
258  $object->timespent_fk_user = GETPOST("userid", 'int');
259  $object->timespent_fk_product = GETPOST("fk_product", 'int');
260  $result = $object->addTimeSpent($user);
261  if ($result >= 0) {
262  setEventMessages($langs->trans("RecordSaved"), null, 'mesgs');
263  } else {
264  setEventMessages($langs->trans($object->error), null, 'errors');
265  $error++;
266  }
267  }
268  }
269  } else {
270  if (empty($id)) {
271  $action = 'createtime';
272  } else {
273  $action = 'createtime';
274  }
275  }
276 }
277 
278 if (($action == 'updateline' || $action == 'updatesplitline') && !$cancel && $user->rights->projet->lire) {
279  $error = 0;
280 
281  if (!GETPOST("new_durationhour") && !GETPOST("new_durationmin")) {
282  setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Duration")), null, 'errors');
283  $error++;
284  }
285 
286  if (!$error) {
287  if (GETPOST('taskid', 'int') != $id) { // GETPOST('taskid') is id of new task
288  $id_temp = GETPOST('taskid', 'int'); // should not overwrite $id
289 
290 
291  $object->fetchTimeSpent(GETPOST('lineid', 'int'));
292 
293  $result = 0;
294  if (in_array($object->timespent_fk_user, $childids) || $user->rights->projet->all->creer) {
295  $result = $object->delTimeSpent($user);
296  }
297 
298  $object->fetch($id_temp, $ref);
299 
300  $object->timespent_note = GETPOST("timespent_note_line", "alphanohtml");
301  $object->timespent_old_duration = GETPOST("old_duration", "int");
302  $object->timespent_duration = GETPOSTINT("new_durationhour") * 60 * 60; // We store duration in seconds
303  $object->timespent_duration += (GETPOSTINT("new_durationmin") ? GETPOSTINT('new_durationmin') : 0) * 60; // We store duration in seconds
304  if (GETPOST("timelinehour") != '' && GETPOST("timelinehour") >= 0) { // If hour was entered
305  $object->timespent_date = dol_mktime(GETPOST("timelinehour"), GETPOST("timelinemin"), 0, GETPOST("timelinemonth"), GETPOST("timelineday"), GETPOST("timelineyear"));
306  $object->timespent_withhour = 1;
307  } else {
308  $object->timespent_date = dol_mktime(12, 0, 0, GETPOST("timelinemonth"), GETPOST("timelineday"), GETPOST("timelineyear"));
309  }
310  $object->timespent_fk_user = GETPOST("userid_line", 'int');
311  $object->timespent_fk_product = GETPOST("fk_product", 'int');
312 
313  $result = 0;
314  if (in_array($object->timespent_fk_user, $childids) || $user->rights->projet->all->creer) {
315  $result = $object->addTimeSpent($user);
316  if ($result >= 0) {
317  setEventMessages($langs->trans("RecordSaved"), null, 'mesgs');
318  } else {
319  setEventMessages($langs->trans($object->error), null, 'errors');
320  $error++;
321  }
322  }
323  } else {
324  $object->fetch($id, $ref);
325 
326  $object->timespent_id = GETPOST("lineid", 'int');
327  $object->timespent_note = GETPOST("timespent_note_line", "alphanohtml");
328  $object->timespent_old_duration = GETPOST("old_duration", "int");
329  $object->timespent_duration = GETPOSTINT("new_durationhour") * 60 * 60; // We store duration in seconds
330  $object->timespent_duration += (GETPOSTINT("new_durationmin") ? GETPOSTINT('new_durationmin') : 0) * 60; // We store duration in seconds
331  if (GETPOST("timelinehour") != '' && GETPOST("timelinehour") >= 0) { // If hour was entered
332  $object->timespent_date = dol_mktime(GETPOST("timelinehour", 'int'), GETPOST("timelinemin", 'int'), 0, GETPOST("timelinemonth", 'int'), GETPOST("timelineday", 'int'), GETPOST("timelineyear", 'int'));
333  $object->timespent_withhour = 1;
334  } else {
335  $object->timespent_date = dol_mktime(12, 0, 0, GETPOST("timelinemonth", 'int'), GETPOST("timelineday", 'int'), GETPOST("timelineyear", 'int'));
336  }
337  $object->timespent_fk_user = GETPOST("userid_line", 'int');
338  $object->timespent_fk_product = GETPOST("fk_product", 'int');
339 
340  $result = 0;
341  if (in_array($object->timespent_fk_user, $childids) || $user->rights->projet->all->creer) {
342  $result = $object->updateTimeSpent($user);
343 
344  if ($result >= 0) {
345  setEventMessages($langs->trans("RecordSaved"), null, 'mesgs');
346  } else {
347  setEventMessages($langs->trans($object->error), null, 'errors');
348  $error++;
349  }
350  }
351  }
352  } else {
353  $action = '';
354  }
355 }
356 
357 if ($action == 'confirm_deleteline' && $confirm == "yes" && ($user->hasRight('projet', 'time') || $user->hasRight('projet', 'all', 'creer'))) {
358  $object->fetchTimeSpent(GETPOST('lineid', 'int')); // load properties like $object->timespent_xxx
359 
360  if (in_array($object->timespent_fk_user, $childids) || $user->hasRight('projet', 'all', 'creer')) {
361  $result = $object->delTimeSpent($user); // delete line with $object->timespent_id
362 
363  if ($result < 0) {
364  $langs->load("errors");
365  setEventMessages($langs->trans($object->error), null, 'errors');
366  $error++;
367  $action = '';
368  } else {
369  setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs');
370  }
371  }
372 }
373 
374 // Retrieve First Task ID of Project if withprojet is on to allow project prev next to work
375 if (!empty($project_ref) && !empty($withproject)) {
376  if ($projectstatic->fetch(0, $project_ref) > 0) {
377  $tasksarray = $object->getTasksArray(0, 0, $projectstatic->id, $socid, 0);
378  if (count($tasksarray) > 0) {
379  $id = $tasksarray[0]->id;
380  } else {
381  header("Location: ".DOL_URL_ROOT.'/projet/tasks.php?id='.$projectstatic->id.($withproject ? '&withproject=1' : '').(empty($mode) ? '' : '&mode='.$mode));
382  exit;
383  }
384  }
385 }
386 
387 // To show all time lines for project
388 $projectidforalltimes = 0;
389 if (GETPOST('projectid', 'int') > 0) {
390  $projectidforalltimes = GETPOST('projectid', 'int');
391 
392  $result = $projectstatic->fetch($projectidforalltimes);
393  if (!empty($projectstatic->socid)) {
394  $projectstatic->fetch_thirdparty();
395  }
396  $res = $projectstatic->fetch_optionals();
397 } elseif (GETPOST('project_ref', 'alpha')) {
398  $projectstatic->fetch(0, GETPOST('project_ref', 'alpha'));
399  $projectidforalltimes = $projectstatic->id;
400  $withproject = 1;
401 } elseif ($id > 0) {
402  $object->fetch($id);
403  $result = $projectstatic->fetch($object->fk_project);
404 }
405 // If not task selected and no project selected
406 if ($id <= 0 && $projectidforalltimes == 0) {
407  $allprojectforuser = $user->id;
408 }
409 
410 if ($action == 'confirm_generateinvoice') {
411  if (!empty($projectstatic->socid)) {
412  $projectstatic->fetch_thirdparty();
413  }
414 
415  if (!($projectstatic->thirdparty->id > 0)) {
416  setEventMessages($langs->trans("ThirdPartyRequiredToGenerateInvoice"), null, 'errors');
417  } else {
418  include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
419  include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
420  include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
421 
422  $tmpinvoice = new Facture($db);
423  $tmptimespent = new Task($db);
424  $tmpproduct = new Product($db);
425  $fuser = new User($db);
426 
427  $db->begin();
428  $idprod = GETPOST('productid', 'int');
429  $generateinvoicemode = GETPOST('generateinvoicemode', 'string');
430  $invoiceToUse = GETPOST('invoiceid', 'int');
431 
432  $prodDurationHoursBase = 1.0;
433  $product_data_cache = array();
434  if ($idprod > 0) {
435  $tmpproduct->fetch($idprod);
436  if ($result<0) {
437  $error++;
438  setEventMessages($tmpproduct->error, $tmpproduct->errors, 'errors');
439  }
440 
441  $prodDurationHoursBase=$tmpproduct->getProductDurationHours();
442  if ($prodDurationHoursBase<0) {
443  $error++;
444  $langs->load("errors");
445  setEventMessages(null, $tmpproduct->errors, 'errors');
446  }
447 
448  $dataforprice = $tmpproduct->getSellPrice($mysoc, $projectstatic->thirdparty, 0);
449 
450  $pu_ht = empty($dataforprice['pu_ht']) ? 0 : $dataforprice['pu_ht'];
451  $txtva = $dataforprice['tva_tx'];
452  $localtax1 = $dataforprice['localtax1'];
453  $localtax2 = $dataforprice['localtax2'];
454  } else {
455  $prodDurationHoursBase = 1;
456 
457  $pu_ht = 0;
458  $txtva = get_default_tva($mysoc, $projectstatic->thirdparty);
459  $localtax1 = get_default_localtax($mysoc, $projectstatic->thirdparty, 1);
460  $localtax2 = get_default_localtax($mysoc, $projectstatic->thirdparty, 2);
461  }
462 
463  $tmpinvoice->socid = $projectstatic->thirdparty->id;
464  $tmpinvoice->date = dol_mktime(GETPOST('rehour', 'int'), GETPOST('remin', 'int'), GETPOST('resec', 'int'), GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
465  $tmpinvoice->fk_project = $projectstatic->id;
466  $tmpinvoice->cond_reglement_id = $projectstatic->thirdparty->cond_reglement_id;
467  $tmpinvoice->mode_reglement_id = $projectstatic->thirdparty->mode_reglement_id;
468  $tmpinvoice->fk_account = $projectstatic->thirdparty->fk_account;
469 
470  if ($invoiceToUse) {
471  $tmpinvoice->fetch($invoiceToUse);
472  } else {
473  $result = $tmpinvoice->create($user);
474  if ($result <= 0) {
475  $error++;
476  setEventMessages($tmpinvoice->error, $tmpinvoice->errors, 'errors');
477  }
478  }
479 
480  if (!$error) {
481  if ($generateinvoicemode == 'onelineperuser') { // 1 line per user (and per product)
482  $arrayoftasks = array();
483  foreach ($toselect as $key => $value) {
484  // Get userid, timepent
485  $object->fetchTimeSpent($value); // $value is ID of 1 line in timespent table
486  $arrayoftasks[$object->timespent_fk_user][(int) $object->timespent_fk_product]['timespent'] += $object->timespent_duration;
487  $arrayoftasks[$object->timespent_fk_user][(int) $object->timespent_fk_product]['totalvaluetodivideby3600'] += ($object->timespent_duration * $object->timespent_thm);
488  }
489 
490  foreach ($arrayoftasks as $userid => $data) {
491  $fuser->fetch($userid);
492  $username = $fuser->getFullName($langs);
493 
494  foreach ($data as $fk_product => $timespent_data) {
495  // Define qty per hour
496  $qtyhour = $timespent_data['timespent'] / 3600;
497  $qtyhourtext = convertSecondToTime($timespent_data['timespent'], 'all', $conf->global->MAIN_DURATION_OF_WORKDAY);
498 
499  // Set the unit price we want to sell the time, for this user
500  if (getDolGlobalInt('PROJECT_USE_REAL_COST_FOR_TIME_INVOICING')) {
501  // We set unit price to 0 to force the use of the rate saved during recording
502  $pu_ht = 0;
503  } else {
504  // We want to sell all the time spent with the last hourly rate of user
505  $pu_ht = $fuser->thm;
506  }
507 
508  // If no unit price known for user, we use the price recorded when recording timespent.
509  if (empty($pu_ht)) {
510  if ($timespent_data['timespent']) {
511  $pu_ht = price2num(($timespent_data['totalvaluetodivideby3600'] / $timespent_data['timespent']), 'MU');
512  }
513  }
514 
515  // Add lines
516  $prodDurationHours = $prodDurationHoursBase;
517  $idprodline=$idprod;
518  $pu_htline = $pu_ht;
519  $txtvaline = $txtva;
520  $localtax1line = $localtax1;
521  $localtax2line = $localtax2;
522 
523  // If a particular product/service was defined for the task
524  if (!empty($fk_product) && $fk_product !== $idprod) {
525  if (!array_key_exists($fk_product, $product_data_cache)) {
526  $result = $tmpproduct->fetch($fk_product);
527  if ($result < 0) {
528  $error++;
529  setEventMessages($tmpproduct->error, $tmpproduct->errors, 'errors');
530  }
531  $prodDurationHours = $tmpproduct->getProductDurationHours();
532  if ($prodDurationHours < 0) {
533  $error++;
534  $langs->load("errors");
535  setEventMessages(null, $tmpproduct->errors, 'errors');
536  }
537 
538  $dataforprice = $tmpproduct->getSellPrice($mysoc, $projectstatic->thirdparty, 0);
539 
540  $pu_htline = empty($dataforprice['pu_ht']) ? 0 : $dataforprice['pu_ht'];
541  $txtvaline = $dataforprice['tva_tx'];
542  $localtax1line = $dataforprice['localtax1'];
543  $localtax2line = $dataforprice['localtax2'];
544 
545  $product_data_cache[$fk_product] = array('duration'=>$prodDurationHours,'dataforprice'=>$dataforprice);
546  } else {
547  $prodDurationHours = $product_data_cache[$fk_product]['duration'];
548  $pu_htline = empty($product_data_cache[$fk_product]['dataforprice']['pu_ht']) ? 0 : $product_data_cache[$fk_product]['dataforprice']['pu_ht'];
549  $txtvaline = $product_data_cache[$fk_product]['dataforprice']['tva_tx'];
550  $localtax1line = $product_data_cache[$fk_product]['dataforprice']['localtax1'];
551  $localtax2line = $product_data_cache[$fk_product]['dataforprice']['localtax2'];
552  }
553  $idprodline=$fk_product;
554  }
555 
556  // Add lines
557  $lineid = $tmpinvoice->addline($langs->trans("TimeSpentForInvoice", $username).' : '.$qtyhourtext, $pu_htline, round($qtyhour / $prodDurationHours, 2), $txtvaline, $localtax1line, $localtax2line, ($idprodline > 0 ? $idprodline : 0));
558  if ($lineid<0) {
559  $error++;
560  setEventMessages(null, $tmpinvoice->errors, 'errors');
561  }
562 
563  // Update lineid into line of timespent
564  $sql = 'UPDATE '.MAIN_DB_PREFIX.'projet_task_time SET invoice_line_id = '.((int) $lineid).', invoice_id = '.((int) $tmpinvoice->id);
565  $sql .= ' WHERE rowid IN ('.$db->sanitize(join(',', $toselect)).') AND fk_user = '.((int) $userid);
566  $result = $db->query($sql);
567  if (!$result) {
568  $error++;
569  setEventMessages($db->lasterror(), null, 'errors');
570  break;
571  }
572  }
573  }
574  } elseif ($generateinvoicemode == 'onelineperperiod') { // One line for each time spent line
575  $arrayoftasks = array();
576 
577  $withdetail=GETPOST('detail_time_duration', 'alpha');
578  foreach ($toselect as $key => $value) {
579  // Get userid, timepent
580  $object->fetchTimeSpent($value);
581  // $object->id is the task id
582  $ftask = new Task($db);
583  $ftask->fetch($object->id);
584 
585  $fuser->fetch($object->timespent_fk_user);
586  $username = $fuser->getFullName($langs);
587 
588  $arrayoftasks[$object->timespent_id]['timespent'] = $object->timespent_duration;
589  $arrayoftasks[$object->timespent_id]['totalvaluetodivideby3600'] = $object->timespent_duration * $object->timespent_thm;
590  $arrayoftasks[$object->timespent_id]['note'] = $ftask->ref.' - '.$ftask->label.' - '.$username.($object->timespent_note ? ' - '.$object->timespent_note : ''); // TODO Add user name in note
591  if (!empty($withdetail)) {
592  if (isModEnabled('fckeditor') && !empty($conf->global->FCKEDITOR_ENABLE_DETAILS)) {
593  $arrayoftasks[$object->timespent_id]['note'] .= "<br/>";
594  } else {
595  $arrayoftasks[$object->timespent_id]['note'] .= "\n";
596  }
597 
598  if (!empty($object->timespent_withhour)) {
599  $arrayoftasks[$object->timespent_id]['note'] .= $langs->trans("Date") . ': ' . dol_print_date($object->timespent_datehour);
600  } else {
601  $arrayoftasks[$object->timespent_id]['note'] .= $langs->trans("Date") . ': ' . dol_print_date($object->timespent_date);
602  }
603  $arrayoftasks[$object->timespent_id]['note'] .= ' - '.$langs->trans("Duration").': '.convertSecondToTime($object->timespent_duration, 'all', $conf->global->MAIN_DURATION_OF_WORKDAY);
604  }
605  $arrayoftasks[$object->timespent_id]['user'] = $object->timespent_fk_user;
606  $arrayoftasks[$object->timespent_id]['fk_product'] = $object->timespent_fk_product;
607  }
608 
609  foreach ($arrayoftasks as $timespent_id => $value) {
610  $userid = $value['user'];
611  //$pu_ht = $value['timespent'] * $fuser->thm;
612 
613  // Define qty per hour
614  $qtyhour = $value['timespent'] / 3600;
615 
616  // If no unit price known
617  if (empty($pu_ht)) {
618  $pu_ht = price2num($value['totalvaluetodivideby3600'] / 3600, 'MU');
619  }
620 
621  // Add lines
622  $prodDurationHours = $prodDurationHoursBase;
623  $idprodline=$idprod;
624  $pu_htline = $pu_ht;
625  $txtvaline = $txtva;
626  $localtax1line = $localtax1;
627  $localtax2line = $localtax2;
628 
629  if (!empty($value['fk_product']) && $value['fk_product']!==$idprod) {
630  if (!array_key_exists($value['fk_product'], $product_data_cache)) {
631  $result = $tmpproduct->fetch($value['fk_product']);
632  if ($result < 0) {
633  $error++;
634  setEventMessages($tmpproduct->error, $tmpproduct->errors, 'errors');
635  }
636  $prodDurationHours = $tmpproduct->getProductDurationHours();
637  if ($prodDurationHours < 0) {
638  $error++;
639  $langs->load("errors");
640  setEventMessages(null, $tmpproduct->errors, 'errors');
641  }
642 
643  $dataforprice = $tmpproduct->getSellPrice($mysoc, $projectstatic->thirdparty, 0);
644 
645  $pu_htline = empty($dataforprice['pu_ht']) ? 0 : $dataforprice['pu_ht'];
646  $txtvaline = $dataforprice['tva_tx'];
647  $localtax1line = $dataforprice['localtax1'];
648  $localtax2line = $dataforprice['localtax2'];
649 
650  $product_data_cache[$value['fk_product']] = array('duration'=>$prodDurationHours,'dataforprice'=>$dataforprice);
651  } else {
652  $prodDurationHours = $product_data_cache[$value['fk_product']]['duration'];
653  $pu_htline = empty($product_data_cache[$value['fk_product']]['dataforprice']['pu_ht']) ? 0 : $product_data_cache[$value['fk_product']]['dataforprice']['pu_ht'];
654  $txtvaline = $product_data_cache[$value['fk_product']]['dataforprice']['tva_tx'];
655  $localtax1line = $product_data_cache[$value['fk_product']]['dataforprice']['localtax1'];
656  $localtax2line = $product_data_cache[$value['fk_product']]['dataforprice']['localtax2'];
657  }
658  $idprodline=$value['fk_product'];
659  }
660  $lineid = $tmpinvoice->addline($value['note'], $pu_htline, round($qtyhour / $prodDurationHours, 2), $txtvaline, $localtax1line, $localtax2line, ($idprodline > 0 ? $idprodline : 0));
661  if ($lineid<0) {
662  $error++;
663  setEventMessages(null, $tmpinvoice->errors, 'errors');
664  }
665  //var_dump($lineid);exit;
666 
667  // Update lineid into line of timespent
668  $sql = 'UPDATE '.MAIN_DB_PREFIX.'projet_task_time SET invoice_line_id = '.((int) $lineid).', invoice_id = '.((int) $tmpinvoice->id);
669  $sql .= ' WHERE rowid IN ('.$db->sanitize(join(',', $toselect)).') AND fk_user = '.((int) $userid);
670  $result = $db->query($sql);
671  if (!$result) {
672  $error++;
673  setEventMessages($db->lasterror(), null, 'errors');
674  break;
675  }
676  }
677  } elseif ($generateinvoicemode == 'onelinepertask') { // One line for each different task
678  $arrayoftasks = array();
679  foreach ($toselect as $key => $value) {
680  // Get userid, timepent
681  $object->fetchTimeSpent($value); // Call method to get list of timespent for a timespent line id (We use the utiliy method found into Task object)
682  // $object->id is now the task id
683  $arrayoftasks[$object->id][(int) $object->timespent_fk_product]['timespent'] += $object->timespent_duration;
684  $arrayoftasks[$object->id][(int) $object->timespent_fk_product]['totalvaluetodivideby3600'] += ($object->timespent_duration * $object->timespent_thm);
685  }
686 
687  foreach ($arrayoftasks as $task_id => $data) {
688  $ftask = new Task($db);
689  $ftask->fetch($task_id);
690 
691  foreach ($data as $fk_product=>$timespent_data) {
692  $qtyhour = $timespent_data['timespent'] / 3600;
693  $qtyhourtext = convertSecondToTime($timespent_data['timespent'], 'all', $conf->global->MAIN_DURATION_OF_WORKDAY);
694 
695  // Add lines
696  $prodDurationHours = $prodDurationHoursBase;
697  $idprodline=$idprod;
698  $pu_htline = $pu_ht;
699  $txtvaline = $txtva;
700  $localtax1line = $localtax1;
701  $localtax2line = $localtax2;
702 
703  if (!empty($fk_product) && $fk_product!==$idprod) {
704  if (!array_key_exists($fk_product, $product_data_cache)) {
705  $result = $tmpproduct->fetch($fk_product);
706  if ($result < 0) {
707  $error++;
708  setEventMessages($tmpproduct->error, $tmpproduct->errors, 'errors');
709  }
710  $prodDurationHours = $tmpproduct->getProductDurationHours();
711  if ($prodDurationHours < 0) {
712  $error++;
713  $langs->load("errors");
714  setEventMessages(null, $tmpproduct->errors, 'errors');
715  }
716 
717  $dataforprice = $tmpproduct->getSellPrice($mysoc, $projectstatic->thirdparty, 0);
718 
719  $pu_htline = empty($dataforprice['pu_ht']) ? 0 : $dataforprice['pu_ht'];
720  $txtvaline = $dataforprice['tva_tx'];
721  $localtax1line = $dataforprice['localtax1'];
722  $localtax2line = $dataforprice['localtax2'];
723 
724  $product_data_cache[$fk_product] = array('duration'=>$prodDurationHours,'dataforprice'=>$dataforprice);
725  } else {
726  $prodDurationHours = $product_data_cache[$fk_product]['duration'];
727  $pu_htline = empty($product_data_cache[$fk_product]['dataforprice']['pu_ht']) ? 0 : $product_data_cache[$fk_product]['dataforprice']['pu_ht'];
728  $txtvaline = $product_data_cache[$fk_product]['dataforprice']['tva_tx'];
729  $localtax1line = $product_data_cache[$fk_product]['dataforprice']['localtax1'];
730  $localtax2line = $product_data_cache[$fk_product]['dataforprice']['localtax2'];
731  }
732  $idprodline=$fk_product;
733  }
734 
735 
736  if ($idprodline > 0) {
737  // If a product is defined, we msut use the $prodDurationHours and $pu_ht of product (already set previously).
738  $pu_ht_for_task = $pu_htline;
739  // If we want to reuse the value of timespent (so use same price than cost price)
740  if (!empty($conf->global->PROJECT_TIME_SPENT_INTO_INVOICE_USE_VALUE)) {
741  $pu_ht_for_task = price2num($timespent_data['totalvaluetodivideby3600'] / $timespent_data['timespent'], 'MU') * $prodDurationHours;
742  }
743  $pa_ht = price2num($timespent_data['totalvaluetodivideby3600'] / $timespent_data['timespent'], 'MU') * $prodDurationHours;
744  } else {
745  // If not product used, we use the hour unit for duration and unit price.
746  $pu_ht_for_task = 0;
747  // If we want to reuse the value of timespent (so use same price than cost price)
748  if (!empty($conf->global->PROJECT_TIME_SPENT_INTO_INVOICE_USE_VALUE)) {
749  $pu_ht_for_task = price2num($timespent_data['totalvaluetodivideby3600'] / $timespent_data['timespent'], 'MU');
750  }
751  $pa_ht = price2num($timespent_data['totalvaluetodivideby3600'] / $timespent_data['timespent'], 'MU');
752  }
753 
754  // Add lines
755  $date_start = '';
756  $date_end = '';
757  $lineName = $ftask->ref . ' - ' . $ftask->label;
758  $lineid = $tmpinvoice->addline($lineName, $pu_ht_for_task, price2num($qtyhour / $prodDurationHours, 'MS'), $txtvaline, $localtax1line, $localtax2line, ($idprodline > 0 ? $idprodline : 0), 0, $date_start, $date_end, 0, 0, '', 'HT', 0, 1, -1, 0, '', 0, 0, null, $pa_ht);
759  if ($lineid < 0) {
760  $error++;
761  setEventMessages($tmpinvoice->error, $tmpinvoice->errors, 'errors');
762  break;
763  }
764 
765  if (!$error) {
766  // Update lineid into line of timespent
767  $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'projet_task_time SET invoice_line_id = ' . ((int) $lineid) . ', invoice_id = ' . ((int) $tmpinvoice->id);
768  $sql .= ' WHERE rowid IN (' . $db->sanitize(join(',', $toselect)) . ')';
769  $result = $db->query($sql);
770  if (!$result) {
771  $error++;
772  setEventMessages($db->lasterror(), null, 'errors');
773  break;
774  }
775  }
776  }
777  }
778  }
779  }
780 
781  if (!$error) {
782  $urltoinvoice = $tmpinvoice->getNomUrl(0);
783  $mesg = $langs->trans("InvoiceGeneratedFromTimeSpent", '{s1}');
784  $mesg = str_replace('{s1}', $urltoinvoice, $mesg);
785  setEventMessages($mesg, null, 'mesgs');
786 
787  //var_dump($tmpinvoice);
788 
789  $db->commit();
790  } else {
791  $db->rollback();
792  }
793  }
794 }
795 
796 if ($action == 'confirm_generateinter') {
797  $langs->load('interventions');
798 
799  if (!empty($projectstatic->socid)) $projectstatic->fetch_thirdparty();
800 
801  if (!($projectstatic->thirdparty->id > 0)) {
802  setEventMessages($langs->trans("ThirdPartyRequiredToGenerateIntervention"), null, 'errors');
803  } else {
804  include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
805  include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
806  include_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
807 
808 
809  require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
810  $tmpinter = new Fichinter($db);
811  $tmptimespent = new Task($db);
812  $fuser = new User($db);
813 
814  $db->begin();
815  $interToUse = GETPOST('interid', 'int');
816 
817 
818  $tmpinter->socid = $projectstatic->thirdparty->id;
819  $tmpinter->date = dol_mktime(GETPOST('rehour', 'int'), GETPOST('remin', 'int'), GETPOST('resec', 'int'), GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
820  $tmpinter->fk_project = $projectstatic->id;
821  $tmpinter->description = $projectstatic->title . ( !empty($projectstatic->description) ? '-' . $projectstatic->label : '' );
822 
823  if ($interToUse) {
824  $tmpinter->fetch($interToUse);
825  } else {
826  $result = $tmpinter->create($user);
827  if ($result <= 0) {
828  $error++;
829  setEventMessages($tmpinter->error, $tmpinter->errors, 'errors');
830  }
831  }
832 
833  if (!$error) {
834  $arrayoftasks = array();
835  foreach ($toselect as $key => $value) {
836  // Get userid, timespent
837  $object->fetchTimeSpent($value);
838  // $object->id is the task id
839  $arrayoftasks[$object->timespent_id]['id'] = $object->id;
840  $arrayoftasks[$object->timespent_id]['timespent'] = $object->timespent_duration;
841  $arrayoftasks[$object->timespent_id]['totalvaluetodivideby3600'] = $object->timespent_duration * $object->timespent_thm;
842  $arrayoftasks[$object->timespent_id]['note'] = $object->timespent_note;
843  $arrayoftasks[$object->timespent_id]['date'] = date('Y-m-d H:i:s', $object->timespent_datehour);
844  }
845 
846  foreach ($arrayoftasks as $timespent_id => $value) {
847  $ftask = new Task($db);
848  $ftask->fetch($value['id']);
849  // Define qty per hour
850  $qtyhour = $value['timespent'] / 3600;
851  $qtyhourtext = convertSecondToTime($value['timespent'], 'all', $conf->global->MAIN_DURATION_OF_WORKDAY);
852 
853  // Add lines
854  $lineid = $tmpinter->addline($user, $tmpinter->id, $ftask->label . ( !empty($value['note']) ? ' - ' . $value['note'] : '' ), $value['date'], $value['timespent']);
855  }
856  }
857 
858  if (!$error) {
859  $urltointer = $tmpinter->getNomUrl(0);
860  $mesg = $langs->trans("InterventionGeneratedFromTimeSpent", '{s1}');
861  $mesg = str_replace('{s1}', $urltointer, $mesg);
862  setEventMessages($mesg, null, 'mesgs');
863 
864  //var_dump($tmpinvoice);
865 
866  $db->commit();
867  } else {
868  $db->rollback();
869  }
870  }
871 }
872 
873 /*
874  * View
875  */
876 $form = new Form($db);
877 $formother = new FormOther($db);
878 $formproject = new FormProjets($db);
879 $userstatic = new User($db);
880 //$result = $projectstatic->fetch($object->fk_project);
881 $arrayofselected = is_array($toselect) ? $toselect : array();
882 
883 $title = $object->ref . ' - ' . $langs->trans("TimeSpent");
884 if (!empty($withproject)) {
885  $title .= ' | ' . $langs->trans("Project") . (!empty($projectstatic->ref) ? ': '.$projectstatic->ref : '') ;
886 }
887 $help_url = '';
888 
889 llxHeader('', $title, $help_url);
890 
891 if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser > 0) {
892  /*
893  * Fiche projet en mode visu
894  */
895  if ($projectidforalltimes > 0) {
896  $result = $projectstatic->fetch($projectidforalltimes);
897  if (!empty($projectstatic->socid)) {
898  $projectstatic->fetch_thirdparty();
899  }
900  $res = $projectstatic->fetch_optionals();
901  } elseif ($object->fetch($id, $ref) >= 0) {
902  if (!empty($conf->global->PROJECT_ALLOW_COMMENT_ON_TASK) && method_exists($object, 'fetchComments') && empty($object->comments)) {
903  $object->fetchComments();
904  }
905  $result = $projectstatic->fetch($object->fk_project);
906  if (!empty($conf->global->PROJECT_ALLOW_COMMENT_ON_PROJECT) && method_exists($projectstatic, 'fetchComments') && empty($projectstatic->comments)) {
907  $projectstatic->fetchComments();
908  }
909  if (!empty($projectstatic->socid)) {
910  $projectstatic->fetch_thirdparty();
911  }
912  $res = $projectstatic->fetch_optionals();
913 
914  $object->project = clone $projectstatic;
915  }
916 
917  $userRead = $projectstatic->restrictedProjectArea($user, 'read');
918  $linktocreatetime = '';
919 
920  if ($projectstatic->id > 0) {
921  if ($withproject) {
922  // Tabs for project
923  if (empty($id) || $tab == 'timespent') {
924  $tab = 'timespent';
925  } else {
926  $tab = 'tasks';
927  }
928 
929  $head = project_prepare_head($projectstatic);
930  print dol_get_fiche_head($head, $tab, $langs->trans("Project"), -1, ($projectstatic->public ? 'projectpub' : 'project'));
931 
932  $param = ((!empty($mode) && $mode == 'mine') ? '&mode=mine' : '');
933  if ($search_user) {
934  $param .= '&search_user='.((int) $search_user);
935  }
936  if ($search_month) {
937  $param .= '&search_month='.((int) $search_month);
938  }
939  if ($search_year) {
940  $param .= '&search_year='.((int) $search_year);
941  }
942 
943  // Project card
944 
945  $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
946 
947  $morehtmlref = '<div class="refidno">';
948  // Title
949  $morehtmlref .= $projectstatic->title;
950  // Thirdparty
951  if (!empty($projectstatic->thirdparty->id) && $projectstatic->thirdparty->id > 0) {
952  $morehtmlref .= '<br>'.$projectstatic->thirdparty->getNomUrl(1, 'project');
953  }
954  $morehtmlref .= '</div>';
955 
956  // Define a complementary filter for search of next/prev ref.
957  if (empty($user->rights->projet->all->lire)) {
958  $objectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 0);
959  $projectstatic->next_prev_filter = " rowid IN (".$db->sanitize(count($objectsListId) ?join(',', array_keys($objectsListId)) : '0').")";
960  }
961 
962  dol_banner_tab($projectstatic, 'project_ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $param);
963 
964  print '<div class="fichecenter">';
965  print '<div class="fichehalfleft">';
966  print '<div class="underbanner clearboth"></div>';
967 
968  print '<table class="border tableforfield centpercent">';
969 
970  // Usage
971  if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES) || empty($conf->global->PROJECT_HIDE_TASKS) || isModEnabled('eventorganization')) {
972  print '<tr><td class="tdtop">';
973  print $langs->trans("Usage");
974  print '</td>';
975  print '<td>';
976  if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) {
977  print '<input type="checkbox" disabled name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') != '' ? ' checked="checked"' : '') : ($projectstatic->usage_opportunity ? ' checked="checked"' : '')).'"> ';
978  $htmltext = $langs->trans("ProjectFollowOpportunity");
979  print $form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext);
980  print '<br>';
981  }
982  if (empty($conf->global->PROJECT_HIDE_TASKS)) {
983  print '<input type="checkbox" disabled name="usage_task"'.(GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') != '' ? ' checked="checked"' : '') : ($projectstatic->usage_task ? ' checked="checked"' : '')).'"> ';
984  $htmltext = $langs->trans("ProjectFollowTasks");
985  print $form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext);
986  print '<br>';
987  }
988  if (empty($conf->global->PROJECT_HIDE_TASKS) && !empty($conf->global->PROJECT_BILL_TIME_SPENT)) {
989  print '<input type="checkbox" disabled name="usage_bill_time"'.(GETPOSTISSET('usage_bill_time') ? (GETPOST('usage_bill_time', 'alpha') != '' ? ' checked="checked"' : '') : ($projectstatic->usage_bill_time ? ' checked="checked"' : '')).'"> ';
990  $htmltext = $langs->trans("ProjectBillTimeDescription");
991  print $form->textwithpicto($langs->trans("BillTime"), $htmltext);
992  print '<br>';
993  }
994  if (isModEnabled('eventorganization')) {
995  print '<input type="checkbox" disabled name="usage_organize_event"'.(GETPOSTISSET('usage_organize_event') ? (GETPOST('usage_organize_event', 'alpha') != '' ? ' checked="checked"' : '') : ($projectstatic->usage_organize_event ? ' checked="checked"' : '')).'"> ';
996  $htmltext = $langs->trans("EventOrganizationDescriptionLong");
997  print $form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext);
998  }
999  print '</td></tr>';
1000  }
1001 
1002  // Visibility
1003  print '<tr><td class="titlefield">'.$langs->trans("Visibility").'</td><td>';
1004  if ($projectstatic->public) {
1005  print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
1006  print $langs->trans('SharedProject');
1007  } else {
1008  print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
1009  print $langs->trans('PrivateProject');
1010  }
1011  print '</td></tr>';
1012 
1013  // Budget
1014  print '<tr><td>'.$langs->trans("Budget").'</td><td>';
1015  if (strcmp($projectstatic->budget_amount, '')) {
1016  print '<span class="amount">'.price($projectstatic->budget_amount, '', $langs, 1, 0, 0, $conf->currency).'</span>';
1017  }
1018  print '</td></tr>';
1019 
1020  // Date start - end project
1021  print '<tr><td>'.$langs->trans("Dates").'</td><td>';
1022  $start = dol_print_date($projectstatic->date_start, 'day');
1023  print ($start ? $start : '?');
1024  $end = dol_print_date($projectstatic->date_end, 'day');
1025  print ' - ';
1026  print ($end ? $end : '?');
1027  if ($projectstatic->hasDelay()) {
1028  print img_warning("Late");
1029  }
1030  print '</td></tr>';
1031 
1032  // Other attributes
1033  $cols = 2;
1034  $savobject = $object;
1035  $object = $projectstatic;
1036  include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php';
1037  $object = $savobject;
1038 
1039  print '</table>';
1040 
1041  print '</div>';
1042  print '<div class="fichehalfright">';
1043  print '<div class="underbanner clearboth"></div>';
1044 
1045  print '<table class="border tableforfield centpercent">';
1046 
1047  // Description
1048  print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>';
1049  print nl2br($projectstatic->description);
1050  print '</td></tr>';
1051 
1052  // Categories
1053  if (isModEnabled('categorie')) {
1054  print '<tr><td class="valignmiddle">'.$langs->trans("Categories").'</td><td>';
1055  print $form->showCategories($projectstatic->id, 'project', 1);
1056  print "</td></tr>";
1057  }
1058 
1059  print '</table>';
1060 
1061  print '</div>';
1062  print '</div>';
1063 
1064  print '<div class="clearboth"></div>';
1065 
1066  print dol_get_fiche_end();
1067 
1068  print '<br>';
1069  }
1070 
1071  // Link to create time
1072  $linktocreatetimeBtnStatus = 0;
1073  $linktocreatetimeUrl = '';
1074  $linktocreatetimeHelpText = '';
1075  if (!empty($user->rights->projet->time)) {
1076  if ($projectstatic->public || $userRead > 0) {
1077  $linktocreatetimeBtnStatus = 1;
1078 
1079  if (!empty($projectidforalltimes)) {
1080  // We are on tab 'Time Spent' of project
1081  $backtourl = $_SERVER['PHP_SELF'].'?projectid='.$projectstatic->id.($withproject ? '&withproject=1' : '');
1082  $linktocreatetimeUrl = $_SERVER['PHP_SELF'].'?'.($withproject ? 'withproject=1' : '').'&projectid='.$projectstatic->id.'&action=createtime&token='.newToken().$param.'&backtopage='.urlencode($backtourl);
1083  } else {
1084  // We are on tab 'Time Spent' of task
1085  $backtourl = $_SERVER['PHP_SELF'].'?id='.$object->id.($withproject ? '&withproject=1' : '');
1086  $linktocreatetimeUrl = $_SERVER['PHP_SELF'].'?'.($withproject ? 'withproject=1' : '').($object->id > 0 ? '&id='.$object->id : '&projectid='.$projectstatic->id).'&action=createtime&token='.newToken().$param.'&backtopage='.urlencode($backtourl);
1087  }
1088  } else {
1089  $linktocreatetimeBtnStatus = -2;
1090  $linktocreatetimeHelpText = $langs->trans("NotOwnerOfProject");
1091  }
1092  } else {
1093  $linktocreatetimeBtnStatus = -2;
1094  $linktocreatetimeHelpText = $langs->trans("NotEnoughPermissions");
1095  }
1096 
1097  $paramsbutton = array('morecss'=>'reposition');
1098  $linktocreatetime = dolGetButtonTitle($langs->trans('AddTimeSpent'), $linktocreatetimeHelpText, 'fa fa-plus-circle', $linktocreatetimeUrl, '', $linktocreatetimeBtnStatus, $paramsbutton);
1099  }
1100 
1101  $massactionbutton = '';
1102  $arrayofmassactions = array();
1103 
1104  if ($projectstatic->id > 0) {
1105  // If we are on a given project.
1106  if ($projectstatic->usage_bill_time) {
1107  $arrayofmassactions = array(
1108  'generateinvoice'=>$langs->trans("GenerateBill"),
1109  //'builddoc'=>$langs->trans("PDFMerge"),
1110  );
1111  }
1112  if ( isModEnabled('ficheinter') && $user->rights->ficheinter->creer) {
1113  $langs->load("interventions");
1114  $arrayofmassactions['generateinter'] = $langs->trans("GenerateInter");
1115  }
1116  }
1117  //if ($user->rights->projet->creer) $arrayofmassactions['predelete']='<span class="fa fa-trash paddingrightonly"></span>'.$langs->trans("Delete");
1118  if (in_array($massaction, array('presend', 'predelete', 'generateinvoice', 'generateinter'))) {
1119  $arrayofmassactions = array();
1120  }
1121  $massactionbutton = $form->selectMassAction('', $arrayofmassactions);
1122 
1123  // Show section with information of task. If id of task is not defined and project id defined, then $projectidforalltimes is not empty.
1124  if (empty($projectidforalltimes) && empty($allprojectforuser)) {
1125  $head = task_prepare_head($object);
1126  print dol_get_fiche_head($head, 'task_time', $langs->trans("Task"), -1, 'projecttask', 0, '', 'reposition');
1127 
1128  if ($action == 'deleteline') {
1129  print $form->formconfirm($_SERVER["PHP_SELF"]."?".($object->id > 0 ? "id=".$object->id : 'projectid='.$projectstatic->id).'&lineid='.GETPOST("lineid", 'int').($withproject ? '&withproject=1' : ''), $langs->trans("DeleteATimeSpent"), $langs->trans("ConfirmDeleteATimeSpent"), "confirm_deleteline", '', '', 1);
1130  }
1131 
1132  $param = ($withproject ? '&withproject=1' : '');
1133  $linkback = $withproject ? '<a href="'.DOL_URL_ROOT.'/projet/tasks.php?id='.$projectstatic->id.'">'.$langs->trans("BackToList").'</a>' : '';
1134 
1135  if (!GETPOST('withproject') || empty($projectstatic->id)) {
1136  $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1);
1137  $object->next_prev_filter = " fk_projet IN (".$db->sanitize($projectsListId).")";
1138  } else {
1139  $object->next_prev_filter = " fk_projet = ".$projectstatic->id;
1140  }
1141 
1142  $morehtmlref = '';
1143 
1144  // Project
1145  if (empty($withproject)) {
1146  $morehtmlref .= '<div class="refidno">';
1147  $morehtmlref .= $langs->trans("Project").': ';
1148  $morehtmlref .= $projectstatic->getNomUrl(1);
1149  $morehtmlref .= '<br>';
1150 
1151  // Third party
1152  $morehtmlref .= $langs->trans("ThirdParty").': ';
1153  if (!empty($projectstatic->thirdparty) && is_object($projectstatic->thirdparty)) {
1154  $morehtmlref .= $projectstatic->thirdparty->getNomUrl(1);
1155  }
1156  $morehtmlref .= '</div>';
1157  }
1158 
1159  dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $param);
1160 
1161  print '<div class="fichecenter">';
1162  print '<div class="fichehalfleft">';
1163 
1164  print '<div class="underbanner clearboth"></div>';
1165  print '<table class="border centpercent tableforfield">';
1166 
1167  // Task parent
1168  print '<tr><td>'.$langs->trans("ChildOfTask").'</td><td>';
1169  if ($object->fk_task_parent > 0) {
1170  $tasktmp = new Task($db);
1171  $tasktmp->fetch($object->fk_task_parent);
1172  print $tasktmp->getNomUrl(1);
1173  }
1174  print '</td></tr>';
1175 
1176  // Date start - Date end task
1177  print '<tr><td class="titlefield">'.$langs->trans("DateStart").' - '.$langs->trans("Deadline").'</td><td>';
1178  $start = dol_print_date($object->date_start, 'dayhour');
1179  print ($start ? $start : '?');
1180  $end = dol_print_date($object->date_end, 'dayhour');
1181  print ' - ';
1182  print ($end ? $end : '?');
1183  if ($object->hasDelay()) {
1184  print img_warning("Late");
1185  }
1186  print '</td></tr>';
1187 
1188  // Planned workload
1189  print '<tr><td>'.$langs->trans("PlannedWorkload").'</td><td>';
1190  if ($object->planned_workload) {
1191  print convertSecondToTime($object->planned_workload, 'allhourmin');
1192  }
1193  print '</td></tr>';
1194 
1195  print '</table>';
1196  print '</div>';
1197 
1198  print '<div class="fichehalfright">';
1199 
1200  print '<div class="underbanner clearboth"></div>';
1201  print '<table class="border tableforfield centpercent">';
1202 
1203  // Progress declared
1204  print '<tr><td class="titlefield">'.$langs->trans("ProgressDeclared").'</td><td>';
1205  print $object->progress != '' ? $object->progress.' %' : '';
1206  print '</td></tr>';
1207 
1208  // Progress calculated
1209  print '<tr><td>'.$langs->trans("ProgressCalculated").'</td><td>';
1210  if ($object->planned_workload) {
1211  $tmparray = $object->getSummaryOfTimeSpent();
1212  if ($tmparray['total_duration'] > 0) {
1213  print round($tmparray['total_duration'] / $object->planned_workload * 100, 2).' %';
1214  } else {
1215  print '0 %';
1216  }
1217  } else {
1218  print '<span class="opacitymedium">'.$langs->trans("WorkloadNotDefined").'</span>';
1219  }
1220  print '</td>';
1221 
1222  print '</tr>';
1223 
1224  print '</table>';
1225 
1226  print '</div>';
1227 
1228  print '</div>';
1229  print '<div class="clearboth"></div>';
1230 
1231  print dol_get_fiche_end();
1232  }
1233 
1234 
1235  if ($projectstatic->id > 0 || $allprojectforuser > 0) {
1236  if ($action == 'deleteline' && !empty($projectidforalltimes)) {
1237  print $form->formconfirm($_SERVER["PHP_SELF"]."?".($object->id > 0 ? "id=".$object->id : 'projectid='.$projectstatic->id).'&lineid='.GETPOST('lineid', 'int').($withproject ? '&withproject=1' : ''), $langs->trans("DeleteATimeSpent"), $langs->trans("ConfirmDeleteATimeSpent"), "confirm_deleteline", '', '', 1);
1238  }
1239 
1240  // Initialize technical object to manage hooks. Note that conf->hooks_modules contains array
1241  $hookmanager->initHooks(array('tasktimelist'));
1242 
1243  $formconfirm = '';
1244 
1245  if ($action == 'deleteline' && !empty($projectidforalltimes)) {
1246  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?".($object->id > 0 ? "id=".$object->id : 'projectid='.$projectstatic->id).'&lineid='.GETPOST('lineid', 'int').($withproject ? '&withproject=1' : ''), $langs->trans("DeleteATimeSpent"), $langs->trans("ConfirmDeleteATimeSpent"), "confirm_deleteline", '', '', 1);
1247  }
1248 
1249  // Call Hook formConfirm
1250  $parameters = array('formConfirm' => $formconfirm, "projectstatic" => $projectstatic, "withproject" => $withproject);
1251  $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1252  if (empty($reshook)) {
1253  $formconfirm .= $hookmanager->resPrint;
1254  } elseif ($reshook > 0) {
1255  $formconfirm = $hookmanager->resPrint;
1256  }
1257 
1258  // Print form confirm
1259  print $formconfirm;
1260 
1261  // Definition of fields for list
1262  $arrayfields = array();
1263  $arrayfields['t.task_date'] = array('label'=>$langs->trans("Date"), 'checked'=>1);
1264  $arrayfields['p.fk_soc'] = array('label'=>$langs->trans("ThirdParty"), 'type'=>'integer:Societe:/societe/class/societe.class.php:1','checked'=>1);
1265  $arrayfields['s.name_alias'] = array('label'=>$langs->trans("AliasNameShort"), 'type'=>'integer:Societe:/societe/class/societe.class.php:1');
1266  if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task
1267  if (! empty($allprojectforuser)) {
1268  $arrayfields['p.project_ref'] = ['label' => $langs->trans('RefProject'), 'checked' => 1];
1269  $arrayfields['p.project_label'] = ['label' => $langs->trans('ProjectLabel'), 'checked' => 1];
1270  }
1271  $arrayfields['t.task_ref'] = array('label'=>$langs->trans("RefTask"), 'checked'=>1);
1272  $arrayfields['t.task_label'] = array('label'=>$langs->trans("LabelTask"), 'checked'=>1);
1273  }
1274  $arrayfields['author'] = array('label'=>$langs->trans("By"), 'checked'=>1);
1275  $arrayfields['t.note'] = array('label'=>$langs->trans("Note"), 'checked'=>1);
1276  if (isModEnabled('service') && !empty($projectstatic->thirdparty) && $projectstatic->thirdparty->id > 0 && $projectstatic->usage_bill_time) {
1277  $arrayfields['t.fk_product'] = array('label' => $langs->trans("Product"), 'checked' => 1);
1278  }
1279  $arrayfields['t.task_duration'] = array('label'=>$langs->trans("Duration"), 'checked'=>1);
1280  $arrayfields['value'] = array('label'=>$langs->trans("Value"), 'checked'=>1, 'enabled'=>(empty($conf->salaries->enabled) ? 0 : 1));
1281  $arrayfields['valuebilled'] = array('label'=>$langs->trans("Billed"), 'checked'=>1, 'enabled'=>(((!empty($conf->global->PROJECT_HIDE_TASKS) || empty($conf->global->PROJECT_BILL_TIME_SPENT)) ? 0 : 1) && $projectstatic->usage_bill_time));
1282  // Extra fields
1283  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
1284 
1285  $arrayfields = dol_sort_array($arrayfields, 'position');
1286 
1287  $param = '';
1288  if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
1289  $param .= '&contextpage='.urlencode($contextpage);
1290  }
1291  if ($limit > 0 && $limit != $conf->liste_limit) {
1292  $param .= '&limit='.urlencode($limit);
1293  }
1294  if ($search_month > 0) {
1295  $param .= '&search_month='.urlencode($search_month);
1296  }
1297  if ($search_year > 0) {
1298  $param .= '&search_year='.urlencode($search_year);
1299  }
1300  if ($search_user > 0) {
1301  $param .= '&search_user='.urlencode($search_user);
1302  }
1303  if ($search_task_ref != '') {
1304  $param .= '&search_task_ref='.urlencode($search_task_ref);
1305  }
1306  if ($search_company != '') {
1307  $param .= '&amp;$search_company='.urlencode($search_company);
1308  }
1309  if ($search_company_alias != '') {
1310  $param .= '&amp;$search_company_alias='.urlencode($search_company_alias);
1311  }
1312  if ($search_project_ref != '') {
1313  $param .= '&amp;$search_project_ref='.urlencode($search_project_ref);
1314  }
1315  if ($search_project_label != '') {
1316  $param .= '&amp;$search_project_label='.urlencode($search_project_label);
1317  }
1318  if ($search_task_label != '') {
1319  $param .= '&search_task_label='.urlencode($search_task_label);
1320  }
1321  if ($search_note != '') {
1322  $param .= '&search_note='.urlencode($search_note);
1323  }
1324  if ($search_duration != '') {
1325  $param .= '&amp;search_field2='.urlencode($search_duration);
1326  }
1327  if ($optioncss != '') {
1328  $param .= '&optioncss='.urlencode($optioncss);
1329  }
1330  if ($search_date_startday) {
1331  $param .= '&search_date_startday='.urlencode($search_date_startday);
1332  }
1333  if ($search_date_startmonth) {
1334  $param .= '&search_date_startmonth='.urlencode($search_date_startmonth);
1335  }
1336  if ($search_date_startyear) {
1337  $param .= '&search_date_startyear='.urlencode($search_date_startyear);
1338  }
1339  if ($search_date_endday) {
1340  $param .= '&search_date_endday='.urlencode($search_date_endday);
1341  }
1342  if ($search_date_endmonth) {
1343  $param .= '&search_date_endmonth='.urlencode($search_date_endmonth);
1344  }
1345  if ($search_date_endyear) {
1346  $param .= '&search_date_endyear='.urlencode($search_date_endyear);
1347  }
1348  if ($search_timespent_starthour) {
1349  $param .= '&search_timespent_duration_starthour='.urlencode($search_timespent_starthour);
1350  }
1351  if ($search_timespent_startmin) {
1352  $param .= '&search_timespent_duration_startmin='.urlencode($search_timespent_startmin);
1353  }
1354  if ($search_timespent_endhour) {
1355  $param .= '&search_timespent_duration_endhour='.urlencode($search_timespent_endhour);
1356  }
1357  if ($search_timespent_endmin) {
1358  $param .= '&search_timespent_duration_endmin='.urlencode($search_timespent_endmin);
1359  }
1360 
1361  /*
1362  // Add $param from extra fields
1363  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
1364  */
1365  if ($id) {
1366  $param .= '&id='.urlencode($id);
1367  }
1368  if ($projectid) {
1369  $param .= '&projectid='.urlencode($projectid);
1370  }
1371  if ($withproject) {
1372  $param .= '&withproject='.urlencode($withproject);
1373  }
1374  // Add $param from hooks
1375  $parameters = array();
1376  $reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook
1377  $param .= $hookmanager->resPrint;
1378 
1379  print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
1380  if ($optioncss != '') {
1381  print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
1382  }
1383  print '<input type="hidden" name="token" value="'.newToken().'">';
1384  print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
1385  if ($action == 'editline') {
1386  print '<input type="hidden" name="action" value="updateline">';
1387  } elseif ($action == 'splitline') {
1388  print '<input type="hidden" name="action" value="updatesplitline">';
1389  } elseif ($action == 'createtime' && $user->rights->projet->time) {
1390  print '<input type="hidden" name="action" value="addtimespent">';
1391  } elseif ($massaction == 'generateinvoice' && $user->rights->facture->creer) {
1392  print '<input type="hidden" name="action" value="confirm_generateinvoice">';
1393  } elseif ($massaction == 'generateinter' && $user->rights->ficheinter->creer) {
1394  print '<input type="hidden" name="action" value="confirm_generateinter">';
1395  } else {
1396  print '<input type="hidden" name="action" value="list">';
1397  }
1398  print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
1399  print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
1400 
1401  print '<input type="hidden" name="id" value="'.$id.'">';
1402  print '<input type="hidden" name="projectid" value="'.$projectidforalltimes.'">';
1403  print '<input type="hidden" name="withproject" value="'.$withproject.'">';
1404  print '<input type="hidden" name="tab" value="'.$tab.'">';
1405  print '<input type="hidden" name="page_y" value="">';
1406 
1407  // Form to convert time spent into invoice
1408  if ($massaction == 'generateinvoice') {
1409  if ($projectstatic->thirdparty->id > 0) {
1410  print '<table class="noborder centerpercent">';
1411  print '<tr>';
1412  print '<td class="titlefield">';
1413  print $langs->trans('DateInvoice');
1414  print '</td>';
1415  print '<td>';
1416  print $form->selectDate('', '', '', '', '', '', 1, 1);
1417  print '</td>';
1418  print '</tr>';
1419 
1420  print '<tr>';
1421  print '<td>';
1422  print $langs->trans('Mode');
1423  print '</td>';
1424  print '<td>';
1425  $tmparray = array(
1426  'onelineperuser'=>'OneLinePerUser',
1427  'onelinepertask'=>'OneLinePerTask',
1428  'onelineperperiod'=>'OneLinePerTimeSpentLine',
1429  );
1430  print $form->selectarray('generateinvoicemode', $tmparray, 'onelineperuser', 0, 0, 0, '', 1);
1431  print "\n".'<script type="text/javascript">';
1432  print '
1433  $(document).ready(function () {
1434  setDetailVisibility();
1435  $("#generateinvoicemode").change(function() {
1436  setDetailVisibility();
1437  });
1438  function setDetailVisibility() {
1439  generateinvoicemode = $("#generateinvoicemode option:selected").val();
1440  if (generateinvoicemode=="onelineperperiod") {
1441  $("#detail_time_duration").show();
1442  } else {
1443  $("#detail_time_duration").hide();
1444  }
1445  }
1446  });
1447  ';
1448  print '</script>'."\n";
1449  print '<span style="display:none" id="detail_time_duration"><input type="checkbox" value="detail" name="detail_time_duration"/>'.$langs->trans('AddDetailDateAndDuration').'</span>';
1450  print '</td>';
1451  print '</tr>';
1452 
1453  if ($conf->service->enabled) {
1454  print '<tr>';
1455  print '<td>';
1456  print $langs->trans('ServiceToUseOnLines');
1457  print '</td>';
1458  print '<td>';
1459  $form->select_produits('', 'productid', '1', 0, $projectstatic->thirdparty->price_level, 1, 2, '', 0, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth500');
1460  print '</td>';
1461  print '</tr>';
1462  }
1463 
1464  print '<tr>';
1465  print '<td class="titlefield">';
1466  print $langs->trans('InvoiceToUse');
1467  print '</td>';
1468  print '<td>';
1469  $form->selectInvoice($projectstatic->thirdparty->id, '', 'invoiceid', 24, 0, $langs->trans('NewInvoice'), 1, 0, 0, 'maxwidth500', '', 'all');
1470  print '</td>';
1471  print '</tr>';
1472  /*print '<tr>';
1473  print '<td>';
1474  print $langs->trans('ValidateInvoices');
1475  print '</td>';
1476  print '<td>';
1477  print $form->selectyesno('validate_invoices', 0, 1);
1478  print '</td>';
1479  print '</tr>';*/
1480  print '</table>';
1481 
1482  print '<br>';
1483  print '<div class="center">';
1484  print '<input type="submit" class="button" id="createbills" name="createbills" value="'.$langs->trans('GenerateBill').'"> ';
1485  print '<input type="submit" class="button button-cancel" id="cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
1486  print '</div>';
1487  print '<br>';
1488  } else {
1489  print '<div class="warning">'.$langs->trans("ThirdPartyRequiredToGenerateInvoice").'</div>';
1490  print '<div class="center">';
1491  print '<input type="submit" class="button button-cancel" id="cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
1492  print '</div>';
1493  $massaction = '';
1494  }
1495  } elseif ($massaction == 'generateinter') {
1496  // Form to convert time spent into invoice
1497  print '<input type="hidden" name="massaction" value="confirm_createinter">';
1498 
1499  if ($projectstatic->thirdparty->id > 0) {
1500  print '<br>';
1501  print '<table class="noborder centpercent">';
1502  print '<tr>';
1503  print '<td class="titlefield">';
1504  print img_picto('', 'intervention', 'class="pictofixedwidth"').$langs->trans('InterToUse');
1505  print '</td>';
1506  print '<td>';
1507  $forminter = new FormIntervention($db);
1508  print $forminter->select_interventions($projectstatic->thirdparty->id, '', 'interid', 24, $langs->trans('NewInter'), true);
1509  print '</td>';
1510  print '</tr>';
1511  print '</table>';
1512 
1513  print '<div class="center">';
1514  print '<input type="submit" class="button" id="createinter" name="createinter" value="'.$langs->trans('GenerateInter').'"> ';
1515  print '<input type="submit" class="button" id="cancel" name="cancel" value="'.$langs->trans('Cancel').'">';
1516  print '</div>';
1517  print '<br>';
1518  } else {
1519  print '<div class="warning">'.$langs->trans("ThirdPartyRequiredToGenerateIntervention").'</div>';
1520  print '<div class="center">';
1521  print '<input type="submit" class="button" id="cancel" name="cancel" value="'.$langs->trans('Cancel').'">';
1522  print '</div>';
1523  $massaction = '';
1524  }
1525  }
1526 
1527  // Allow Pre-Mass-Action hook (eg for confirmation dialog)
1528  $parameters = array(
1529  'toselect' => $toselect,
1530  'uploaddir' => isset($uploaddir) ? $uploaddir : null
1531  );
1532 
1533  $reshook = $hookmanager->executeHooks('doPreMassActions', $parameters, $object, $action);
1534  if ($reshook < 0) {
1535  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1536  } else {
1537  print $hookmanager->resPrint;
1538  }
1539 
1540  /*
1541  * List of time spent
1542  */
1543  $tasks = array();
1544 
1545  $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
1546  $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // This also change content of $arrayfields
1547 
1548  $sql = "SELECT t.rowid, t.fk_task, t.task_date, t.task_datehour, t.task_date_withhour, t.task_duration, t.fk_user, t.note, t.thm,";
1549  $sql .= " t.fk_product,";
1550  $sql .= " pt.ref, pt.label, pt.fk_projet,";
1551  $sql .= " u.lastname, u.firstname, u.login, u.photo, u.statut as user_status,";
1552  $sql .= " il.fk_facture as invoice_id, inv.fk_statut,";
1553  $sql .= " p.fk_soc,s.name_alias,";
1554  // Add fields from hooks
1555  $parameters = array();
1556  $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
1557  $sql .= preg_replace('/^,/', '', $hookmanager->resPrint);
1558  $sql = preg_replace('/,\s*$/', '', $sql);
1559  $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t";
1560  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facturedet as il ON il.rowid = t.invoice_line_id";
1561  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture as inv ON inv.rowid = il.fk_facture";
1562  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as prod ON prod.rowid = t.fk_product";
1563  $sql .= " INNER JOIN ".MAIN_DB_PREFIX."projet_task as pt ON pt.rowid = t.fk_task";
1564  $sql .= " INNER JOIN ".MAIN_DB_PREFIX."projet as p ON p.rowid = pt.fk_projet";
1565  $sql .= " INNER JOIN ".MAIN_DB_PREFIX."user as u ON t.fk_user = u.rowid";
1566  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = p.fk_soc";
1567 
1568  // Add table from hooks
1569  $parameters = array();
1570  $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook
1571  $sql .= $hookmanager->resPrint;
1572  $sql .= " WHERE 1 = 1 ";
1573  if (empty($projectidforalltimes) && empty($allprojectforuser)) {
1574  // Limit on one task
1575  $sql .= " AND t.fk_task =".((int) $object->id);
1576  } elseif (!empty($projectidforalltimes)) {
1577  // Limit on one project
1578  $sql .= " AND pt.fk_projet IN (".$db->sanitize($projectidforalltimes).")";
1579  } elseif (!empty($allprojectforuser)) {
1580  // Limit on on user
1581  if (empty($search_user)) {
1582  $search_user = $user->id;
1583  }
1584  if ($search_user > 0) $sql .= " AND t.fk_user = ".((int) $search_user);
1585  }
1586 
1587  if ($search_note) {
1588  $sql .= natural_search('t.note', $search_note);
1589  }
1590  if ($search_task_ref) {
1591  $sql .= natural_search('pt.ref', $search_task_ref);
1592  }
1593  if (empty($arrayfields['s.name_alias']['checked']) && $search_company) {
1594  $sql .= natural_search(array("s.nom", "s.name_alias"), $search_company);
1595  } else {
1596  if ($search_company) {
1597  $sql .= natural_search('s.nom', $search_company);
1598  }
1599  if ($search_company_alias) {
1600  $sql .= natural_search('s.name_alias', $search_company_alias);
1601  }
1602  }
1603  if ($search_project_ref) {
1604  $sql .= natural_search('p.ref', $search_project_ref);
1605  }
1606  if ($search_project_label) {
1607  $sql .= natural_search('p.title', $search_project_label);
1608  }
1609  if ($search_task_label) {
1610  $sql .= natural_search('pt.label', $search_task_label);
1611  }
1612  if ($search_user > 0) {
1613  $sql .= natural_search('t.fk_user', $search_user, 2);
1614  }
1615  if (!empty($search_product_ref)) {
1616  $sql .= natural_search('prod.ref', $search_product_ref);
1617  }
1618  if ($search_valuebilled == '1') {
1619  $sql .= ' AND t.invoice_id > 0';
1620  }
1621  if ($search_valuebilled == '0') {
1622  $sql .= ' AND (t.invoice_id = 0 OR t.invoice_id IS NULL)';
1623  }
1624 
1625  if ($search_date_start) {
1626  $sql .= " AND t.task_date >= '".$db->idate($search_date_start)."'";
1627  }
1628  if ($search_date_end) {
1629  $sql .= " AND t.task_date <= '".$db->idate($search_date_end)."'";
1630  }
1631 
1632  if (!empty($arrayfields['t.task_duration']['checked'])) {
1633  if ($search_timespent_starthour || $search_timespent_startmin) {
1634  $timespent_duration_start = $search_timespent_starthour * 60 * 60; // We store duration in seconds
1635  $timespent_duration_start += ($search_timespent_startmin ? $search_timespent_startmin : 0) * 60; // We store duration in seconds
1636  $sql .= " AND t.task_duration >= " . $timespent_duration_start;
1637  }
1638 
1639  if ($search_timespent_endhour || $search_timespent_endmin) {
1640  $timespent_duration_end = $search_timespent_endhour * 60 * 60; // We store duration in seconds
1641  $timespent_duration_end += ($search_timespent_endmin ? $search_timespent_endmin : 0) * 60; // We store duration in seconds
1642  $sql .= " AND t.task_duration <= " . $timespent_duration_end;
1643  }
1644  }
1645 
1646  $sql .= dolSqlDateFilter('t.task_datehour', $search_day, $search_month, $search_year);
1647 
1648  // Add where from hooks
1649  $parameters = array();
1650  $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
1651  $sql .= $hookmanager->resPrint;
1652  $sql .= $db->order($sortfield, $sortorder);
1653 
1654  // Count total nb of records
1655  $nbtotalofrecords = '';
1656  if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
1657  $resql = $db->query($sql);
1658 
1659  if (! $resql) {
1660  dol_print_error($db);
1661  exit;
1662  }
1663 
1664  $nbtotalofrecords = $db->num_rows($resql);
1665  if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0
1666  $page = 0;
1667  $offset = 0;
1668  }
1669  }
1670  // if total of record found is smaller than limit, no need to do paging and to restart another select with limits set.
1671  if (is_numeric($nbtotalofrecords) && $limit > $nbtotalofrecords) {
1672  $num = $nbtotalofrecords;
1673  } else {
1674  $sql .= $db->plimit($limit + 1, $offset);
1675 
1676  $resql = $db->query($sql);
1677  if (!$resql) {
1678  dol_print_error($db);
1679  exit;
1680  }
1681 
1682  $num = $db->num_rows($resql);
1683  }
1684 
1685  if ($num >= 0) {
1686  if (!empty($projectidforalltimes)) {
1687  print '<!-- List of time spent for project -->'."\n";
1688 
1689  $title = $langs->trans("ListTaskTimeUserProject");
1690 
1691  print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'clock', 0, $linktocreatetime, '', $limit, 0, 0, 1);
1692  } else {
1693  print '<!-- List of time spent -->'."\n";
1694 
1695  $title = $langs->trans("ListTaskTimeForTask");
1696 
1697  print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'clock', 0, $linktocreatetime, '', $limit, 0, 0, 1);
1698  }
1699 
1700  $i = 0;
1701  while ($i < $num) {
1702  $row = $db->fetch_object($resql);
1703  $tasks[$i] = $row;
1704  $i++;
1705  }
1706  $db->free($resql);
1707  } else {
1708  dol_print_error($db);
1709  }
1710 
1711  /*
1712  * Form to add a new line of time spent
1713  */
1714  if ($action == 'createtime' && $user->rights->projet->time) {
1715  print '<!-- table to add time spent -->'."\n";
1716  if (!empty($id)) {
1717  print '<input type="hidden" name="taskid" value="'.$id.'">';
1718  }
1719 
1720  print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
1721  print '<table class="noborder nohover centpercent">';
1722 
1723  print '<tr class="liste_titre">';
1724  print '<td>'.$langs->trans("Date").'</td>';
1725  if (!empty($allprojectforuser)) {
1726  print '<td>'.$langs->trans("Project").'</td>';
1727  }
1728  if (empty($id)) {
1729  print '<td>'.$langs->trans("Task").'</td>';
1730  }
1731  print '<td>'.$langs->trans("By").'</td>';
1732  print '<td>'.$langs->trans("Note").'</td>';
1733  print '<td>'.$langs->trans("NewTimeSpent").'</td>';
1734  print '<td>'.$langs->trans("ProgressDeclared").'</td>';
1735  if (empty($conf->global->PROJECT_HIDE_TASKS) && !empty($conf->global->PROJECT_BILL_TIME_SPENT)) {
1736  print '<td></td>';
1737 
1738  if ($conf->service->enabled && $projectstatic->thirdparty->id > 0 && $projectstatic->usage_bill_time) {
1739  print '<td>'.$langs->trans("Product").'</td>';
1740  }
1741  }
1742  // Hook fields
1743  $parameters = array('mode' => 'create');
1744  $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook
1745  print $hookmanager->resPrint;
1746  print '<td></td>';
1747  print "</tr>\n";
1748 
1749  print '<tr class="oddeven nohover">';
1750 
1751  // Date
1752  print '<td class="maxwidthonsmartphone">';
1753  $newdate = '';
1754  print $form->selectDate($newdate, 'time', ($conf->browser->layout == 'phone' ? 2 : 1), 1, 2, "timespent_date", 1, 0);
1755  print '</td>';
1756 
1757  if (!empty($allprojectforuser)) {
1758  print '<td>';
1759  // Add project selector
1760  print '</td>';
1761  }
1762 
1763  // Task
1764  $nboftasks = 0;
1765  if (empty($id)) {
1766  print '<td class="maxwidthonsmartphone">';
1767  $nboftasks = $formproject->selectTasks(-1, GETPOST('taskid', 'int'), 'taskid', 0, 0, 1, 1, 0, 0, 'maxwidth300', $projectstatic->id, 'progress');
1768  print '</td>';
1769  }
1770 
1771  // Contributor
1772  print '<td class="maxwidthonsmartphone nowraponall">';
1773  $contactsofproject = $projectstatic->getListContactId('internal');
1774  if (count($contactsofproject) > 0) {
1775  print img_object('', 'user', 'class="hideonsmartphone"');
1776  if (in_array($user->id, $contactsofproject)) {
1777  $userid = $user->id;
1778  } else {
1779  $userid = $contactsofproject[0];
1780  }
1781 
1782  if ($projectstatic->public) {
1783  $contactsofproject = array();
1784  }
1785  print $form->select_dolusers((GETPOST('userid', 'int') ? GETPOST('userid', 'int') : $userid), 'userid', 0, '', 0, '', $contactsofproject, 0, 0, 0, '', 0, $langs->trans("ResourceNotAssignedToProject"), 'maxwidth250');
1786  } else {
1787  if ($nboftasks) {
1788  print img_error($langs->trans('FirstAddRessourceToAllocateTime')).' '.$langs->trans('FirstAddRessourceToAllocateTime');
1789  }
1790  }
1791  print '</td>';
1792 
1793  // Note
1794  print '<td>';
1795  print '<textarea name="timespent_note" class="maxwidth100onsmartphone" rows="'.ROWS_2.'">'.(GETPOST('timespent_note') ? GETPOST('timespent_note') : '').'</textarea>';
1796  print '</td>';
1797 
1798  // Duration - Time spent
1799  print '<td class="nowraponall">';
1800  $durationtouse = (GETPOST('timespent_duration') ? GETPOST('timespent_duration') : '');
1801  if (GETPOSTISSET('timespent_durationhour') || GETPOSTISSET('timespent_durationmin')) {
1802  $durationtouse = (GETPOST('timespent_durationhour') * 3600 + GETPOST('timespent_durationmin') * 60);
1803  }
1804  print $form->select_duration('timespent_duration', $durationtouse, 0, 'text');
1805  print '</td>';
1806 
1807  // Progress declared
1808  print '<td class="nowrap">';
1809  print $formother->select_percent(GETPOST('progress') ?GETPOST('progress') : $object->progress, 'progress', 0, 5, 0, 100, 1);
1810  print '</td>';
1811 
1812  // Invoiced
1813  if (empty($conf->global->PROJECT_HIDE_TASKS) && !empty($conf->global->PROJECT_BILL_TIME_SPENT)) {
1814  print '<td>';
1815  print '</td>';
1816 
1817  if ($conf->service->enabled && $projectstatic->thirdparty->id > 0 && $projectstatic->usage_bill_time) {
1818  print '<td class="nowrap">';
1819  print $form->select_produits('', 'fk_product', '1', 0, $projectstatic->thirdparty->price_level, 1, 2, '', 0, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth500');
1820  print '</td>';
1821  }
1822  }
1823 
1824  // Fields from hook
1825  $parameters = array('mode' => 'create');
1826  $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook
1827  print $hookmanager->resPrint;
1828 
1829  print '<td class="center">';
1830  $form->buttonsSaveCancel();
1831  print '<input type="submit" name="save" class="button buttongen marginleftonly margintoponlyshort marginbottomonlyshort button-add" value="'.$langs->trans("Add").'">';
1832  print '<input type="submit" name="cancel" class="button buttongen marginleftonly margintoponlyshort marginbottomonlyshort button-cancel" value="'.$langs->trans("Cancel").'">';
1833  print '</td></tr>';
1834 
1835  print '</table>';
1836  print '</div>';
1837 
1838  print '<br>';
1839  }
1840 
1841  $moreforfilter = '';
1842 
1843  $parameters = array();
1844  $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
1845  if (empty($reshook)) {
1846  $moreforfilter .= $hookmanager->resPrint;
1847  } else {
1848  $moreforfilter = $hookmanager->resPrint;
1849  }
1850 
1851  if (!empty($moreforfilter)) {
1852  print '<div class="liste_titre liste_titre_bydiv centpercent">';
1853  print $moreforfilter;
1854  print '</div>';
1855  }
1856 
1857  $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
1858  $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
1859  $selectedfields .= (is_array($arrayofmassactions) && count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : '');
1860 
1861  print '<div class="div-table-responsive">';
1862  print '<table class="tagtable nobottomiftotal liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
1863 
1864  // Fields title search
1865  print '<tr class="liste_titre_filter">';
1866  // Date
1867  if (!empty($arrayfields['t.task_date']['checked'])) {
1868  print '<td class="liste_titre left">';
1869  print '<div class="nowrap">';
1870  print $form->selectDate($search_date_start ? $search_date_start : -1, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
1871  print '</div>';
1872  print '<div class="nowrap">';
1873  print $form->selectDate($search_date_end ? $search_date_end : -1, 'search_date_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
1874  print '</div>';
1875  print '</td>';
1876  }
1877  // Thirdparty
1878  if (!empty($arrayfields['p.fk_soc']['checked'])) {
1879  print '<td class="liste_titre"><input type="text" class="flat maxwidth100" name="$search_company" value="'.dol_escape_htmltag($search_company).'"></td>';
1880  }
1881 
1882  // Thirdparty alias
1883  if (!empty($arrayfields['s.name_alias']['checked'])) {
1884  print '<td class="liste_titre"><input type="text" class="flat maxwidth100" name="$search_company_alias" value="'.dol_escape_htmltag($search_company_alias).'"></td>';
1885  }
1886 
1887  if (!empty($allprojectforuser)) {
1888  if (!empty($arrayfields['p.project_ref']['checked'])) {
1889  print '<td class="liste_titre"><input type="text" class="flat maxwidth100" name="$search_project_ref" value="'.dol_escape_htmltag($search_project_ref).'"></td>';
1890  }
1891  if (!empty($arrayfields['p.project_label']['checked'])) {
1892  print '<td class="liste_titre"><input type="text" class="flat maxwidth100" name="$search_project_label" value="'.dol_escape_htmltag($search_project_label).'"></td>';
1893  }
1894  }
1895  // Task
1896  if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task
1897  if (!empty($arrayfields['t.task_ref']['checked'])) {
1898  print '<td class="liste_titre"><input type="text" class="flat maxwidth100" name="search_task_ref" value="'.dol_escape_htmltag($search_task_ref).'"></td>';
1899  }
1900  if (!empty($arrayfields['t.task_label']['checked'])) {
1901  print '<td class="liste_titre"><input type="text" class="flat maxwidth100" name="search_task_label" value="'.dol_escape_htmltag($search_task_label).'"></td>';
1902  }
1903  }
1904  // Author
1905  if (!empty($arrayfields['author']['checked'])) {
1906  print '<td class="liste_titre">'.$form->select_dolusers(($search_user > 0 ? $search_user : -1), 'search_user', 1, null, 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth250').'</td>';
1907  }
1908  // Note
1909  if (!empty($arrayfields['t.note']['checked'])) {
1910  print '<td class="liste_titre"><input type="text" class="flat maxwidth100" name="search_note" value="'.dol_escape_htmltag($search_note).'"></td>';
1911  }
1912  // Duration
1913  if (!empty($arrayfields['t.task_duration']['checked'])) {
1914  // Duration - Time spent
1915  print '<td class="liste_titre right">';
1916 
1917  $durationtouse_start = 0;
1918  if ($search_timespent_starthour || $search_timespent_startmin) {
1919  $durationtouse_start = ($search_timespent_starthour * 3600 + $search_timespent_startmin * 60);
1920  }
1921  print '<div class="nowraponall">'.$langs->trans('from').'&nbsp;';
1922  $form->select_duration('search_timespent_duration_start', $durationtouse_start, 0, 'text');
1923  print '</div>';
1924 
1925  $durationtouse_end = 0;
1926  if ($search_timespent_endhour || $search_timespent_endmin) {
1927  $durationtouse_end = ($search_timespent_endhour * 3600 + $search_timespent_endmin * 60);
1928  }
1929  print '<div class="nowraponall">'.$langs->trans('at').'&nbsp;';
1930  $form->select_duration('search_timespent_duration_end', $durationtouse_end, 0, 'text');
1931  print '</div>';
1932 
1933  print '</td>';
1934  }
1935  // Product
1936  if (!empty($arrayfields['t.fk_product']['checked'])) {
1937  print '<td class="liste_titre right"></td>';
1938  }
1939  // Value in main currency
1940  if (!empty($arrayfields['value']['checked'])) {
1941  print '<td class="liste_titre"></td>';
1942  }
1943  // Value billed
1944  if (!empty($arrayfields['valuebilled']['checked'])) {
1945  print '<td class="liste_titre center">'.$form->selectyesno('search_valuebilled', $search_valuebilled, 1, false, 1).'</td>';
1946  }
1947 
1948  /*
1949  // Extra fields
1950  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
1951  */
1952  // Fields from hook
1953  $parameters = array('arrayfields'=>$arrayfields);
1954  $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook
1955  print $hookmanager->resPrint;
1956  // Action column
1957  print '<td class="liste_titre center">';
1958  $searchpicto = $form->showFilterButtons();
1959  print $searchpicto;
1960  print '</td>';
1961  print '</tr>'."\n";
1962 
1963  print '<tr class="liste_titre">';
1964  if (!empty($arrayfields['t.task_date']['checked'])) {
1965  print_liste_field_titre($arrayfields['t.task_date']['label'], $_SERVER['PHP_SELF'], 't.task_date,t.task_datehour,t.rowid', '', $param, '', $sortfield, $sortorder);
1966  }
1967 
1968  if (!empty($arrayfields['p.fk_soc']['checked'])) {
1969  print_liste_field_titre($arrayfields['p.fk_soc']['label'], $_SERVER['PHP_SELF'], 't.task_date,t.task_datehour,t.rowid', '', $param, '', $sortfield, $sortorder);
1970  }
1971  if (!empty($arrayfields['s.name_alias']['checked'])) {
1972  print_liste_field_titre($arrayfields['s.name_alias']['label'], $_SERVER['PHP_SELF'], 's.name_alias', '', $param, '', $sortfield, $sortorder);
1973  }
1974  if (!empty($allprojectforuser)) {
1975  if (!empty($arrayfields['p.project_ref']['checked'])) {
1976  print_liste_field_titre("Project", $_SERVER['PHP_SELF'], 'p.ref', '', $param, '', $sortfield, $sortorder);
1977  }
1978  if (!empty($arrayfields['p.project_label']['checked'])) {
1979  print_liste_field_titre("ProjectLabel", $_SERVER['PHP_SELF'], 'p.title', '', $param, '', $sortfield, $sortorder);
1980  }
1981  }
1982  if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task
1983  if (!empty($arrayfields['t.task_ref']['checked'])) {
1984  print_liste_field_titre($arrayfields['t.task_ref']['label'], $_SERVER['PHP_SELF'], 'pt.ref', '', $param, '', $sortfield, $sortorder);
1985  }
1986  if (!empty($arrayfields['t.task_label']['checked'])) {
1987  print_liste_field_titre($arrayfields['t.task_label']['label'], $_SERVER['PHP_SELF'], 'pt.label', '', $param, '', $sortfield, $sortorder);
1988  }
1989  }
1990  if (!empty($arrayfields['author']['checked'])) {
1991  print_liste_field_titre($arrayfields['author']['label'], $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder);
1992  }
1993  if (!empty($arrayfields['t.note']['checked'])) {
1994  print_liste_field_titre($arrayfields['t.note']['label'], $_SERVER['PHP_SELF'], 't.note', '', $param, '', $sortfield, $sortorder);
1995  }
1996  if (!empty($arrayfields['t.task_duration']['checked'])) {
1997  print_liste_field_titre($arrayfields['t.task_duration']['label'], $_SERVER['PHP_SELF'], 't.task_duration', '', $param, '', $sortfield, $sortorder, 'right ');
1998  }
1999  if (!empty($arrayfields['t.fk_product']['checked'])) {
2000  print_liste_field_titre($arrayfields['t.fk_product']['label'], $_SERVER['PHP_SELF'], 't.fk_product', '', $param, '', $sortfield, $sortorder);
2001  }
2002 
2003  if (!empty($arrayfields['value']['checked'])) {
2004  print_liste_field_titre($arrayfields['value']['label'], $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder, 'right ');
2005  }
2006  if (!empty($arrayfields['valuebilled']['checked'])) {
2007  print_liste_field_titre($arrayfields['valuebilled']['label'], $_SERVER['PHP_SELF'], 'il.total_ht', '', $param, '', $sortfield, $sortorder, 'center ', $langs->trans("SelectLinesOfTimeSpentToInvoice"));
2008  }
2009  /*
2010  // Extra fields
2011  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
2012  */
2013  // Hook fields
2014  $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder);
2015  $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook
2016  print $hookmanager->resPrint;
2017  print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', 'width="80"', $sortfield, $sortorder, 'center maxwidthsearch ');
2018  print "</tr>\n";
2019 
2020  $tasktmp = new Task($db);
2021  $tmpinvoice = new Facture($db);
2022 
2023  $i = 0;
2024 
2025  $total = 0;
2026  $totalvalue = 0;
2027  $totalarray = array('nbfield'=>0);
2028  foreach ($tasks as $task_time) {
2029  if ($i >= $limit) {
2030  break;
2031  }
2032 
2033  $date1 = $db->jdate($task_time->task_date);
2034  $date2 = $db->jdate($task_time->task_datehour);
2035 
2036  print '<tr class="oddeven">';
2037 
2038  // Date
2039  if (!empty($arrayfields['t.task_date']['checked'])) {
2040  print '<td class="nowrap">';
2041  if ($action == 'editline' && GETPOST('lineid', 'int') == $task_time->rowid) {
2042  if (empty($task_time->task_date_withhour)) {
2043  print $form->selectDate(($date2 ? $date2 : $date1), 'timeline', 3, 3, 2, "timespent_date", 1, 0);
2044  } else {
2045  print $form->selectDate(($date2 ? $date2 : $date1), 'timeline', 1, 1, 2, "timespent_date", 1, 0);
2046  }
2047  } else {
2048  print dol_print_date(($date2 ? $date2 : $date1), ($task_time->task_date_withhour ? 'dayhour' : 'day'));
2049  }
2050  print '</td>';
2051  if (!$i) {
2052  $totalarray['nbfield']++;
2053  }
2054  }
2055 
2056  // Thirdparty
2057  if (!empty($arrayfields['p.fk_soc']['checked'])) {
2058  print '<td class="nowrap">';
2059  if ($task_time->fk_soc > 0) {
2060  if (empty($conf->cache['thridparty'][$task_time->fk_soc])) {
2061  $tmpsociete = new Societe($db);
2062  $tmpsociete->fetch($task_time->fk_soc);
2063  $conf->cache['thridparty'][$task_time->fk_soc] = $tmpsociete;
2064  } else {
2065  $tmpsociete = $conf->cache['thridparty'][$task_time->fk_soc];
2066  }
2067  print $tmpsociete->getNomUrl(1, '', 100, 0, 1, empty($arrayfields['s.name_alias']['checked']) ? 0 : 1);
2068  }
2069  print '</td>';
2070  if (!$i) {
2071  $totalarray['nbfield']++;
2072  }
2073  }
2074 
2075  // Thirdparty alias
2076  if (!empty($arrayfields['s.name_alias']['checked'])) {
2077  print '<td class="nowrap">';
2078  if ($task_time->fk_soc > 0) {
2079  if (empty($conf->cache['thridparty'][$task_time->fk_soc])) {
2080  $tmpsociete = new Societe($db);
2081  $tmpsociete->fetch($task_time->fk_soc);
2082  $conf->cache['thridparty'][$task_time->fk_soc] = $tmpsociete;
2083  } else {
2084  $tmpsociete = $conf->cache['thridparty'][$task_time->fk_soc];
2085  }
2086  print $tmpsociete->name_alias;
2087  }
2088  print '</td>';
2089  if (!$i) {
2090  $totalarray['nbfield']++;
2091  }
2092  }
2093 
2094  // Project ref & label
2095  if (!empty($allprojectforuser)) {
2096  if (!empty($arrayfields['p.project_ref']['checked'])) {
2097  print '<td class="nowraponall">';
2098  if (empty($conf->cache['project'][$task_time->fk_projet])) {
2099  $tmpproject = new Project($db);
2100  $tmpproject->fetch($task_time->fk_projet);
2101  $conf->cache['project'][$task_time->fk_projet] = $tmpproject;
2102  } else {
2103  $tmpproject = $conf->cache['project'][$task_time->fk_projet];
2104  }
2105  print $tmpproject->getNomUrl(1);
2106  print '</td>';
2107  if (! $i) {
2108  $totalarray['nbfield']++;
2109  }
2110  }
2111  if (!empty($arrayfields['p.project_label']['checked'])) {
2112  print '<td class="nowraponall">';
2113  if (empty($conf->cache['project'][$task_time->fk_projet])) {
2114  $tmpproject = new Project($db);
2115  $tmpproject->fetch($task_time->fk_projet);
2116  $conf->cache['project'][$task_time->fk_projet] = $tmpproject;
2117  } else {
2118  $tmpproject = $conf->cache['project'][$task_time->fk_projet];
2119  }
2120  print $tmpproject->title;
2121  print '</td>';
2122  if (! $i) {
2123  $totalarray['nbfield']++;
2124  }
2125  }
2126  }
2127 
2128  // Task ref
2129  if (!empty($arrayfields['t.task_ref']['checked'])) {
2130  if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task
2131  print '<td class="nowrap">';
2132  if ($action == 'editline' && GETPOST('lineid', 'int') == $task_time->rowid) {
2133  $formproject->selectTasks(-1, GETPOST('taskid', 'int') ? GETPOST('taskid', 'int') : $task_time->fk_task, 'taskid', 0, 0, 1, 1, 0, 0, 'maxwidth300', $projectstatic->id, '');
2134  } else {
2135  $tasktmp->id = $task_time->fk_task;
2136  $tasktmp->ref = $task_time->ref;
2137  $tasktmp->label = $task_time->label;
2138  print $tasktmp->getNomUrl(1, 'withproject', 'time');
2139  }
2140  print '</td>';
2141  if (!$i) {
2142  $totalarray['nbfield']++;
2143  }
2144  }
2145  } elseif ($action !== 'createtime') {
2146  print '<input type="hidden" name="taskid" value="'.$id.'">';
2147  }
2148 
2149  // Task label
2150  if (!empty($arrayfields['t.task_label']['checked'])) {
2151  if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task
2152  print '<td class="nowrap tdoverflowmax300" title="'.dol_escape_htmltag($task_time->label).'">';
2153  print dol_escape_htmltag($task_time->label);
2154  print '</td>';
2155  if (!$i) {
2156  $totalarray['nbfield']++;
2157  }
2158  }
2159  }
2160 
2161  // By User
2162  if (!empty($arrayfields['author']['checked'])) {
2163  print '<td class="tdoverflowmax100">';
2164  if ($action == 'editline' && GETPOST('lineid', 'int') == $task_time->rowid) {
2165  if (empty($object->id)) {
2166  $object->fetch($id);
2167  }
2168  $contactsoftask = $object->getListContactId('internal');
2169  if (!in_array($task_time->fk_user, $contactsoftask)) {
2170  $contactsoftask[] = $task_time->fk_user;
2171  }
2172  if (count($contactsoftask) > 0) {
2173  print img_object('', 'user', 'class="hideonsmartphone"');
2174  print $form->select_dolusers($task_time->fk_user, 'userid_line', 0, '', 0, '', $contactsoftask, '0', 0, 0, '', 0, '', 'maxwidth200');
2175  } else {
2176  print img_error($langs->trans('FirstAddRessourceToAllocateTime')).$langs->trans('FirstAddRessourceToAllocateTime');
2177  }
2178  } else {
2179  $userstatic->id = $task_time->fk_user;
2180  $userstatic->lastname = $task_time->lastname;
2181  $userstatic->firstname = $task_time->firstname;
2182  $userstatic->photo = $task_time->photo;
2183  $userstatic->statut = $task_time->user_status;
2184  print $userstatic->getNomUrl(-1);
2185  }
2186  print '</td>';
2187  if (!$i) {
2188  $totalarray['nbfield']++;
2189  }
2190  }
2191 
2192  // Note
2193  if (!empty($arrayfields['t.note']['checked'])) {
2194  print '<td class="small">';
2195  if ($action == 'editline' && GETPOST('lineid', 'int') == $task_time->rowid) {
2196  print '<textarea name="timespent_note_line" width="95%" rows="'.ROWS_1.'">'.dol_escape_htmltag($task_time->note, 0, 1).'</textarea>';
2197  } else {
2198  print dol_nl2br($task_time->note);
2199  }
2200  print '</td>';
2201  if (!$i) {
2202  $totalarray['nbfield']++;
2203  }
2204  } elseif ($action == 'editline' && GETPOST('lineid', 'int') == $task_time->rowid) {
2205  print '<input type="hidden" name="timespent_note_line" value="'.dol_escape_htmltag($task_time->note, 0, 1).'">';
2206  }
2207 
2208  // Time spent
2209  if (!empty($arrayfields['t.task_duration']['checked'])) {
2210  print '<td class="right nowraponall">';
2211  if ($action == 'editline' && GETPOST('lineid', 'int') == $task_time->rowid) {
2212  print '<input type="hidden" name="old_duration" value="'.$task_time->task_duration.'">';
2213  print $form->select_duration('new_duration', $task_time->task_duration, 0, 'text');
2214  } else {
2215  print convertSecondToTime($task_time->task_duration, 'allhourmin');
2216  }
2217  print '</td>';
2218  if (!$i) {
2219  $totalarray['nbfield']++;
2220  }
2221  if (!$i) {
2222  $totalarray['pos'][$totalarray['nbfield']] = 't.task_duration';
2223  }
2224  if (empty($totalarray['val']['t.task_duration'])) {
2225  $totalarray['val']['t.task_duration'] = $task_time->task_duration;
2226  } else {
2227  $totalarray['val']['t.task_duration'] += $task_time->task_duration;
2228  }
2229  if (!$i) {
2230  $totalarray['totaldurationfield'] = $totalarray['nbfield'];
2231  }
2232  if (empty($totalarray['totalduration'])) {
2233  $totalarray['totalduration'] = $task_time->task_duration;
2234  } else {
2235  $totalarray['totalduration'] += $task_time->task_duration;
2236  }
2237  }
2238 
2239  //Product
2240  if (!empty($arrayfields['t.fk_product']['checked'])) {
2241  print '<td class="nowraponall">';
2242  if ($action == 'editline' && $_GET['lineid'] == $task_time->rowid) {
2243  $form->select_produits($task_time->fk_product, 'fk_product', '1', 0, $projectstatic->thirdparty->price_level, 1, 2, '', 0, array(), $projectstatic->thirdparty->id, 'None', 0, 'maxwidth500');
2244  } elseif (!empty($task_time->fk_product)) {
2245  $product = new Product($db);
2246  $resultFetch = $product->fetch($task_time->fk_product);
2247  if ($resultFetch < 0) {
2248  setEventMessages($product->error, $product->errors, 'errors');
2249  } else {
2250  print $product->getNomUrl(1);
2251  }
2252  }
2253  print '</td>';
2254  }
2255 
2256  // Value spent
2257  if (!empty($arrayfields['value']['checked'])) {
2258  $langs->load("salaries");
2259  $value = price2num($task_time->thm * $task_time->task_duration / 3600, 'MT', 1);
2260 
2261  print '<td class="nowraponall right">';
2262  print '<span class="amount" title="'.$langs->trans("THM").': '.price($task_time->thm).'">';
2263  print price($value, 1, $langs, 1, -1, -1, $conf->currency);
2264  print '</span>';
2265  print '</td>';
2266  if (!$i) {
2267  $totalarray['nbfield']++;
2268  }
2269  if (!$i) {
2270  $totalarray['pos'][$totalarray['nbfield']] = 'value';
2271  }
2272  if (empty($totalarray['val']['value'])) {
2273  $totalarray['val']['value'] = $value;
2274  } else {
2275  $totalarray['val']['value'] += $value;
2276  }
2277  if (!$i) {
2278  $totalarray['totalvaluefield'] = $totalarray['nbfield'];
2279  }
2280  if (empty($totalarray['totalvalue'])) {
2281  $totalarray['totalvalue'] = $value;
2282  } else {
2283  $totalarray['totalvalue'] += $value;
2284  }
2285  }
2286 
2287  // Invoiced
2288  if (!empty($arrayfields['valuebilled']['checked'])) {
2289  print '<td class="center">'; // invoice_id and invoice_line_id
2290  if (empty($conf->global->PROJECT_HIDE_TASKS) && !empty($conf->global->PROJECT_BILL_TIME_SPENT)) {
2291  if ($projectstatic->usage_bill_time) {
2292  if ($task_time->invoice_id) {
2293  $result = $tmpinvoice->fetch($task_time->invoice_id);
2294  if ($result > 0) {
2295  print $tmpinvoice->getNomUrl(1);
2296  }
2297  } else {
2298  print $langs->trans("No");
2299  }
2300  } else {
2301  print '<span class="opacitymedium">'.$langs->trans("NA").'</span>';
2302  }
2303  }
2304  print '</td>';
2305  if (!$i) {
2306  $totalarray['nbfield']++;
2307  }
2308  }
2309 
2310  /*
2311  // Extra fields
2312  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
2313  */
2314 
2315  // Fields from hook
2316  $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$task_time, 'i'=>$i, 'totalarray'=>&$totalarray);
2317  $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook
2318  print $hookmanager->resPrint;
2319 
2320  // Action column
2321  print '<td class="center nowraponall">';
2322  if (($action == 'editline' || $action == 'splitline') && GETPOST('lineid', 'int') == $task_time->rowid) {
2323  print '<input type="hidden" name="lineid" value="'.GETPOST('lineid', 'int').'">';
2324  print '<input type="submit" class="button buttongen margintoponlyshort marginbottomonlyshort button-save" name="save" value="'.$langs->trans("Save").'">';
2325  print ' ';
2326  print '<input type="submit" class="button buttongen margintoponlyshort marginbottomonlyshort button-cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
2327  } elseif ($user->hasRight('projet', 'time') || $user->hasRight('projet', 'all', 'creer')) { // Read project and enter time consumed on assigned tasks
2328  if (in_array($task_time->fk_user, $childids) || $user->hasRight('projet', 'all', 'creer')) {
2329  if (getDolGlobalString('MAIN_FEATURES_LEVEL') >= 2) {
2330  print '&nbsp;';
2331  print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=splitline&token='.newToken().'&lineid='.$task_time->rowid.$param.((empty($id) || $tab == 'timespent') ? '&tab=timespent' : '').'">';
2332  print img_split('', 'class="pictofixedwidth"');
2333  print '</a>';
2334  }
2335 
2336  print '<a class="reposition editfielda" href="'.$_SERVER["PHP_SELF"].'?id='.$task_time->fk_task.'&action=editline&token='.newToken().'&lineid='.$task_time->rowid.$param.((empty($id) || $tab == 'timespent') ? '&tab=timespent' : '').'">';
2337  print img_edit('default', 0, 'class="pictofixedwidth paddingleft"');
2338  print '</a>';
2339 
2340  print '<a class="reposition paddingleft" href="'.$_SERVER["PHP_SELF"].'?id='.$task_time->fk_task.'&action=deleteline&token='.newToken().'&lineid='.$task_time->rowid.$param.((empty($id) || $tab == 'timespent') ? '&tab=timespent' : '').'">';
2341  print img_delete('default', 'class="pictodelete paddingleft"');
2342  print '</a>';
2343 
2344  if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
2345  $selected = 0;
2346  if (in_array($task_time->rowid, $arrayofselected)) {
2347  $selected = 1;
2348  }
2349  print '&nbsp;';
2350  print '<input id="cb'.$task_time->rowid.'" class="flat checkforselect marginleftonly" type="checkbox" name="toselect[]" value="'.$task_time->rowid.'"'.($selected ? ' checked="checked"' : '').'>';
2351  }
2352  }
2353  }
2354  print '</td>';
2355  if (!$i) {
2356  $totalarray['nbfield']++;
2357  }
2358 
2359  print "</tr>\n";
2360 
2361 
2362  // Add line to split
2363 
2364  if ($action == 'splitline' && GETPOST('lineid', 'int') == $task_time->rowid) {
2365  print '<tr class="oddeven">';
2366 
2367  // Date
2368  if (!empty($arrayfields['t.task_date']['checked'])) {
2369  print '<td class="nowrap">';
2370  if ($action == 'splitline' && GETPOST('lineid', 'int') == $task_time->rowid) {
2371  if (empty($task_time->task_date_withhour)) {
2372  print $form->selectDate(($date2 ? $date2 : $date1), 'timeline', 3, 3, 2, "timespent_date", 1, 0);
2373  } else {
2374  print $form->selectDate(($date2 ? $date2 : $date1), 'timeline', 1, 1, 2, "timespent_date", 1, 0);
2375  }
2376  } else {
2377  print dol_print_date(($date2 ? $date2 : $date1), ($task_time->task_date_withhour ? 'dayhour' : 'day'));
2378  }
2379  print '</td>';
2380  }
2381 
2382  // Project ref
2383  if (!empty($allprojectforuser)) {
2384  if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task
2385  print '<td class="nowrap">';
2386  print '</td>';
2387  }
2388  }
2389 
2390  // Task ref
2391  if (!empty($arrayfields['t.task_ref']['checked'])) {
2392  if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task
2393  print '<td class="nowrap">';
2394  $tasktmp->id = $task_time->fk_task;
2395  $tasktmp->ref = $task_time->ref;
2396  $tasktmp->label = $task_time->label;
2397  print $tasktmp->getNomUrl(1, 'withproject', 'time');
2398  print '</td>';
2399  }
2400  }
2401 
2402  // Task label
2403  if (!empty($arrayfields['t.task_label']['checked'])) {
2404  if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task
2405  print '<td class="tdoverflowmax300" title="'.dol_escape_htmltag($task_time->label).'">';
2406  print dol_escape_htmltag($task_time->label);
2407  print '</td>';
2408  }
2409  }
2410 
2411  // User
2412  if (!empty($arrayfields['author']['checked'])) {
2413  print '<td>';
2414  if ($action == 'splitline' && GETPOST('lineid', 'int') == $task_time->rowid) {
2415  if (empty($object->id)) {
2416  $object->fetch($id);
2417  }
2418  $contactsoftask = $object->getListContactId('internal');
2419  if (!in_array($task_time->fk_user, $contactsoftask)) {
2420  $contactsoftask[] = $task_time->fk_user;
2421  }
2422  if (count($contactsoftask) > 0) {
2423  print img_object('', 'user', 'class="hideonsmartphone"');
2424  print $form->select_dolusers($task_time->fk_user, 'userid_line', 0, '', 0, '', $contactsoftask);
2425  } else {
2426  print img_error($langs->trans('FirstAddRessourceToAllocateTime')).$langs->trans('FirstAddRessourceToAllocateTime');
2427  }
2428  } else {
2429  $userstatic->id = $task_time->fk_user;
2430  $userstatic->lastname = $task_time->lastname;
2431  $userstatic->firstname = $task_time->firstname;
2432  $userstatic->photo = $task_time->photo;
2433  $userstatic->statut = $task_time->user_status;
2434  print $userstatic->getNomUrl(-1);
2435  }
2436  print '</td>';
2437  }
2438 
2439  // Note
2440  if (!empty($arrayfields['t.note']['checked'])) {
2441  print '<td class="tdoverflowmax300">';
2442  if ($action == 'splitline' && GETPOST('lineid', 'int') == $task_time->rowid) {
2443  print '<textarea name="timespent_note_line" width="95%" rows="'.ROWS_1.'">'.dol_escape_htmltag($task_time->note, 0, 1).'</textarea>';
2444  } else {
2445  print dol_nl2br($task_time->note);
2446  }
2447  print '</td>';
2448  } elseif ($action == 'splitline' && GETPOST('lineid', 'int') == $task_time->rowid) {
2449  print '<input type="hidden" name="timespent_note_line" rows="'.ROWS_1.'" value="'.dol_escape_htmltag($task_time->note, 0, 1).'">';
2450  }
2451 
2452  // Time spent
2453  if (!empty($arrayfields['t.task_duration']['checked'])) {
2454  print '<td class="right">';
2455  if ($action == 'splitline' && GETPOST('lineid', 'int') == $task_time->rowid) {
2456  print '<input type="hidden" name="old_duration" value="'.$task_time->task_duration.'">';
2457  print $form->select_duration('new_duration', $task_time->task_duration, 0, 'text');
2458  } else {
2459  print convertSecondToTime($task_time->task_duration, 'allhourmin');
2460  }
2461  print '</td>';
2462  }
2463 
2464  // Value spent
2465  if (!empty($arrayfields['value']['checked'])) {
2466  print '<td class="right">';
2467  print '<span class="amount">';
2468  $value = price2num($task_time->thm * $task_time->task_duration / 3600, 'MT', 1);
2469  print price($value, 1, $langs, 1, -1, -1, $conf->currency);
2470  print '</span>';
2471  print '</td>';
2472  }
2473 
2474  // Value billed
2475  if (!empty($arrayfields['valuebilled']['checked'])) {
2476  print '<td class="right">';
2477  $valuebilled = price2num($task_time->total_ht, '', 1);
2478  if (isset($task_time->total_ht)) {
2479  print price($valuebilled, 1, $langs, 1, -1, -1, $conf->currency);
2480  }
2481  print '</td>';
2482  }
2483 
2484  /*
2485  // Extra fields
2486  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
2487  */
2488 
2489  // Fields from hook
2490  $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$task_time, 'mode' => 'split1');
2491  $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook
2492  print $hookmanager->resPrint;
2493 
2494  // Action column
2495  print '<td class="center nowraponall">';
2496  print '</td>';
2497 
2498  print "</tr>\n";
2499 
2500 
2501  // Line for second dispatching
2502 
2503  print '<tr class="oddeven">';
2504 
2505  // Date
2506  if (!empty($arrayfields['t.task_date']['checked'])) {
2507  print '<td class="nowrap">';
2508  if ($action == 'splitline' && GETPOST('lineid', 'int') == $task_time->rowid) {
2509  if (empty($task_time->task_date_withhour)) {
2510  print $form->selectDate(($date2 ? $date2 : $date1), 'timeline_2', 3, 3, 2, "timespent_date", 1, 0);
2511  } else {
2512  print $form->selectDate(($date2 ? $date2 : $date1), 'timeline_2', 1, 1, 2, "timespent_date", 1, 0);
2513  }
2514  } else {
2515  print dol_print_date(($date2 ? $date2 : $date1), ($task_time->task_date_withhour ? 'dayhour' : 'day'));
2516  }
2517  print '</td>';
2518  }
2519 
2520  // Project ref
2521  if (!empty($allprojectforuser)) {
2522  if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task
2523  print '<td class="nowrap">';
2524  print '</td>';
2525  }
2526  }
2527 
2528  // Task ref
2529  if (!empty($arrayfields['t.task_ref']['checked'])) {
2530  if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task
2531  print '<td class="nowrap">';
2532  $tasktmp->id = $task_time->fk_task;
2533  $tasktmp->ref = $task_time->ref;
2534  $tasktmp->label = $task_time->label;
2535  print $tasktmp->getNomUrl(1, 'withproject', 'time');
2536  print '</td>';
2537  }
2538  }
2539 
2540  // Task label
2541  if (!empty($arrayfields['t.task_label']['checked'])) {
2542  if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task
2543  print '<td class="nowrap">';
2544  print $task_time->label;
2545  print '</td>';
2546  }
2547  }
2548 
2549  // User
2550  if (!empty($arrayfields['author']['checked'])) {
2551  print '<td>';
2552  if ($action == 'splitline' && GETPOST('lineid', 'int') == $task_time->rowid) {
2553  if (empty($object->id)) {
2554  $object->fetch($id);
2555  }
2556  $contactsoftask = $object->getListContactId('internal');
2557  if (!in_array($task_time->fk_user, $contactsoftask)) {
2558  $contactsoftask[] = $task_time->fk_user;
2559  }
2560  if (count($contactsoftask) > 0) {
2561  print img_object('', 'user', 'class="hideonsmartphone"');
2562  print $form->select_dolusers($task_time->fk_user, 'userid_line_2', 0, '', 0, '', $contactsoftask);
2563  } else {
2564  print img_error($langs->trans('FirstAddRessourceToAllocateTime')).$langs->trans('FirstAddRessourceToAllocateTime');
2565  }
2566  } else {
2567  $userstatic->id = $task_time->fk_user;
2568  $userstatic->lastname = $task_time->lastname;
2569  $userstatic->firstname = $task_time->firstname;
2570  $userstatic->photo = $task_time->photo;
2571  $userstatic->statut = $task_time->user_status;
2572  print $userstatic->getNomUrl(-1);
2573  }
2574  print '</td>';
2575  }
2576 
2577  // Note
2578  if (!empty($arrayfields['t.note']['checked'])) {
2579  print '<td class="small tdoverflowmax300"">';
2580  if ($action == 'splitline' && GETPOST('lineid', 'int') == $task_time->rowid) {
2581  print '<textarea name="timespent_note_line_2" width="95%" rows="'.ROWS_1.'">'.dol_escape_htmltag($task_time->note, 0, 1).'</textarea>';
2582  } else {
2583  print dol_nl2br($task_time->note);
2584  }
2585  print '</td>';
2586  } elseif ($action == 'splitline' && GETPOST('lineid', 'int') == $task_time->rowid) {
2587  print '<input type="hidden" name="timespent_note_line_2" value="'.dol_escape_htmltag($task_time->note, 0, 1).'">';
2588  }
2589 
2590  // Time spent
2591  if (!empty($arrayfields['t.task_duration']['checked'])) {
2592  print '<td class="right">';
2593  if ($action == 'splitline' && GETPOST('lineid', 'int') == $task_time->rowid) {
2594  print '<input type="hidden" name="old_duration_2" value="0">';
2595  print $form->select_duration('new_duration_2', 0, 0, 'text');
2596  } else {
2597  print convertSecondToTime($task_time->task_duration, 'allhourmin');
2598  }
2599  print '</td>';
2600  }
2601 
2602  // Value spent
2603  if (!empty($arrayfields['value']['checked'])) {
2604  print '<td class="right">';
2605  print '<span class="amount">';
2606  $value = 0;
2607  print price($value, 1, $langs, 1, -1, -1, $conf->currency);
2608  print '</span>';
2609  print '</td>';
2610  }
2611 
2612  // Value billed
2613  if (!empty($arrayfields['valuebilled']['checked'])) {
2614  print '<td class="right">';
2615  $valuebilled = price2num($task_time->total_ht, '', 1);
2616  if (isset($task_time->total_ht)) {
2617  print '<span class="amount">';
2618  print price($valuebilled, 1, $langs, 1, -1, -1, $conf->currency);
2619  print '</span>';
2620  }
2621  print '</td>';
2622  }
2623 
2624  /*
2625  // Extra fields
2626  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php';
2627  */
2628 
2629  // Fields from hook
2630  $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$task_time, 'mode' => 'split2');
2631  $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook
2632  print $hookmanager->resPrint;
2633 
2634  // Action column
2635  print '<td class="center nowraponall">';
2636  print '</td>';
2637 
2638  print "</tr>\n";
2639  }
2640 
2641  $i++;
2642  }
2643 
2644  // Show total line
2645  //include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
2646  if (isset($totalarray['totaldurationfield']) || isset($totalarray['totalvaluefield'])) {
2647  print '<tr class="liste_total">';
2648  $i = 0;
2649  while ($i < $totalarray['nbfield']) {
2650  $i++;
2651  if ($i == 1) {
2652  if ($num < $limit && empty($offset)) {
2653  print '<td class="left">'.$langs->trans("Total").'</td>';
2654  } else {
2655  print '<td class="left">'.$langs->trans("Totalforthispage").'</td>';
2656  }
2657  } elseif ($totalarray['totaldurationfield'] == $i) {
2658  print '<td class="right">'.convertSecondToTime($totalarray['totalduration'], 'allhourmin').'</td>';
2659  } elseif ($totalarray['totalvaluefield'] == $i) {
2660  print '<td class="right">'.price($totalarray['totalvalue']).'</td>';
2661  //} elseif ($totalarray['totalvaluebilledfield'] == $i) { print '<td class="center">'.price($totalarray['totalvaluebilled']).'</td>';
2662  } else {
2663  print '<td></td>';
2664  }
2665  }
2666  print '</tr>';
2667  }
2668 
2669  if (!count($tasks)) {
2670  $totalnboffields = 1;
2671  foreach ($arrayfields as $value) {
2672  if ($value['checked']) {
2673  $totalnboffields++;
2674  }
2675  }
2676  print '<tr class="oddeven"><td colspan="'.$totalnboffields.'">';
2677  print '<span class="opacitymedium">'.$langs->trans("None").'</span>';
2678  print '</td></tr>';
2679  }
2680 
2681  $parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql);
2682  $reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters); // Note that $action and $object may have been modified by hook
2683  print $hookmanager->resPrint;
2684 
2685  print "</table>";
2686  print '</div>';
2687  print "</form>";
2688  }
2689 }
2690 
2691 // End of page
2692 llxFooter();
2693 $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 invoices.
Class to manage interventions.
Class to manage generation of HTML components Only common components must be here.
Class to manage generation of HTML components for contract module.
Classe permettant la generation de composants html autre Only common components are here.
Class to manage building of HTML components.
Class to manage products or services.
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:45
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
dolSqlDateFilter($datefield, $day_date, $month_date, $year_date, $excludefirstand=0, $gm=false)
Generate a SQL string to make a filter into a range (for second of date until last second of date).
Definition: date.lib.php:358
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_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='rowid', $fieldref='ref', $morehtmlref='', $moreparam='', $nodbprefix=0, $morehtmlleft='', $morehtmlstatus='', $onlybanner=0, $morehtmlright='')
Show tab footer of a card.
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...
get_default_localtax($thirdparty_seller, $thirdparty_buyer, $local, $idprod=0)
Function that return localtax of a product line (according to seller, buyer and product vat rate) Si ...
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='')
Show tabs of a record.
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
GETPOSTINT($paramname, $method=0)
Return value of a param into GET or POST supervariable.
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.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
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.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_get_fiche_end($notab=0)
Return tab footer of a card.
dol_nl2br($stringtoencode, $nl2brmode=0, $forxml=false)
Replace CRLF in string with a HTML BR tag.
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.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
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...
newToken()
Return the value of token currently saved into session with name 'newtoken'.
print_liste_field_titre($name, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
img_split($titlealt='default', $other='class="pictosplit"')
Show split logo.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
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.
img_error($titlealt='default')
Show error logo.
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.
img_edit($titlealt='default', $float=0, $other='')
Show logo editer/modifier fiche.
get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that return vat rate of a product line (according to seller, buyer and product vat rate) VAT...
$formconfirm
if ($action == 'delbookkeepingyear') {
$nbtotalofrecords
Count total nb of records.
Definition: list.php:329
task_prepare_head($object)
Prepare array with list of tabs.
project_prepare_head(Project $project, $moreparam='')
Prepare array with list of tabs.
Definition: project.lib.php:38
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.