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