dolibarr  13.0.2
permonth.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2015 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005-2010 Regis Houssin <regis.houssin@capnetworks.com>
5  * Copyright (C) 2010 François Legastelois <flegastelois@teclib.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
27 require "../../main.inc.php";
28 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
29 require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
30 require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
31 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
32 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
34 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
35 require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php';
36 
37 // Load translation files required by the page
38 $langs->loadLangs(array('projects', 'users', 'companies'));
39 $hookmanager->initHooks(array('timesheetpermonthcard'));
40 
41 $action = GETPOST('action', 'aZ09');
42 $mode = GETPOST("mode", 'alpha');
43 $id = GETPOST('id', 'int');
44 $taskid = GETPOST('taskid', 'int');
45 
46 $mine = 0;
47 if ($mode == 'mine') $mine = 1;
48 
49 $projectid = isset($_GET["id"]) ? GETPOST("id", "int", 1) : GETPOST("projectid", "int");
50 
51 // Security check
52 $socid = 0;
53 // For external user, no check is done on company because readability is managed by public status of project and assignement.
54 // if ($user->societe_id > 0) $socid=$user->societe_id;
55 $result = restrictedArea($user, 'projet', $projectid);
56 
57 $now = dol_now();
58 $nowtmp = dol_getdate($now);
59 $nowday = $nowtmp['mday'];
60 $nowmonth = $nowtmp['mon'];
61 $nowyear = $nowtmp['year'];
62 
63 $year = GETPOST('reyear') ?GETPOST('reyear', 'int') : (GETPOST("year") ?GETPOST("year", "int") : date("Y"));
64 $month = GETPOST('remonth') ?GETPOST('remonth', 'int') : (GETPOST("month") ?GETPOST("month", "int") : date("m"));
65 $day = GETPOST('reday') ?GETPOST('reday', 'int') : (GETPOST("day") ?GETPOST("day", "int") : date("d"));
66 $day = (int) $day;
67 $week = GETPOST("week", "int") ?GETPOST("week", "int") : date("W");
68 
69 $search_categ = GETPOST("search_categ", 'alpha');
70 $search_usertoprocessid = GETPOST('search_usertoprocessid', 'int');
71 $search_task_ref = GETPOST('search_task_ref', 'alpha');
72 $search_task_label = GETPOST('search_task_label', 'alpha');
73 $search_project_ref = GETPOST('search_project_ref', 'alpha');
74 $search_thirdparty = GETPOST('search_thirdparty', 'alpha');
75 $search_declared_progress = GETPOST('search_declared_progress', 'alpha');
76 
77 $startdayarray = dol_get_prev_month($month, $year);
78 
79 $prev = $startdayarray;
80 $prev_year = $prev['year'];
81 $prev_month = $prev['month'];
82 $prev_day = 1;
83 
84 $next = dol_get_next_month($month, $year);
85 $next_year = $next['year'];
86 $next_month = $next['month'];
87 $next_day = 1;
88 $TWeek = getWeekNumbersOfMonth($month, $year);
89 $firstdaytoshow = dol_mktime(0, 0, 0, $month, 1, $year);
90 $TFirstDays = getFirstDayOfEachWeek($TWeek, $year);
91 $TFirstDays[reset($TWeek)] = '01'; //first day of month
92 $TLastDays = getLastDayOfEachWeek($TWeek, $year);
93 $TLastDays[end($TWeek)] = date("t", strtotime($year.'-'.$month.'-'.$day)); //last day of month
94 if (empty($search_usertoprocessid) || $search_usertoprocessid == $user->id)
95 {
96  $usertoprocess = $user;
97  $search_usertoprocessid = $usertoprocess->id;
98 } elseif ($search_usertoprocessid > 0)
99 {
100  $usertoprocess = new User($db);
101  $usertoprocess->fetch($search_usertoprocessid);
102  $search_usertoprocessid = $usertoprocess->id;
103 } else {
104  $usertoprocess = new User($db);
105 }
106 
107 $object = new Task($db);
108 
109 
110 /*
111  * Actions
112  */
113 $parameters = array('id' => $id, 'taskid' => $taskid, 'projectid' => $projectid, 'TWeek' => $TWeek, 'TFirstDays' => $TFirstDays, 'TLastDays' => $TLastDays);
114 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
115 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
116 
117 // Purge criteria
118 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
119 {
120  $action = '';
121  $search_categ = '';
122  $search_usertoprocessid = $user->id;
123  $search_task_ref = '';
124  $search_task_label = '';
125  $search_project_ref = '';
126  $search_thirdparty = '';
127  $search_declared_progress = '';
128 }
129 if (GETPOST("button_search_x", 'alpha') || GETPOST("button_search.x", 'alpha') || GETPOST("button_search", 'alpha'))
130 {
131  $action = '';
132 }
133 
134 if (GETPOST('submitdateselect'))
135 {
136  $daytoparse = dol_mktime(0, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
137 
138  $action = '';
139 }
140 if ($action == 'addtime' && $user->rights->projet->lire && GETPOST('assigntask'))
141 {
142  $action = 'assigntask';
143 
144  if ($taskid > 0)
145  {
146  $result = $object->fetch($taskid, $ref);
147  if ($result < 0) $error++;
148  } else {
149  setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Task")), '', 'errors');
150  $error++;
151  }
152  if (!GETPOST('type'))
153  {
154  setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), '', 'errors');
155  $error++;
156  }
157 
158  if (!$error)
159  {
160  $idfortaskuser = $usertoprocess->id;
161  $result = $object->add_contact($idfortaskuser, GETPOST("type"), 'internal');
162 
163  if ($result >= 0 || $result == -2) // Contact add ok or already contact of task
164  {
165  // 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)
166  $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';
167  $sql .= ' AND ec.fk_socpeople = '.$idfortaskuser." AND ec.element_id = '.$object->fk_project.' AND tc.element = 'project' AND source = 'internal'";
168  $resql = $db->query($sql);
169  if ($resql)
170  {
171  $obj = $db->fetch_object($resql);
172  if (!$obj) // User is not already linked to project, so we will create link to first type
173  {
174  $project = new Project($db);
175  $project->fetch($object->fk_project);
176  // Get type
177  $listofprojcontact = $project->liste_type_contact('internal');
178 
179  if (count($listofprojcontact))
180  {
181  $typeforprojectcontact = reset(array_keys($listofprojcontact));
182  $result = $project->add_contact($idfortaskuser, $typeforprojectcontact, 'internal');
183  }
184  }
185  } else {
186  dol_print_error($db);
187  }
188  }
189  }
190 
191  if ($result < 0)
192  {
193  $error++;
194  if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS')
195  {
196  $langs->load("errors");
197  setEventMessages($langs->trans("ErrorTaskAlreadyAssigned"), null, 'warnings');
198  } else {
199  setEventMessages($object->error, $object->errors, 'errors');
200  }
201  }
202 
203  if (!$error)
204  {
205  setEventMessages("TaskAssignedToEnterTime", null);
206  $taskid = 0;
207  }
208 
209  $action = '';
210 }
211 
212 if ($action == 'addtime' && $user->rights->projet->lire)
213 {
214  $timetoadd = $_POST['task'];
215  if (empty($timetoadd))
216  {
217  setEventMessages($langs->trans("ErrorTimeSpentIsEmpty"), null, 'errors');
218  } else {
219  foreach ($timetoadd as $taskid => $value) // Loop on each task
220  {
221  $updateoftaskdone = 0;
222  foreach ($value as $key => $val) // Loop on each day
223  {
224  $amountoadd = $timetoadd[$taskid][$key];
225  if (!empty($amountoadd))
226  {
227  $tmpduration = explode(':', $amountoadd);
228  $newduration = 0;
229  if (!empty($tmpduration[0])) $newduration += ($tmpduration[0] * 3600);
230  if (!empty($tmpduration[1])) $newduration += ($tmpduration[1] * 60);
231  if (!empty($tmpduration[2])) $newduration += ($tmpduration[2]);
232 
233  if ($newduration > 0)
234  {
235  $object->fetch($taskid);
236  $object->progress = GETPOST($taskid.'progress', 'int');
237  $object->timespent_duration = $newduration;
238  $object->timespent_fk_user = $usertoprocess->id;
239  $object->timespent_date = dol_time_plus_duree($firstdaytoshow, $key, 'd');
240  $object->timespent_datehour = $object->timespent_date;
241 
242  $result = $object->addTimeSpent($user);
243  if ($result < 0)
244  {
245  setEventMessages($object->error, $object->errors, 'errors');
246  $error++;
247  break;
248  }
249 
250  $updateoftaskdone++;
251  }
252  }
253  }
254 
255  if (!$updateoftaskdone) // Check to update progress if no update were done on task.
256  {
257  $object->fetch($taskid);
258  //var_dump($object->progress);var_dump(GETPOST($taskid . 'progress', 'int')); exit;
259  if ($object->progress != GETPOST($taskid.'progress', 'int'))
260  {
261  $object->progress = GETPOST($taskid.'progress', 'int');
262  $result = $object->update($user);
263  if ($result < 0)
264  {
265  setEventMessages($object->error, $object->errors, 'errors');
266  $error++;
267  break;
268  }
269  }
270  }
271  }
272 
273  if (!$error)
274  {
275  setEventMessages($langs->trans("RecordSaved"), null, 'mesgs');
276 
277  $param = '';
278  $param .= ($mode ? '&mode='.$mode : '');
279  $param .= ($projectid ? 'id='.$projectid : '');
280  $param .= ($search_usertoprocessid ? '&search_usertoprocessid='.$search_usertoprocessid : '');
281  $param .= ($day ? '&day='.$day : '').($month ? '&month='.$month : '').($year ? '&year='.$year : '');
282  $param .= ($search_project_ref ? '&search_project_ref='.$search_project_ref : '');
283  $param .= ($search_usertoprocessid > 0 ? '&search_usertoprocessid='.$search_usertoprocessid : '');
284  $param .= ($search_thirdparty ? '&search_thirdparty='.$search_thirdparty : '');
285  $param .= ($search_declared_progress ? '&search_declared_progress='.$search_declared_progress : '');
286  $param .= ($search_task_ref ? '&search_task_ref='.$search_task_ref : '');
287  $param .= ($search_task_label ? '&search_task_label='.$search_task_label : '');
288 
289  // Redirect to avoid submit twice on back
290  header('Location: '.$_SERVER["PHP_SELF"].'?'.$param);
291  exit;
292  }
293  }
294 }
295 
296 
297 
298 /*
299  * View
300  */
301 
302 $form = new Form($db);
303 $formother = new FormOther($db);
304 $formcompany = new FormCompany($db);
305 $formproject = new FormProjets($db);
306 $projectstatic = new Project($db);
307 $project = new Project($db);
308 $taskstatic = new Task($db);
309 $thirdpartystatic = new Societe($db);
310 $holiday = new Holiday($db);
311 
312 $title = $langs->trans("TimeSpent");
313 
314 $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
315 //var_dump($projectsListId);
316 if ($id)
317 {
318  $project->fetch($id);
319  $project->fetch_thirdparty();
320 }
321 
322 $onlyopenedproject = 1; // or -1
323 $morewherefilter = '';
324 
325 if ($search_project_ref) $morewherefilter .= natural_search(array("p.ref", "p.title"), $search_project_ref);
326 if ($search_task_ref) $morewherefilter .= natural_search("t.ref", $search_task_ref);
327 if ($search_task_label) $morewherefilter .= natural_search(array("t.ref", "t.label"), $search_task_label);
328 if ($search_thirdparty) $morewherefilter .= natural_search("s.nom", $search_thirdparty);
329 if ($search_declared_progress) $morewherefilter .= natural_search("t.progress", $search_declared_progress, 1);
330 
331 $tasksarray = $taskstatic->getTasksArray(0, 0, ($project->id ? $project->id : 0), $socid, 0, $search_project_ref, $onlyopenedproject, $morewherefilter, ($search_usertoprocessid ? $search_usertoprocessid : 0)); // We want to see all tasks of open project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later.
332 if ($morewherefilter) // Get all task without any filter, so we can show total of time spent for not visible tasks
333 {
334  $tasksarraywithoutfilter = $taskstatic->getTasksArray(0, 0, ($project->id ? $project->id : 0), $socid, 0, '', $onlyopenedproject, '', ($search_usertoprocessid ? $search_usertoprocessid : 0)); // We want to see all tasks of open project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later.
335 }
336 $projectsrole = $taskstatic->getUserRolesForProjectsOrTasks($usertoprocess, 0, ($project->id ? $project->id : 0), 0, $onlyopenedproject);
337 $tasksrole = $taskstatic->getUserRolesForProjectsOrTasks(0, $usertoprocess, ($project->id ? $project->id : 0), 0, $onlyopenedproject);
338 //var_dump($tasksarray);
339 //var_dump($projectsrole);
340 //var_dump($taskrole);
341 
342 
343 llxHeader("", $title, "", '', '', '', array('/core/js/timesheet.js'));
344 
345 //print_barre_liste($title, $page, $_SERVER["PHP_SELF"], "", $sortfield, $sortorder, "", $num, '', 'title_project');
346 
347 $param = '';
348 $param .= ($mode ? '&mode='.$mode : '');
349 $param .= ($search_project_ref ? '&search_project_ref='.$search_project_ref : '');
350 $param .= ($search_usertoprocessid > 0 ? '&search_usertoprocessid='.$search_usertoprocessid : '');
351 $param .= ($search_thirdparty ? '&search_thirdparty='.$search_thirdparty : '');
352 $param .= ($search_task_ref ? '&search_task_ref='.$search_task_ref : '');
353 $param .= ($search_task_label ? '&search_task_label='.$search_task_label : '');
354 
355 // Show navigation bar
356 $nav = '<a class="inline-block valignmiddle" href="?year='.$prev_year."&month=".$prev_month."&day=".$prev_day.$param.'">'.img_previous($langs->trans("Previous"))."</a>\n";
357 $nav .= " <span id=\"month_name\">".dol_print_date(dol_mktime(0, 0, 0, $month, 1, $year), "%Y").", ".$langs->trans(date('F', mktime(0, 0, 0, $month, 10)))." </span>\n";
358 $nav .= '<a class="inline-block valignmiddle" href="?year='.$next_year."&month=".$next_month."&day=".$next_day.$param.'">'.img_next($langs->trans("Next"))."</a>\n";
359 //$nav.=" &nbsp; (<a href=\"?year=".$nowyear."&month=".$nowmonth."&day=".$nowday.$param."\">".$langs->trans("Today")."</a>)";
360 $nav .= ' '.$form->selectDate(-1, '', 0, 0, 2, "addtime", 1, 1).' ';
361 //$nav.=' <input type="submit" name="submitdateselect" class="button" value="'.$langs->trans("Refresh").'">';
362 $nav .= ' <button type="submit" name="button_search_x" value="x" class="bordertransp"><span class="fa fa-search"></span></button>';
363 
364 $picto = 'clock';
365 
366 print '<form name="addtime" method="POST" action="'.$_SERVER["PHP_SELF"].'">';
367 print '<input type="hidden" name="token" value="'.newToken().'">';
368 print '<input type="hidden" name="action" value="addtime">';
369 print '<input type="hidden" name="mode" value="'.$mode.'">';
370 print '<input type="hidden" name="day" value="'.$day.'">';
371 print '<input type="hidden" name="month" value="'.$month.'">';
372 print '<input type="hidden" name="year" value="'.$year.'">';
373 
374 $head = project_timesheet_prepare_head($mode, $usertoprocess);
375 print dol_get_fiche_head($head, 'inputpermonth', $langs->trans('TimeSpent'), -1, $picto);
376 
377 // Show description of content
378 print '<div class="hideonsmartphone opacitymedium">';
379 if ($mine || ($usertoprocess->id == $user->id)) print $langs->trans("MyTasksDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'<br>';
380 else {
381  if (empty($usertoprocess->id) || $usertoprocess->id < 0)
382  {
383  if ($user->rights->projet->all->lire && !$socid) print $langs->trans("ProjectsDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'<br>';
384  else print $langs->trans("ProjectsPublicTaskDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'<br>';
385  }
386 }
387 if ($mine || ($usertoprocess->id == $user->id))
388 {
389  print $langs->trans("OnlyYourTaskAreVisible").'<br>';
390 } else {
391  print $langs->trans("AllTaskVisibleButEditIfYouAreAssigned").'<br>';
392 }
393 print '</div>';
394 
395 print dol_get_fiche_end();
396 
397 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.
398 
399 print '<div class="colorbacktimesheet float valignmiddle">';
400 $titleassigntask = $langs->transnoentities("AssignTaskToMe");
401 if ($usertoprocess->id != $user->id) $titleassigntask = $langs->transnoentities("AssignTaskToUser", $usertoprocess->getFullName($langs));
402 print '<div class="taskiddiv inline-block">';
403 print img_picto('', 'projecttask');
404 $formproject->selectTasks($socid ? $socid : -1, $taskid, 'taskid', 32, 0, '-- '.$langs->trans("ChooseANotYetAssignedTask").' --', 1);
405 print '</div>';
406 print ' ';
407 print $formcompany->selectTypeContact($object, '', 'type', 'internal', 'rowid', 0, 'maxwidth150onsmartphone');
408 print '<input type="submit" class="button valignmiddle" name="assigntask" value="'.dol_escape_htmltag($titleassigntask).'">';
409 print '</div>';
410 
411 print '<div class="clearboth" style="padding-bottom: 20px;"></div>';
412 
413 
414 $moreforfilter = '';
415 
416 // Filter on categories
417 /*
418 if (! empty($conf->categorie->enabled))
419 {
420  require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
421  $moreforfilter.='<div class="divsearchfield">';
422  $moreforfilter.=$langs->trans('ProjectCategories'). ': ';
423  $moreforfilter.=$formother->select_categories('project', $search_categ, 'search_categ', 1, 1, 'maxwidth300');
424  $moreforfilter.='</div>';
425 }*/
426 
427 // If the user can view user other than himself
428 $moreforfilter .= '<div class="divsearchfield">';
429 $moreforfilter .= '<div class="inline-block hideonsmartphone"></div>';
430 $includeonly = 'hierachyme';
431 if (empty($user->rights->user->user->lire)) $includeonly = array($user->id);
432 $moreforfilter .= img_picto($langs->trans('User'), 'user').$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');
433 $moreforfilter .= '</div>';
434 
435 if (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT))
436 {
437  $moreforfilter .= '<div class="divsearchfield">';
438  $moreforfilter .= '<div class="inline-block"></div>';
439  $moreforfilter .= img_picto($langs->trans('Project'), 'project').'<input type="text" size="4" name="search_project_ref" class="marginleftonly" value="'.dol_escape_htmltag($search_project_ref).'">';
440  $moreforfilter .= '</div>';
441 
442  $moreforfilter .= '<div class="divsearchfield">';
443  $moreforfilter .= '<div class="inline-block"></div>';
444  $moreforfilter .= img_picto($langs->trans('ThirdParty'), 'company').'<input type="text" size="4" name="search_thirdparty" class="marginleftonly" value="'.dol_escape_htmltag($search_thirdparty).'">';
445  $moreforfilter .= '</div>';
446 }
447 
448 if (!empty($moreforfilter))
449 {
450  print '<div class="liste_titre liste_titre_bydiv centpercent">';
451  print $moreforfilter;
452  $parameters = array();
453  $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
454  print $hookmanager->resPrint;
455  print '</div>';
456 }
457 
458 print '<div class="div-table-responsive">';
459 
460 print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'" id="tablelines3">'."\n";
461 
462 print '<tr class="liste_titre_filter">';
463 if (!empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)) print '<td class="liste_titre"><input type="text" size="4" name="search_project_ref" value="'.dol_escape_htmltag($search_project_ref).'"></td>';
464 if (!empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)) print '<td class="liste_titre"><input type="text" size="4" name="search_thirdparty" value="'.dol_escape_htmltag($search_thirdparty).'"></td>';
465 print '<td class="liste_titre"><input type="text" size="4" name="search_task_label" value="'.dol_escape_htmltag($search_task_label).'"></td>';
466 print '<td class="liste_titre"></td>';
467 print '<td class="liste_titre right"><input type="text" size="4" name="search_declared_progress" value="'.dol_escape_htmltag($search_declared_progress).'"></td>';
468 print '<td class="liste_titre"></td>';
469 print '<td class="liste_titre"></td>';
470 foreach ($TWeek as $week_number)
471 {
472  print '<td class="liste_titre"></td>';
473 }
474 // Action column
475 print '<td class="liste_titre nowrap" align="right">';
476 $searchpicto = $form->showFilterAndCheckAddButtons(0);
477 print $searchpicto;
478 print '</td>';
479 print "</tr>\n";
480 
481 print '<tr class="liste_titre">';
482 if (!empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)) print '<td>'.$langs->trans("Project").'</td>';
483 if (!empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)) print '<td>'.$langs->trans("ThirdParty").'</td>';
484 print '<td>'.$langs->trans("Task").'</td>';
485 print '<td align="right" class="leftborder plannedworkload maxwidth75">'.$langs->trans("PlannedWorkload").'</td>';
486 print '<td align="right" class="maxwidth75">'.$langs->trans("ProgressDeclared").'</td>';
487 /*print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpent").'</td>';
488  if ($usertoprocess->id == $user->id) print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpentByYou").'</td>';
489  else print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpentByUser").'</td>';*/
490 print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpent").'<br><span class="opacitymedium">'.$langs->trans("Everybody").'</span></td>';
491 print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpent").($usertoprocess->firstname ? '<br><span class="opacitymedium">'.dol_trunc($usertoprocess->firstname, 10).'</span>' : '').'</td>';
492 
493 foreach ($TWeek as $week_number)
494 {
495  print '<td width="6%" align="center" class="bold hide">'.$langs->trans("Week").' '.$week_number.'<br>('.$TFirstDays[$week_number].'...'.$TLastDays[$week_number].')</td>';
496 }
497 print '<td></td>';
498 print "</tr>\n";
499 
500 $colspan = 5;
501 
502 // By default, we can edit only tasks we are assigned to
503 $restrictviewformytask = (empty($conf->global->PROJECT_TIME_SHOW_TASK_NOT_ASSIGNED) ? 1 : 0);
504 
505 // Get if user is available or not for each day
506 $isavailable = array();
507 // TODO See code into perweek.php to initialize isavailable array
508 
509 
510 if (count($tasksarray) > 0)
511 {
512  //var_dump($tasksarray); // contains only selected tasks
513  //var_dump($tasksarraywithoutfilter); // contains all tasks (if there is a filter, not defined if no filter)
514  //var_dump($tasksrole);
515 
516  $j = 0;
517  $level = 0;
518  $totalforvisibletasks = projectLinesPerMonth($j, $firstdaytoshow, $usertoprocess, 0, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask, $isavailable, 0, $TWeek);
519  //var_dump($totalforvisibletasks);
520 
521  // Show total for all other tasks
522 
523  // Calculate total for all tasks
524  $listofdistinctprojectid = array(); // List of all distinct projects
525  if (is_array($tasksarraywithoutfilter) && count($tasksarraywithoutfilter))
526  {
527  foreach ($tasksarraywithoutfilter as $tmptask)
528  {
529  $listofdistinctprojectid[$tmptask->fk_project] = $tmptask->fk_project;
530  }
531  }
532  //var_dump($listofdistinctprojectid);
533  $totalforeachweek = array();
534  foreach ($listofdistinctprojectid as $tmpprojectid)
535  {
536  $projectstatic->id = $tmpprojectid;
537  $projectstatic->loadTimeSpentMonth($firstdaytoshow, 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
538  foreach ($TWeek as $weekNb)
539  {
540  $totalforeachweek[$weekNb] += $projectstatic->monthWorkLoad[$weekNb];
541  }
542  }
543 
544  //var_dump($totalforeachday);
545  //var_dump($totalforvisibletasks);
546 
547  // Is there a diff between selected/filtered tasks and all tasks ?
548  $isdiff = 0;
549  if (count($totalforeachweek))
550  {
551  foreach ($TWeek as $weekNb)
552  {
553  $timeonothertasks = ($totalforeachweek[$weekNb] - $totalforvisibletasks[$weekNb]);
554  if ($timeonothertasks)
555  {
556  $isdiff = 1;
557  break;
558  }
559  }
560  }
561 
562  // 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
563  if ($isdiff)
564  {
565  print '<tr class="oddeven othertaskwithtime">';
566  print '<td colspan="'.$colspan.'" class="opacitymedium">';
567  print $langs->trans("OtherFilteredTasks");
568  print '</td>';
569  foreach ($TWeek as $weekNb)
570  {
571  print '<td class="center hide">';
572 
573  $timeonothertasks = ($totalforeachweek[$weekNb] - $totalforvisibletasks[$weekNb]);
574  if ($timeonothertasks)
575  {
576  print '<span class="timesheetalreadyrecorded" title="texttoreplace"><input type="text" class="center smallpadd" size="2" disabled="" id="timespent[-1]['.$weekNb.']" name="task[-1]['.$weekNb.']" value="';
577  print convertSecondToTime($timeonothertasks, 'allhourmin');
578  print '"></span>';
579  }
580  print '</td>';
581  }
582  print ' <td class="liste_total"></td>';
583  print '</tr>';
584  }
585 
586  if ($conf->use_javascript_ajax)
587  {
588  print '<tr class="liste_total">
589  <td class="liste_total" colspan="'.$colspan.'">';
590  print $langs->trans("Total");
591  print '<span class="opacitymediumbycolor"> - '.$langs->trans("ExpectedWorkedHours").': <strong>'.price($usertoprocess->weeklyhours, 1, $langs, 0, 0).'</strong></span>';
592  print '</td>';
593 
594  foreach ($TWeek as $weekNb)
595  {
596  print '<td class="liste_total hide'.$weekNb.'" align="center"><div class="totalDay'.$weekNb.'">'.convertSecondToTime($totalforvisibletasks[$weekNb], 'allhourmin').'</div></td>';
597  }
598  print '<td class="liste_total center"><div class="totalDayAll">&nbsp;</div></td>
599  </tr>';
600  }
601 } else {
602  print '<tr><td colspan="15"><span class="opacitymedium">'.$langs->trans("NoAssignedTasks").'</span></td></tr>';
603 }
604 print "</table>";
605 print '</div>';
606 
607 print '<input type="hidden" id="numberOfLines" name="numberOfLines" value="'.count($tasksarray).'"/>'."\n";
608 print '<input type="hidden" id="numberOfFirstLine" name="numberOfFirstLine" value="'.(reset($TWeek)).'"/>'."\n";
609 
610 print '<div class="center">';
611 print '<input type="submit" class="button button-save" name="save" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
612 print '</div>';
613 
614 print '</form>'."\n\n";
615 
616 $modeinput = 'hours';
617 
618 if ($conf->use_javascript_ajax)
619 {
620  print "\n<!-- JS CODE TO ENABLE Tooltips on all object with class classfortooltip -->\n";
621  print '<script type="text/javascript">'."\n";
622  print "jQuery(document).ready(function () {\n";
623  print ' jQuery(".timesheetalreadyrecorded").tooltip({
624  show: { collision: "flipfit", effect:\'toggle\', delay:50 },
625  hide: { effect:\'toggle\', delay: 50 },
626  tooltipClass: "mytooltip",
627  content: function () {
628  return \''.dol_escape_js($langs->trans("TimeAlreadyRecorded", $usertoprocess->getFullName($langs))).'\';
629  }
630  });'."\n";
631 
632  foreach ($TWeek as $week_number)
633  {
634  print ' updateTotal('.$week_number.',\''.$modeinput.'\');';
635  }
636  print "\n});\n";
637  print '</script>';
638 }
639 
640 
641 llxFooter();
642 
643 $db->close();
GETPOST($paramname, $check= 'alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
Class of the module paid holiday.
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_prev_month($month, $year)
Return previous month.
Definition: date.lib.php:398
dol_now($mode= 'auto')
Return date for now.
Class to manage Dolibarr users.
Definition: user.class.php:44
getFirstDayOfEachWeek($TWeek, $year)
Return array of first day of weeks.
Definition: date.lib.php:972
getWeekNumbersOfMonth($month, $year)
Return array of week numbers.
Definition: date.lib.php:955
getLastDayOfEachWeek($TWeek, $year)
Return array of last day of weeks.
Definition: date.lib.php:988
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...
llxHeader()
Empty header.
Definition: wrapper.php:45
Class to build HTML component for third parties management Only common components are here...
setEventMessages($mesg, $mesgs, $style= 'mesgs', $messagekey= '')
Set event messages in dol_events session object.
Class to manage generation of HTML components Only common components must be here.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage projects.
Class to manage building of HTML components.
dol_get_next_month($month, $year)
Return next month.
Definition: date.lib.php:418
img_picto($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt= '', $morecss= '', $marginleftonlyshort=2)
Show picto whatever it&#39;s its name (generic function)
Classe permettant la generation de composants html autre Only common components are here...
dol_getdate($timestamp, $fast=false, $forcetimezone= '')
Return an array with locale date info.
restrictedArea($user, $features, $objectid=0, $tableandshare= '', $feature2= '', $dbt_keyfield= 'fk_soc', $dbt_select= 'rowid', $isdraft=0)
Check permissions of a user to show a page and an object.
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...
print $_SERVER["PHP_SELF"]
Edit parameters.
img_next($titlealt= 'default', $moreatt= '')
Show next logo.
dol_get_fiche_head($links=array(), $active= '', $title= '', $notab=0, $picto= '', $pictoisfullpath=0, $morehtmlright= '', $morecss= '', $limittoshow=0, $moretabssuffix= '')
Show tabs of a record.
print
Draft customers invoices.
Definition: index.php:89
Class to manage tasks.
Definition: task.class.php:35
img_previous($titlealt= 'default', $moreatt= '')
Show previous logo.
projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask, &$isavailable, $oldprojectforbreak=0, $TWeek=array())
Output a task line into a perday intput mode.
if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) if(!empty($conf->don->enabled)&&$user->rights->don->lire) if(!empty($conf->tax->enabled)&&$user->rights->tax->charges->lire) if(!empty($conf->facture->enabled)&&!empty($conf->commande->enabled)&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1232
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.
project_timesheet_prepare_head($mode, $fuser=null)
Prepare array with list of tabs.
dol_time_plus_duree($time, $duration_value, $duration_unit)
Add a delay to a date.
Definition: date.lib.php:114
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:180
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $keepmoretags= '', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields...