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