dolibarr  17.0.4
perday.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2016 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005-2010 Regis Houssin <regis.houssin@inodbox.com>
5  * Copyright (C) 2010 François Legastelois <flegastelois@teclib.com>
6  * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
28 require "../../main.inc.php";
29 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
30 require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
31 require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
32 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
33 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
34 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
35 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
36 require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php';
37 
38 // Load translation files required by the page
39 $langs->loadLangs(array('projects', 'users', 'companies'));
40 
41 $action = GETPOST('action', 'aZ09');
42 $mode = GETPOST("mode", 'alpha');
43 $id = GETPOST('id', 'int');
44 $taskid = GETPOST('taskid', 'int');
45 
46 $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'perdaycard';
47 
48 $mine = 0;
49 if ($mode == 'mine') {
50  $mine = 1;
51 }
52 
53 $projectid = GETPOSTISSET("id") ? GETPOST("id", "int", 1) : GETPOST("projectid", "int");
54 
55 $hookmanager->initHooks(array('timesheetperdaycard'));
56 
57 // Security check
58 $socid = 0;
59 // For external user, no check is done on company because readability is managed by public status of project and assignement.
60 //if ($user->socid > 0) $socid=$user->socid;
61 $result = restrictedArea($user, 'projet', $projectid);
62 
63 $now = dol_now();
64 
65 $year = GETPOST('reyear', 'int') ?GETPOST('reyear', 'int') : (GETPOST("year", "int") ?GETPOST("year", "int") : (GETPOST("addtimeyear", "int") ?GETPOST("addtimeyear", "int") : date("Y")));
66 $month = GETPOST('remonth', 'int') ?GETPOST('remonth', 'int') : (GETPOST("month", "int") ?GETPOST("month", "int") : (GETPOST("addtimemonth", "int") ?GETPOST("addtimemonth", "int") : date("m")));
67 $day = GETPOST('reday', 'int') ?GETPOST('reday', 'int') : (GETPOST("day", "int") ?GETPOST("day", "int") : (GETPOST("addtimeday", "int") ?GETPOST("addtimeday", "int") : date("d")));
68 $week = GETPOST("week", "int") ?GETPOST("week", "int") : date("W");
69 
70 $day = (int) $day;
71 
72 //$search_categ = GETPOST("search_categ", 'alpha');
73 $search_usertoprocessid = GETPOST('search_usertoprocessid', 'int');
74 $search_task_ref = GETPOST('search_task_ref', 'alpha');
75 $search_task_label = GETPOST('search_task_label', 'alpha');
76 $search_project_ref = GETPOST('search_project_ref', 'alpha');
77 $search_thirdparty = GETPOST('search_thirdparty', 'alpha');
78 $search_declared_progress = GETPOST('search_declared_progress', 'alpha');
79 
80 $sortfield = GETPOST('sortfield', 'aZ09comma');
81 $sortorder = GETPOST('sortorder', 'aZ09comma');
82 
83 $monthofday = GETPOST('addtimemonth');
84 $dayofday = GETPOST('addtimeday');
85 $yearofday = GETPOST('addtimeyear');
86 
87 //var_dump(GETPOST('remonth'));
88 //var_dump(GETPOST('button_search_x'));
89 //var_dump(GETPOST('button_addtime'));
90 
91 $daytoparse = $now;
92 if ($year && $month && $day) {
93  $daytoparse = dol_mktime(0, 0, 0, $month, $day, $year); // this are value submited after submit of action 'submitdateselect'
94 } elseif ($yearofday && $monthofday && $dayofday) {
95  $daytoparse = dol_mktime(0, 0, 0, $monthofday, $dayofday, $yearofday); // xxxofday is value of day after submit action 'addtime'
96 }
97 
98 $daytoparsegmt = dol_now('gmt');
99 if ($yearofday && $monthofday && $dayofday) $daytoparsegmt = dol_mktime(0, 0, 0, $monthofday, $dayofday, $yearofday, 'gmt'); // xxxofday is value of day after submit action 'addtime'
100 elseif ($year && $month && $day) $daytoparsegmt = dol_mktime(0, 0, 0, $month, $day, $year, 'gmt'); // this are value submited after submit of action 'submitdateselect'
101 
102 if (empty($search_usertoprocessid) || $search_usertoprocessid == $user->id) {
103  $usertoprocess = $user;
104  $search_usertoprocessid = $usertoprocess->id;
105 } elseif ($search_usertoprocessid > 0) {
106  $usertoprocess = new User($db);
107  $usertoprocess->fetch($search_usertoprocessid);
108  $search_usertoprocessid = $usertoprocess->id;
109 } else {
110  $usertoprocess = new User($db);
111 }
112 
113 $object = new Task($db);
114 $project = new Project($db);
115 
116 // Extra fields
117 $extrafields = new ExtraFields($db);
118 
119 // fetch optionals attributes and labels
120 $extrafields->fetch_name_optionals_label($object->table_element);
121 
122 // Definition of fields for list
123 $arrayfields = array();
124 $arrayfields['t.planned_workload'] = array('label'=>'PlannedWorkload', 'checked'=>1, 'enabled'=>1, 'position'=>0);
125 $arrayfields['t.progress'] = array('label'=>'ProgressDeclared', 'checked'=>1, 'enabled'=>1, 'position'=>0);
126 $arrayfields['timeconsumed'] = array('label'=>'TimeConsumed', 'checked'=>1, 'enabled'=>1, 'position'=>15);
127 /*$arrayfields=array(
128  // Project
129  'p.opp_amount'=>array('label'=>$langs->trans("OpportunityAmountShort"), 'checked'=>0, 'enabled'=>($conf->global->PROJECT_USE_OPPORTUNITIES?1:0), 'position'=>103),
130  'p.fk_opp_status'=>array('label'=>$langs->trans("OpportunityStatusShort"), 'checked'=>0, 'enabled'=>($conf->global->PROJECT_USE_OPPORTUNITIES?1:0), 'position'=>104),
131  'p.opp_percent'=>array('label'=>$langs->trans("OpportunityProbabilityShort"), 'checked'=>0, 'enabled'=>($conf->global->PROJECT_USE_OPPORTUNITIES?1:0), 'position'=>105),
132  'p.budget_amount'=>array('label'=>$langs->trans("Budget"), 'checked'=>0, 'position'=>110),
133  'p.usage_bill_time'=>array('label'=>$langs->trans("BillTimeShort"), 'checked'=>0, 'position'=>115),
134  );
135  */
136 // Extra fields
137 if (!empty($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0) {
138  foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
139  if (!empty($extrafields->attributes[$object->table_element]['list'][$key])) {
140  $arrayfields["efpt.".$key] = array('label'=>$extrafields->attributes[$object->table_element]['label'][$key], 'checked'=>(($extrafields->attributes[$object->table_element]['list'][$key] < 0) ? 0 : 1), 'position'=>$extrafields->attributes[$object->table_element]['pos'][$key], 'enabled'=>(abs((int) $extrafields->attributes[$object->table_element]['list'][$key]) != 3 && $extrafields->attributes[$object->table_element]['perms'][$key]));
141  }
142  }
143 }
144 $arrayfields = dol_sort_array($arrayfields, 'position');
145 
146 
147 $search_array_options_project = $extrafields->getOptionalsFromPost($project->table_element, '', 'search_');
148 $search_array_options_task = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_task_');
149 
150 
151 /*
152  * Actions
153  */
154 
155 $parameters = array('id' => $id, 'taskid' => $taskid, 'projectid' => $projectid);
156 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
157 if ($reshook < 0) {
158  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
159 }
160 // Purge criteria
161 if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
162  $action = '';
163  //$search_categ = '';
164  $search_usertoprocessid = $user->id;
165  $search_task_ref = '';
166  $search_task_label = '';
167  $search_project_ref = '';
168  $search_thirdparty = '';
169  $search_declared_progress = '';
170 
171  $search_array_options_project = array();
172  $search_array_options_task = array();
173 
174  // We redefine $usertoprocess
175  $usertoprocess = $user;
176 }
177 if (GETPOST("button_search_x", 'alpha') || GETPOST("button_search.x", 'alpha') || GETPOST("button_search", 'alpha')) {
178  $action = '';
179 }
180 
181 if (GETPOST('submitdateselect')) {
182  if (GETPOST('remonth', 'int') && GETPOST('reday', 'int') && GETPOST('reyear', 'int')) {
183  $daytoparse = dol_mktime(0, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
184  }
185 
186  $action = '';
187 }
188 
189 include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
190 
191 if ($action == 'addtime' && $user->rights->projet->lire && GETPOST('assigntask') && GETPOST('formfilteraction') != 'listafterchangingselectedfields') {
192  $action = 'assigntask';
193 
194  if ($taskid > 0) {
195  $result = $object->fetch($taskid, $ref);
196  if ($result < 0) {
197  $error++;
198  }
199  } else {
200  setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Task")), '', 'errors');
201  $error++;
202  }
203  if (!GETPOST('type')) {
204  setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), '', 'errors');
205  $error++;
206  }
207  if (!$error) {
208  $idfortaskuser = $usertoprocess->id;
209  $result = $object->add_contact($idfortaskuser, GETPOST("type"), 'internal');
210 
211  if ($result >= 0 || $result == -2) { // Contact add ok or already contact of task
212  // Test if we are already contact of the project (should be rare but sometimes we can add as task contact without being contact of project, like when admin user has been removed from contact of project)
213  $sql = 'SELECT ec.rowid FROM '.MAIN_DB_PREFIX.'element_contact as ec, '.MAIN_DB_PREFIX.'c_type_contact as tc WHERE tc.rowid = ec.fk_c_type_contact';
214  $sql .= ' AND ec.fk_socpeople = '.((int) $idfortaskuser)." AND ec.element_id = ".((int) $object->fk_project)." AND tc.element = 'project' AND source = 'internal'";
215  $resql = $db->query($sql);
216  if ($resql) {
217  $obj = $db->fetch_object($resql);
218  if (!$obj) { // User is not already linked to project, so we will create link to first type
219  $project = new Project($db);
220  $project->fetch($object->fk_project);
221  // Get type
222  $listofprojcontact = $project->liste_type_contact('internal');
223 
224  if (count($listofprojcontact)) {
225  $tmparray = array_keys($listofprojcontact);
226  $typeforprojectcontact = reset($tmparray);
227  $result = $project->add_contact($idfortaskuser, $typeforprojectcontact, 'internal');
228  }
229  }
230  } else {
231  dol_print_error($db);
232  }
233  }
234  }
235 
236  if ($result < 0) {
237  $error++;
238  if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
239  $langs->load("errors");
240  setEventMessages($langs->trans("ErrorTaskAlreadyAssigned"), null, 'warnings');
241  } else {
242  setEventMessages($object->error, $object->errors, 'errors');
243  }
244  }
245 
246  if (!$error) {
247  setEventMessages("TaskAssignedToEnterTime", null);
248  $taskid = 0;
249  }
250 
251  $action = '';
252 }
253 
254 if ($action == 'addtime' && $user->rights->projet->lire && GETPOST('formfilteraction') != 'listafterchangingselectedfields') {
255  $timespent_duration = array();
256 
257  if (is_array($_POST)) {
258  foreach ($_POST as $key => $time) {
259  if (intval($time) > 0) {
260  $matches = array();
261  // Hours or minutes of duration
262  if (preg_match("/([0-9]+)duration(hour|min)/", $key, $matches)) {
263  $id = $matches[1];
264  if ($id > 0) {
265  // We store HOURS in seconds
266  if ($matches[2] == 'hour') {
267  $timespent_duration[$id] += $time * 60 * 60;
268  }
269 
270  // We store MINUTES in seconds
271  if ($matches[2] == 'min') {
272  $timespent_duration[$id] += $time * 60;
273  }
274  }
275  }
276  }
277  }
278  }
279 
280  if (count($timespent_duration) > 0) {
281  foreach ($timespent_duration as $key => $val) {
282  $object->fetch($key);
283  $taskid = $object->id;
284 
285  if (GETPOSTISSET($taskid.'progress')) {
286  $object->progress = GETPOST($taskid.'progress', 'int');
287  } else {
288  unset($object->progress);
289  }
290 
291  $object->timespent_duration = $val;
292  $object->timespent_fk_user = $usertoprocess->id;
293  $object->timespent_note = GETPOST($key.'note');
294  if (GETPOST($key."hour", 'int') != '' && GETPOST($key."hour", 'int') >= 0) { // If hour was entered
295  $object->timespent_datehour = dol_mktime(GETPOST($key."hour", 'int'), GETPOST($key."min", 'int'), 0, $monthofday, $dayofday, $yearofday);
296  $object->timespent_withhour = 1;
297  } else {
298  $object->timespent_datehour = dol_mktime(12, 0, 0, $monthofday, $dayofday, $yearofday);
299  }
300  $object->timespent_date = $object->timespent_datehour;
301 
302  if ($object->timespent_date > 0) {
303  $result = $object->addTimeSpent($user);
304  } else {
305  setEventMessages("ErrorBadDate", null, 'errors');
306  $error++;
307  break;
308  }
309 
310  if ($result < 0) {
311  setEventMessages($object->error, $object->errors, 'errors');
312  $error++;
313  break;
314  }
315  }
316 
317  if (!$error) {
318  setEventMessages($langs->trans("RecordSaved"), null, 'mesgs');
319 
320  // Redirect to avoid submit twice on back
321  header('Location: '.$_SERVER["PHP_SELF"].'?'.($projectid ? 'id='.$projectid : '').($search_usertoprocessid ? '&search_usertoprocessid='.urlencode($search_usertoprocessid) : '').($mode ? '&mode='.$mode : '').'&year='.$yearofday.'&month='.$monthofday.'&day='.$dayofday);
322  exit;
323  }
324  } else {
325  setEventMessages($langs->trans("ErrorTimeSpentIsEmpty"), null, 'errors');
326  }
327 }
328 
329 
330 
331 /*
332  * View
333  */
334 
335 $form = new Form($db);
336 $formother = new FormOther($db);
337 $formcompany = new FormCompany($db);
338 $formproject = new FormProjets($db);
339 $projectstatic = new Project($db);
340 $project = new Project($db);
341 $taskstatic = new Task($db);
342 $thirdpartystatic = new Societe($db);
343 $holiday = new Holiday($db);
344 
345 $prev = dol_getdate($daytoparse - (24 * 3600));
346 $prev_year = $prev['year'];
347 $prev_month = $prev['mon'];
348 $prev_day = $prev['mday'];
349 
350 $next = dol_getdate($daytoparse + (24 * 3600));
351 $next_year = $next['year'];
352 $next_month = $next['mon'];
353 $next_day = $next['mday'];
354 
355 $title = $langs->trans("TimeSpent");
356 
357 $projectsListId = $projectstatic->getProjectsAuthorizedForUser($usertoprocess, (empty($usertoprocess->id) ? 2 : 0), 1); // Return all project i have permission on (assigned to me+public). I want my tasks and some of my task may be on a public projet that is not my project
358 
359 if ($id) {
360  $project->fetch($id);
361  $project->fetch_thirdparty();
362 }
363 
364 $onlyopenedproject = 1; // or -1
365 $morewherefilter = '';
366 
367 if ($search_project_ref) {
368  $morewherefilter .= natural_search(array("p.ref", "p.title"), $search_project_ref);
369 }
370 if ($search_task_ref) {
371  $morewherefilter .= natural_search("t.ref", $search_task_ref);
372 }
373 if ($search_task_label) {
374  $morewherefilter .= natural_search(array("t.ref", "t.label"), $search_task_label);
375 }
376 if ($search_thirdparty) {
377  $morewherefilter .= natural_search("s.nom", $search_thirdparty);
378 }
379 if ($search_declared_progress) {
380  $morewherefilter .= natural_search("t.progress", $search_declared_progress, 1);
381 }
382 
383 $sql = &$morewherefilter;
384 
385 /*$search_array_options = $search_array_options_project;
386 $extrafieldsobjectprefix='efp.';
387 $search_options_pattern='search_options_';
388 $extrafieldsobjectkey='projet';
389 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
390 */
391 $search_array_options = $search_array_options_task;
392 $extrafieldsobjectprefix = 'efpt.';
393 $search_options_pattern = 'search_task_options_';
394 $extrafieldsobjectkey = 'projet_task';
395 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
396 
397 $tasksarray = $taskstatic->getTasksArray(0, 0, ($project->id ? $project->id : 0), $socid, 0, $search_project_ref, $onlyopenedproject, $morewherefilter, ($search_usertoprocessid ? $search_usertoprocessid : 0), 0, $extrafields); // We want to see all task of opened project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later.
398 if ($morewherefilter) { // Get all task without any filter, so we can show total of time spent for not visible tasks
399  $tasksarraywithoutfilter = $taskstatic->getTasksArray(0, 0, ($project->id ? $project->id : 0), $socid, 0, '', $onlyopenedproject, '', ($search_usertoprocessid ? $search_usertoprocessid : 0)); // We want to see all task of opened project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later.
400 }
401 $projectsrole = $taskstatic->getUserRolesForProjectsOrTasks($usertoprocess, 0, ($project->id ? $project->id : 0), 0, $onlyopenedproject);
402 $tasksrole = $taskstatic->getUserRolesForProjectsOrTasks(0, $usertoprocess, ($project->id ? $project->id : 0), 0, $onlyopenedproject);
403 //var_dump($usertoprocess);
404 //var_dump($projectsrole);
405 //var_dump($taskrole);
406 
407 llxHeader("", $title, "", '', '', '', array('/core/js/timesheet.js'));
408 
409 //print_barre_liste($title, $page, $_SERVER["PHP_SELF"], "", $sortfield, $sortorder, "", $num, '', 'project');
410 
411 $param = '';
412 $param .= ($mode ? '&mode='.urlencode($mode) : '');
413 $param .= ($search_project_ref ? '&search_project_ref='.urlencode($search_project_ref) : '');
414 $param .= ($search_usertoprocessid > 0 ? '&search_usertoprocessid='.urlencode($search_usertoprocessid) : '');
415 $param .= ($search_thirdparty ? '&search_thirdparty='.urlencode($search_thirdparty) : '');
416 $param .= ($search_task_ref ? '&search_task_ref='.urlencode($search_task_ref) : '');
417 $param .= ($search_task_label ? '&search_task_label='.urlencode($search_task_label) : '');
418 
419 /*
420 $search_array_options = $search_array_options_project;
421 $search_options_pattern='search_options_';
422 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
423 */
424 
425 $search_array_options = $search_array_options_task;
426 $search_options_pattern = 'search_task_options_';
427 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
428 
429 // Show navigation bar
430 $nav = '<a class="inline-block valignmiddle" href="?year='.$prev_year."&month=".$prev_month."&day=".$prev_day.$param.'">'.img_previous($langs->trans("Previous"))."</a>\n";
431 $nav .= dol_print_date(dol_mktime(0, 0, 0, $month, $day, $year), "%A").' ';
432 $nav .= " <span id=\"month_name\">".dol_print_date(dol_mktime(0, 0, 0, $month, $day, $year), "day")." </span>\n";
433 $nav .= '<a class="inline-block valignmiddle" href="?year='.$next_year."&month=".$next_month."&day=".$next_day.$param.'">'.img_next($langs->trans("Next"))."</a>\n";
434 $nav .= ' '.$form->selectDate(-1, '', 0, 0, 2, "addtime", 1, 1).' ';
435 $nav .= ' <button type="submit" name="button_search_x" value="x" class="bordertransp nobordertransp button_search"><span class="fa fa-search"></span></button>';
436 
437 $picto = 'clock';
438 
439 print '<form name="addtime" method="POST" action="'.$_SERVER["PHP_SELF"].($project->id > 0 ? '?id='.$project->id : '').'">';
440 print '<input type="hidden" name="token" value="'.newToken().'">';
441 print '<input type="hidden" name="action" value="addtime">';
442 print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
443 print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
444 print '<input type="hidden" name="mode" value="'.$mode.'">';
445 $tmp = dol_getdate($daytoparse);
446 print '<input type="hidden" name="addtimeyear" value="'.$tmp['year'].'">';
447 print '<input type="hidden" name="addtimemonth" value="'.$tmp['mon'].'">';
448 print '<input type="hidden" name="addtimeday" value="'.$tmp['mday'].'">';
449 
450 $head = project_timesheet_prepare_head($mode, $usertoprocess);
451 print dol_get_fiche_head($head, 'inputperday', $langs->trans('TimeSpent'), -1, $picto);
452 
453 // Show description of content
454 print '<div class="hideonsmartphone opacitymedium">';
455 if ($mine || ($usertoprocess->id == $user->id)) {
456  print $langs->trans("MyTasksDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'<br>';
457 } else {
458  if (empty($usertoprocess->id) || $usertoprocess->id < 0) {
459  if ($user->rights->projet->all->lire && !$socid) {
460  print $langs->trans("ProjectsDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'<br>';
461  } else {
462  print $langs->trans("ProjectsPublicTaskDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'<br>';
463  }
464  }
465 }
466 if ($mine || ($usertoprocess->id == $user->id)) {
467  print $langs->trans("OnlyYourTaskAreVisible").'<br>';
468 } else {
469  print $langs->trans("AllTaskVisibleButEditIfYouAreAssigned").'<br>';
470 }
471 print '</div>';
472 
473 print dol_get_fiche_end();
474 
475 
476 print '<div class="floatright right'.($conf->dol_optimize_smallscreen ? ' centpercent' : '').'">'.$nav.'</div>'; // We move this before the assign to components so, the default submit button is not the assign to.
477 
478 print '<div class="colorbacktimesheet float valignmiddle">';
479 $titleassigntask = $langs->transnoentities("AssignTaskToMe");
480 if ($usertoprocess->id != $user->id) {
481  $titleassigntask = $langs->transnoentities("AssignTaskToUser", $usertoprocess->getFullName($langs));
482 }
483 print '<div class="taskiddiv inline-block">';
484 print img_picto('', 'projecttask', 'class="pictofixedwidth"');
485 $formproject->selectTasks($socid ? $socid : -1, $taskid, 'taskid', 32, 0, '-- '.$langs->trans("ChooseANotYetAssignedTask").' --', 1, 0, 0, '', '', 'all', $usertoprocess);
486 print '</div>';
487 print ' ';
488 print $formcompany->selectTypeContact($object, '', 'type', 'internal', 'position', 0, 'maxwidth150onsmartphone');
489 print '<input type="submit" class="button valignmiddle smallonsmartphone small" name="assigntask" value="'.dol_escape_htmltag($titleassigntask).'">';
490 print '</div>';
491 
492 print '<div class="clearboth" style="padding-bottom: 20px;"></div>';
493 
494 
495 $moreforfilter = '';
496 
497 // Filter on categories
498 /*if (!empty($conf->categorie->enabled))
499 {
500  require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
501  $moreforfilter.='<div class="divsearchfield">';
502  $moreforfilter.=$langs->trans('ProjectCategories'). ': ';
503  $moreforfilter.=$formother->select_categories('project', $search_categ, 'search_categ', 1, 1, 'maxwidth300');
504  $moreforfilter.='</div>';
505 }*/
506 
507 // If the user can view user other than himself
508 $moreforfilter .= '<div class="divsearchfield">';
509 $moreforfilter .= '<div class="inline-block hideonsmartphone"></div>';
510 $includeonly = 'hierarchyme';
511 if (empty($user->rights->user->user->lire)) {
512  $includeonly = array($user->id);
513 }
514 $moreforfilter .= img_picto($langs->trans('Filter').' '.$langs->trans('User'), 'user', 'class="paddingright pictofixedwidth"').$form->select_dolusers($search_usertoprocessid ? $search_usertoprocessid : $usertoprocess->id, 'search_usertoprocessid', $user->rights->user->user->lire ? 0 : 0, null, 0, $includeonly, null, 0, 0, 0, '', 0, '', 'maxwidth200');
515 $moreforfilter .= '</div>';
516 
517 if (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)) {
518  $moreforfilter .= '<div class="divsearchfield">';
519  $moreforfilter .= '<div class="inline-block"></div>';
520  $moreforfilter .= img_picto($langs->trans('Filter').' '.$langs->trans('Project'), 'project', 'class="paddingright pictofixedwidth"').'<input type="text" name="search_project_ref" class="maxwidth100" value="'.dol_escape_htmltag($search_project_ref).'">';
521  $moreforfilter .= '</div>';
522 
523  $moreforfilter .= '<div class="divsearchfield">';
524  $moreforfilter .= '<div class="inline-block"></div>';
525  $moreforfilter .= img_picto($langs->trans('Filter').' '.$langs->trans('ThirdParty'), 'company', 'class="paddingright pictofixedwidth"').'<input type="text" name="search_thirdparty" class="maxwidth100" value="'.dol_escape_htmltag($search_thirdparty).'">';
526  $moreforfilter .= '</div>';
527 }
528 
529 if (!empty($moreforfilter)) {
530  print '<div class="liste_titre liste_titre_bydiv centpercent">';
531  print $moreforfilter;
532  $parameters = array();
533  $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
534  print $hookmanager->resPrint;
535  print '</div>';
536 }
537 
538 $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
539 $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
540 
541 // This must be after the $selectedfields
542 $addcolspan = 0;
543 if (!empty($arrayfields['t.planned_workload']['checked'])) {
544  $addcolspan++;
545 }
546 if (!empty($arrayfields['t.progress']['checked'])) {
547  $addcolspan++;
548 }
549 foreach ($arrayfields as $key => $val) {
550  if ($val['checked'] && substr($key, 0, 5) == 'efpt.') {
551  $addcolspan++;
552  }
553 }
554 
555 print '<div class="div-table-responsive">';
556 print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'" id="tablelines3">'."\n";
557 
558 print '<tr class="liste_titre_filter">';
559 if (!empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)) {
560  print '<td class="liste_titre"><input type="text" size="4" name="search_project_ref" value="'.dol_escape_htmltag($search_project_ref).'"></td>';
561 }
562 if (!empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)) {
563  print '<td class="liste_titre"><input type="text" size="4" name="search_thirdparty" value="'.dol_escape_htmltag($search_thirdparty).'"></td>';
564 }
565 print '<td class="liste_titre"><input type="text" size="4" name="search_task_label" value="'.dol_escape_htmltag($search_task_label).'"></td>';
566 // TASK fields
567 $search_options_pattern = 'search_task_options_';
568 $extrafieldsobjectkey = 'projet_task';
569 $extrafieldsobjectprefix = 'efpt.';
570 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
571 if (!empty($arrayfields['t.planned_workload']['checked'])) {
572  print '<td class="liste_titre"></td>';
573 }
574 if (!empty($arrayfields['t.progress']['checked'])) {
575  print '<td class="liste_titre right"><input type="text" size="4" name="search_declared_progress" value="'.dol_escape_htmltag($search_declared_progress).'"></td>';
576 }
577 if (!empty($arrayfields['timeconsumed']['checked'])) {
578  print '<td class="liste_titre"></td>';
579  print '<td class="liste_titre"></td>';
580 }
581 print '<td class="liste_titre"></td>';
582 print '<td class="liste_titre"></td>';
583 print '<td class="liste_titre"></td>';
584 // Action column
585 print '<td class="liste_titre nowrap right">';
586 $searchpicto = $form->showFilterAndCheckAddButtons(0);
587 print $searchpicto;
588 print '</td>';
589 print "</tr>\n";
590 
591 print '<tr class="liste_titre">';
592 if (!empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)) {
593  print '<th>'.$langs->trans("Project").'</th>';
594 }
595 if (!empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)) {
596  print '<th>'.$langs->trans("ThirdParty").'</th>';
597 }
598 print '<th>'.$langs->trans("Task").'</th>';
599 // TASK fields
600 $extrafieldsobjectkey = 'projet_task';
601 $extrafieldsobjectprefix = 'efpt.';
602 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
603 if (!empty($arrayfields['t.planned_workload']['checked'])) {
604  print '<th class="leftborder plannedworkload minwidth75 maxwidth100 right" title="'.dol_escape_htmltag($langs->trans("PlannedWorkload")).'">'.$langs->trans("PlannedWorkload").'</th>';
605 }
606 if (!empty($arrayfields['t.progress']['checked'])) {
607  print '<th class="right minwidth75 maxwidth100 title="'.dol_escape_htmltag($langs->trans("ProgressDeclared")).'">'.$langs->trans("ProgressDeclared").'</th>';
608 }
609 if (!empty($arrayfields['timeconsumed']['checked'])) {
610  print '<th class="right maxwidth100">'.$langs->trans("TimeSpent").'<br>';
611  print '<span class="nowraponall">';
612  print '<span class="opacitymedium nopadding userimg"><img alt="Photo" class="photouserphoto userphoto" src="'.DOL_URL_ROOT.'/theme/common/everybody.png"></span>';
613  print '<span class="opacitymedium paddingleft">'.$langs->trans("Everybody").'</span>';
614  print '</span>';
615  print '</th>';
616  print '<th class="right maxwidth75 maxwidth100">'.$langs->trans("TimeSpent").($usertoprocess->firstname ? '<br><span class="nowraponall">'.$usertoprocess->getNomUrl(-2).'<span class="opacitymedium paddingleft">'.dol_trunc($usertoprocess->firstname, 10).'</span></span>' : '').'</th>';
617 }
618 print '<th class="center leftborder">'.$langs->trans("HourStart").'</td>';
619 
620 // By default, we can edit only tasks we are assigned to
621 $restrictviewformytask = ((!isset($conf->global->PROJECT_TIME_SHOW_TASK_NOT_ASSIGNED)) ? 2 : $conf->global->PROJECT_TIME_SHOW_TASK_NOT_ASSIGNED);
622 
623 $numendworkingday = 0;
624 $numstartworkingday = 0;
625 // Get if user is available or not for each day
626 $isavailable = array();
627 
628 // Assume from Monday to Friday if conf empty or badly formed
629 $numstartworkingday = 1;
630 $numendworkingday = 5;
631 
632 if (!empty($conf->global->MAIN_DEFAULT_WORKING_DAYS)) {
633  $tmparray = explode('-', $conf->global->MAIN_DEFAULT_WORKING_DAYS);
634  if (count($tmparray) >= 2) {
635  $numstartworkingday = $tmparray[0];
636  $numendworkingday = $tmparray[1];
637  }
638 }
639 
640 $statusofholidaytocheck = Holiday::STATUS_APPROVED;
641 $isavailablefordayanduser = $holiday->verifDateHolidayForTimestamp($usertoprocess->id, $daytoparse, $statusofholidaytocheck); // $daytoparse is a date with hours = 0
642 $isavailable[$daytoparse] = $isavailablefordayanduser; // in projectLinesPerWeek later, we are using $firstdaytoshow and dol_time_plus_duree to loop on each day
643 
644 $test = num_public_holiday($daytoparsegmt, $daytoparsegmt + 86400, $mysoc->country_code);
645 if ($test) {
646  $isavailable[$daytoparse] = array('morning'=>false, 'afternoon'=>false, 'morning_reason'=>'public_holiday', 'afternoon_reason'=>'public_holiday');
647 }
648 
649 $tmparray = dol_getdate($daytoparse, true); // detail of current day
650 // For monday, must be 0 for monday if MAIN_START_WEEK = 1, must be 1 for monday if MAIN_START_WEEK = 0
651 $idw = ($tmparray['wday'] - (empty($conf->global->MAIN_START_WEEK) ? 0 : 1));
652 // numstartworkingday and numendworkingday are default start and end date of working days (1 means sunday if MAIN_START_WEEK is 0, 1 means monday if MAIN_START_WEEK is 1)
653 $cssweekend = '';
654 if ((($idw + 1) < $numstartworkingday) || (($idw + 1) > $numendworkingday)) { // This is a day is not inside the setup of working days, so we use a week-end css.
655  $cssweekend = 'weekend';
656 }
657 
658 $tmpday = dol_time_plus_duree($daytoparse, $idw, 'd');
659 
660 $cssonholiday = '';
661 if (!$isavailable[$daytoparse]['morning'] && !$isavailable[$daytoparse]['afternoon']) {
662  $cssonholiday .= 'onholidayallday ';
663 } elseif (!$isavailable[$daytoparse]['morning']) {
664  $cssonholiday .= 'onholidaymorning ';
665 } elseif (!$isavailable[$daytoparse]['afternoon']) {
666  $cssonholiday .= 'onholidayafternoon ';
667 }
668 
669 print '<th class="center'.($cssonholiday ? ' '.$cssonholiday : '').($cssweekend ? ' '.$cssweekend : '').'">'.$langs->trans("Duration").'</th>';
670 print '<th class="center">'.$langs->trans("Note").'</th>';
671 //print '<td class="center"></td>';
672 print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
673 
674 print "</tr>\n";
675 
676 $colspan = 2 + (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT) ? 0 : 2);
677 
678 if ($conf->use_javascript_ajax) {
679  print '<tr class="liste_total">';
680  print '<td class="liste_total" colspan="'.($colspan - 1 + $addcolspan).'">';
681  print $langs->trans("Total");
682  print '</td>';
683  if (!empty($arrayfields['timeconsumed']['checked'])) {
684  print '<td class="liste_total"></td>';
685  print '<td class="liste_total"></td>';
686  }
687  print '<td class="liste_total leftborder">';
688  //print ' - '.$langs->trans("ExpectedWorkedHours").': <strong>'.price($usertoprocess->weeklyhours, 1, $langs, 0, 0).'</strong>';
689  print '</td>';
690 
691  print '<td class="liste_total center'.($cssonholiday ? ' '.$cssonholiday : '').($cssweekend ? ' '.$cssweekend : '').'"><div class="totalDay0">&nbsp;</div></td>';
692 
693  print '<td class="liste_total"></td>';
694  print '<td class="liste_total"></td>';
695  print '</tr>';
696 }
697 
698 
699 if (count($tasksarray) > 0) {
700  //var_dump($tasksarray); // contains only selected tasks
701  //var_dump($tasksarraywithoutfilter); // contains all tasks (if there is a filter, not defined if no filter)
702  //var_dump($tasksrole);
703 
704  $j = 0;
705  $level = 0;
706  $totalforvisibletasks = projectLinesPerDay($j, 0, $usertoprocess, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask, $daytoparse, $isavailable, 0, $arrayfields, $extrafields);
707  //var_dump($totalforvisibletasks);
708 
709  // Show total for all other tasks
710 
711  // Calculate total for all tasks
712  $listofdistinctprojectid = array(); // List of all distinct projects
713  if (!empty($tasksarraywithoutfilter) && is_array($tasksarraywithoutfilter) && count($tasksarraywithoutfilter)) {
714  foreach ($tasksarraywithoutfilter as $tmptask) {
715  $listofdistinctprojectid[$tmptask->fk_project] = $tmptask->fk_project;
716  }
717  }
718  //var_dump($listofdistinctprojectid);
719  $totalforeachday = array();
720  foreach ($listofdistinctprojectid as $tmpprojectid) {
721  $projectstatic->id = $tmpprojectid;
722  $projectstatic->loadTimeSpent($daytoparse, 0, $usertoprocess->id); // Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week
723  for ($idw = 0; $idw < 7; $idw++) {
724  $tmpday = dol_time_plus_duree($daytoparse, $idw, 'd');
725  $totalforeachday[$tmpday] += $projectstatic->weekWorkLoad[$tmpday];
726  }
727  }
728  //var_dump($totalforeachday);
729 
730  // Is there a diff between selected/filtered tasks and all tasks ?
731  $isdiff = 0;
732  if (count($totalforeachday)) {
733  $timeonothertasks = ($totalforeachday[$daytoparse] - $totalforvisibletasks[$daytoparse]);
734  if ($timeonothertasks) {
735  $isdiff = 1;
736  }
737  }
738 
739  // There is a diff between total shown on screen and total spent by user, so we add a line with all other cumulated time of user
740  if ($isdiff) {
741  print '<tr class="oddeven othertaskwithtime">';
742  print '<td colspan="'.($colspan - 1).'" class="opacitymedium">';
743  print $langs->trans("OtherFilteredTasks");
744  print '</td>';
745  if (!empty($arrayfields['timeconsumed']['checked'])) {
746  print '<td class="liste_total"></td>';
747  print '<td class="liste_total"></td>';
748  }
749  print '<td class="leftborder"></td>';
750  print '<td class="center">';
751  $timeonothertasks = ($totalforeachday[$daytoparse] - $totalforvisibletasks[$daytoparse]);
752  //if ($timeonothertasks)
753  //{
754  print '<span class="timesheetalreadyrecorded" title="texttoreplace"><input type="text" class="center" size="2" disabled="" id="timespent[-1][0]" name="task[-1][0]" value="';
755  if ($timeonothertasks) {
756  print convertSecondToTime($timeonothertasks, 'allhourmin');
757  }
758  print '"></span>';
759  //}
760  print '</td>';
761  print ' <td class="liste_total"></td>';
762  print ' <td class="liste_total"></td>';
763  print '</tr>';
764  }
765 
766  if ($conf->use_javascript_ajax) {
767  print '<tr class="liste_total">';
768  print '<td class="liste_total" colspan="'.($colspan - 1 + $addcolspan).'">';
769  print $langs->trans("Total");
770  print '</td>';
771  if (!empty($arrayfields['timeconsumed']['checked'])) {
772  print '<td class="liste_total"></td>';
773  print '<td class="liste_total"></td>';
774  }
775  print '<td class="liste_total leftborder">';
776  //print ' - '.$langs->trans("ExpectedWorkedHours").': <strong>'.price($usertoprocess->weeklyhours, 1, $langs, 0, 0).'</strong>';
777  print '</td>';
778 
779  print '<td class="liste_total center'.($cssonholiday ? ' '.$cssonholiday : '').($cssweekend ? ' '.$cssweekend : '').'"><div class="totalDay0">&nbsp;</div></td>';
780 
781  print '<td class="liste_total"></td>
782  <td class="liste_total"></td>
783  </tr>';
784  }
785 } else {
786  print '<tr><td colspan="14"><span class="opacitymedium">'.$langs->trans("NoAssignedTasks").'</span></td></tr>';
787 }
788 print "</table>";
789 print '</div>';
790 
791 print '<input type="hidden" id="numberOfLines" name="numberOfLines" value="'.count($tasksarray).'"/>'."\n";
792 
793 print '<div class="center">';
794 print '<input type="submit" name="button_addtime" class="button button-save"'.(!empty($disabledtask) ? ' disabled' : '').' value="'.$langs->trans("Save").'">';
795 print '</div>';
796 
797 print '</form>';
798 
799 if (!empty($conf->use_javascript_ajax)) {
800  $modeinput = 'hours';
801  print "\n<!-- JS CODE TO ENABLE Tooltips on all object with class classfortooltip -->\n";
802  print '<script type="text/javascript">'."\n";
803  print "jQuery(document).ready(function () {\n";
804  print " updateTotal(0,\''.$modeinput.'\');\n";
805  print ' jQuery(".timesheetalreadyrecorded").tooltip({
806  show: { collision: "flipfit", effect:\'toggle\', delay:50 },
807  hide: { effect:\'toggle\', delay: 50 },
808  tooltipClass: "mytooltip",
809  content: function () {
810  return \''.dol_escape_js($langs->trans("TimeAlreadyRecorded", $usertoprocess->getFullName($langs))).'\';
811  }
812  });'."\n";
813  print " jQuery('.inputhour, .inputminute').bind('keyup', function(e) { updateTotal(0, '".$modeinput."') });";
814  print "\n});\n";
815  print '</script>';
816 }
817 
818 // End of page
819 llxFooter();
820 $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
Class to manage standard extra fields.
Class to build HTML component for third parties management Only common components are here.
Class to manage generation of HTML components Only common components must be here.
Classe permettant la generation de composants html autre Only common components are here.
Class to manage building of HTML components.
Class of the module paid holiday.
const STATUS_APPROVED
Approved.
Class to manage projects.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage tasks.
Definition: task.class.php:38
Class to manage Dolibarr users.
Definition: user.class.php:47
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:745
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition: date.lib.php:121
convertSecondToTime($iSecond, $format='all', $lengthOfDay=86400, $lengthOfWeek=7)
Return, in clear text, value of a number of seconds in days, hours and minutes.
Definition: date.lib.php:238
num_public_holiday($timestampStart, $timestampEnd, $country_code='', $lastday=0, $includesaturday=-1, $includesunday=-1, $includefriday=-1, $includemonday=-1)
Return the number of non working days including Friday, Saturday and Sunday (or not) between 2 dates ...
Definition: date.lib.php:744
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...
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='')
Show tabs of a record.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_get_fiche_end($notab=0)
Return tab footer of a card.
natural_search($fields, $value, $mode=0, $nofirstand=0)
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_now($mode='auto')
Return date for now.
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.
img_previous($titlealt='default', $moreatt='')
Show previous logo.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
img_next($titlealt='default', $moreatt='')
Show next logo.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask, $preselectedday, &$isavailable, $oldprojectforbreak=0, $arrayfields=array(), $extrafields=null)
Output a task line into a pertime intput mode.
project_timesheet_prepare_head($mode, $fuser=null)
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.