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