dolibarr  16.0.1
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') {
48  $mine = 1;
49 }
50 
51 $projectid = GETPOSTISSET("id") ? GETPOST("id", "int", 1) : GETPOST("projectid", "int");
52 
53 // Security check
54 $socid = 0;
55 // For external user, no check is done on company because readability is managed by public status of project and assignement.
56 // if ($user->societe_id > 0) $socid=$user->societe_id;
57 $result = restrictedArea($user, 'projet', $projectid);
58 
59 $now = dol_now();
60 
61 $year = GETPOST('reyear') ?GETPOST('reyear', 'int') : (GETPOST("year") ?GETPOST("year", "int") : date("Y"));
62 $month = GETPOST('remonth') ?GETPOST('remonth', 'int') : (GETPOST("month") ?GETPOST("month", "int") : date("m"));
63 $day = GETPOST('reday') ?GETPOST('reday', 'int') : (GETPOST("day") ?GETPOST("day", "int") : date("d"));
64 $day = (int) $day;
65 $week = GETPOST("week", "int") ?GETPOST("week", "int") : date("W");
66 
67 //$search_categ = GETPOST("search_categ", 'alpha');
68 $search_usertoprocessid = GETPOST('search_usertoprocessid', 'int');
69 $search_task_ref = GETPOST('search_task_ref', 'alpha');
70 $search_task_label = GETPOST('search_task_label', 'alpha');
71 $search_project_ref = GETPOST('search_project_ref', 'alpha');
72 $search_thirdparty = GETPOST('search_thirdparty', 'alpha');
73 $search_declared_progress = GETPOST('search_declared_progress', 'alpha');
74 
75 $startdayarray = dol_get_prev_month($month, $year);
76 
77 $prev = $startdayarray;
78 $prev_year = $prev['year'];
79 $prev_month = $prev['month'];
80 $prev_day = 1;
81 
82 $next = dol_get_next_month($month, $year);
83 $next_year = $next['year'];
84 $next_month = $next['month'];
85 $next_day = 1;
86 $TWeek = getWeekNumbersOfMonth($month, $year);
87 $firstdaytoshow = dol_mktime(0, 0, 0, $month, 1, $year);
88 $TFirstDays = getFirstDayOfEachWeek($TWeek, $year);
89 $TFirstDays[reset($TWeek)] = '01'; //first day of month
90 $TLastDays = getLastDayOfEachWeek($TWeek, $year);
91 $TLastDays[end($TWeek)] = date("t", strtotime($year.'-'.$month.'-'.$day)); //last day of month
92 if (empty($search_usertoprocessid) || $search_usertoprocessid == $user->id) {
93  $usertoprocess = $user;
94  $search_usertoprocessid = $usertoprocess->id;
95 } elseif ($search_usertoprocessid > 0) {
96  $usertoprocess = new User($db);
97  $usertoprocess->fetch($search_usertoprocessid);
98  $search_usertoprocessid = $usertoprocess->id;
99 } else {
100  $usertoprocess = new User($db);
101 }
102 
103 $object = new Task($db);
104 
105 
106 /*
107  * Actions
108  */
109 $parameters = array('id' => $id, 'taskid' => $taskid, 'projectid' => $projectid, 'TWeek' => $TWeek, 'TFirstDays' => $TFirstDays, 'TLastDays' => $TLastDays);
110 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
111 if ($reshook < 0) {
112  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
113 }
114 
115 // Purge criteria
116 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
117  $action = '';
118  //$search_categ = '';
119  $search_usertoprocessid = $user->id;
120  $search_task_ref = '';
121  $search_task_label = '';
122  $search_project_ref = '';
123  $search_thirdparty = '';
124  $search_declared_progress = '';
125 }
126 if (GETPOST("button_search_x", 'alpha') || GETPOST("button_search.x", 'alpha') || GETPOST("button_search", 'alpha')) {
127  $action = '';
128 }
129 
130 if (GETPOST('submitdateselect')) {
131  $daytoparse = dol_mktime(0, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
132 
133  $action = '';
134 }
135 if ($action == 'addtime' && $user->rights->projet->lire && GETPOST('assigntask')) {
136  $action = 'assigntask';
137 
138  if ($taskid > 0) {
139  $result = $object->fetch($taskid, $ref);
140  if ($result < 0) {
141  $error++;
142  }
143  } else {
144  setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Task")), '', 'errors');
145  $error++;
146  }
147  if (!GETPOST('type')) {
148  setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), '', 'errors');
149  $error++;
150  }
151 
152  if (!$error) {
153  $idfortaskuser = $usertoprocess->id;
154  $result = $object->add_contact($idfortaskuser, GETPOST("type"), 'internal');
155 
156  if ($result >= 0 || $result == -2) { // Contact add ok or already contact of task
157  // 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)
158  $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';
159  $sql .= ' AND ec.fk_socpeople = '.((int) $idfortaskuser)." AND ec.element_id = ".((int) $object->fk_project)." AND tc.element = 'project' AND source = 'internal'";
160  $resql = $db->query($sql);
161  if ($resql) {
162  $obj = $db->fetch_object($resql);
163  if (!$obj) { // User is not already linked to project, so we will create link to first type
164  $project = new Project($db);
165  $project->fetch($object->fk_project);
166  // Get type
167  $listofprojcontact = $project->liste_type_contact('internal');
168 
169  if (count($listofprojcontact)) {
170  $typeforprojectcontact = reset(array_keys($listofprojcontact));
171  $result = $project->add_contact($idfortaskuser, $typeforprojectcontact, 'internal');
172  }
173  }
174  } else {
175  dol_print_error($db);
176  }
177  }
178  }
179 
180  if ($result < 0) {
181  $error++;
182  if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
183  $langs->load("errors");
184  setEventMessages($langs->trans("ErrorTaskAlreadyAssigned"), null, 'warnings');
185  } else {
186  setEventMessages($object->error, $object->errors, 'errors');
187  }
188  }
189 
190  if (!$error) {
191  setEventMessages("TaskAssignedToEnterTime", null);
192  $taskid = 0;
193  }
194 
195  $action = '';
196 }
197 
198 if ($action == 'addtime' && $user->rights->projet->lire) {
199  $timetoadd = GETPOST('task');
200  if (empty($timetoadd)) {
201  setEventMessages($langs->trans("ErrorTimeSpentIsEmpty"), null, 'errors');
202  } else {
203  foreach ($timetoadd as $taskid => $value) { // Loop on each task
204  $updateoftaskdone = 0;
205  foreach ($value as $key => $val) { // Loop on each day
206  $amountoadd = $timetoadd[$taskid][$key];
207  if (!empty($amountoadd)) {
208  $tmpduration = explode(':', $amountoadd);
209  $newduration = 0;
210  if (!empty($tmpduration[0])) {
211  $newduration += ($tmpduration[0] * 3600);
212  }
213  if (!empty($tmpduration[1])) {
214  $newduration += ($tmpduration[1] * 60);
215  }
216  if (!empty($tmpduration[2])) {
217  $newduration += ($tmpduration[2]);
218  }
219 
220  if ($newduration > 0) {
221  $object->fetch($taskid);
222  $object->progress = GETPOST($taskid.'progress', 'int');
223  $object->timespent_duration = $newduration;
224  $object->timespent_fk_user = $usertoprocess->id;
225  $object->timespent_date = dol_time_plus_duree($firstdaytoshow, $key, 'd');
226  $object->timespent_datehour = $object->timespent_date;
227 
228  $result = $object->addTimeSpent($user);
229  if ($result < 0) {
230  setEventMessages($object->error, $object->errors, 'errors');
231  $error++;
232  break;
233  }
234 
235  $updateoftaskdone++;
236  }
237  }
238  }
239 
240  if (!$updateoftaskdone) { // Check to update progress if no update were done on task.
241  $object->fetch($taskid);
242  //var_dump($object->progress);
243  //var_dump(GETPOST($taskid . 'progress', 'int')); exit;
244  if ($object->progress != GETPOST($taskid.'progress', 'int')) {
245  $object->progress = GETPOST($taskid.'progress', 'int');
246  $result = $object->update($user);
247  if ($result < 0) {
248  setEventMessages($object->error, $object->errors, 'errors');
249  $error++;
250  break;
251  }
252  }
253  }
254  }
255 
256  if (!$error) {
257  setEventMessages($langs->trans("RecordSaved"), null, 'mesgs');
258 
259  $param = '';
260  $param .= ($mode ? '&mode='.$mode : '');
261  $param .= ($projectid ? 'id='.$projectid : '');
262  $param .= ($search_usertoprocessid ? '&search_usertoprocessid='.$search_usertoprocessid : '');
263  $param .= ($day ? '&day='.$day : '').($month ? '&month='.$month : '').($year ? '&year='.$year : '');
264  $param .= ($search_project_ref ? '&search_project_ref='.$search_project_ref : '');
265  $param .= ($search_usertoprocessid > 0 ? '&search_usertoprocessid='.$search_usertoprocessid : '');
266  $param .= ($search_thirdparty ? '&search_thirdparty='.$search_thirdparty : '');
267  $param .= ($search_declared_progress ? '&search_declared_progress='.$search_declared_progress : '');
268  $param .= ($search_task_ref ? '&search_task_ref='.$search_task_ref : '');
269  $param .= ($search_task_label ? '&search_task_label='.$search_task_label : '');
270 
271  // Redirect to avoid submit twice on back
272  header('Location: '.$_SERVER["PHP_SELF"].'?'.$param);
273  exit;
274  }
275  }
276 }
277 
278 
279 
280 /*
281  * View
282  */
283 
284 $form = new Form($db);
285 $formother = new FormOther($db);
286 $formcompany = new FormCompany($db);
287 $formproject = new FormProjets($db);
288 $projectstatic = new Project($db);
289 $project = new Project($db);
290 $taskstatic = new Task($db);
291 $thirdpartystatic = new Societe($db);
292 $holiday = new Holiday($db);
293 
294 $title = $langs->trans("TimeSpent");
295 
296 $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
297 //var_dump($projectsListId);
298 if ($id) {
299  $project->fetch($id);
300  $project->fetch_thirdparty();
301 }
302 
303 $onlyopenedproject = 1; // or -1
304 $morewherefilter = '';
305 
306 if ($search_project_ref) {
307  $morewherefilter .= natural_search(array("p.ref", "p.title"), $search_project_ref);
308 }
309 if ($search_task_ref) {
310  $morewherefilter .= natural_search("t.ref", $search_task_ref);
311 }
312 if ($search_task_label) {
313  $morewherefilter .= natural_search(array("t.ref", "t.label"), $search_task_label);
314 }
315 if ($search_thirdparty) {
316  $morewherefilter .= natural_search("s.nom", $search_thirdparty);
317 }
318 if ($search_declared_progress) {
319  $morewherefilter .= natural_search("t.progress", $search_declared_progress, 1);
320 }
321 
322 $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.
323 if ($morewherefilter) { // Get all task without any filter, so we can show total of time spent for not visible tasks
324  $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.
325 }
326 $projectsrole = $taskstatic->getUserRolesForProjectsOrTasks($usertoprocess, 0, ($project->id ? $project->id : 0), 0, $onlyopenedproject);
327 $tasksrole = $taskstatic->getUserRolesForProjectsOrTasks(0, $usertoprocess, ($project->id ? $project->id : 0), 0, $onlyopenedproject);
328 //var_dump($tasksarray);
329 //var_dump($projectsrole);
330 //var_dump($taskrole);
331 
332 
333 llxHeader("", $title, "", '', '', '', array('/core/js/timesheet.js'));
334 
335 //print_barre_liste($title, $page, $_SERVER["PHP_SELF"], "", $sortfield, $sortorder, "", $num, '', 'title_project');
336 
337 $param = '';
338 $param .= ($mode ? '&mode='.urlencode($mode) : '');
339 $param .= ($search_project_ref ? '&search_project_ref='.urlencode($search_project_ref) : '');
340 $param .= ($search_usertoprocessid > 0 ? '&search_usertoprocessid='.urlencode($search_usertoprocessid) : '');
341 $param .= ($search_thirdparty ? '&search_thirdparty='.urlencode($search_thirdparty) : '');
342 $param .= ($search_task_ref ? '&search_task_ref='.urlencode($search_task_ref) : '');
343 $param .= ($search_task_label ? '&search_task_label='.urlencode($search_task_label) : '');
344 
345 // Show navigation bar
346 $nav = '<a class="inline-block valignmiddle" href="?year='.$prev_year."&month=".$prev_month."&day=".$prev_day.$param.'">'.img_previous($langs->trans("Previous"))."</a>\n";
347 $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";
348 $nav .= '<a class="inline-block valignmiddle" href="?year='.$next_year."&month=".$next_month."&day=".$next_day.$param.'">'.img_next($langs->trans("Next"))."</a>\n";
349 $nav .= ' '.$form->selectDate(-1, '', 0, 0, 2, "addtime", 1, 1).' ';
350 $nav .= ' <button type="submit" name="button_search_x" value="x" class="bordertransp nobordertransp button_search_x"><span class="fa fa-search"></span></button>';
351 
352 $picto = 'clock';
353 
354 print '<form name="addtime" method="POST" action="'.$_SERVER["PHP_SELF"].'">';
355 print '<input type="hidden" name="token" value="'.newToken().'">';
356 print '<input type="hidden" name="action" value="addtime">';
357 print '<input type="hidden" name="mode" value="'.$mode.'">';
358 print '<input type="hidden" name="day" value="'.$day.'">';
359 print '<input type="hidden" name="month" value="'.$month.'">';
360 print '<input type="hidden" name="year" value="'.$year.'">';
361 
362 $head = project_timesheet_prepare_head($mode, $usertoprocess);
363 print dol_get_fiche_head($head, 'inputpermonth', $langs->trans('TimeSpent'), -1, $picto);
364 
365 // Show description of content
366 print '<div class="hideonsmartphone opacitymedium">';
367 if ($mine || ($usertoprocess->id == $user->id)) {
368  print $langs->trans("MyTasksDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'<br>';
369 } else {
370  if (empty($usertoprocess->id) || $usertoprocess->id < 0) {
371  if ($user->rights->projet->all->lire && !$socid) {
372  print $langs->trans("ProjectsDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'<br>';
373  } else {
374  print $langs->trans("ProjectsPublicTaskDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'<br>';
375  }
376  }
377 }
378 if ($mine || ($usertoprocess->id == $user->id)) {
379  print $langs->trans("OnlyYourTaskAreVisible").'<br>';
380 } else {
381  print $langs->trans("AllTaskVisibleButEditIfYouAreAssigned").'<br>';
382 }
383 print '</div>';
384 
385 print dol_get_fiche_end();
386 
387 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.
388 
389 print '<div class="colorbacktimesheet float valignmiddle">';
390 $titleassigntask = $langs->transnoentities("AssignTaskToMe");
391 if ($usertoprocess->id != $user->id) {
392  $titleassigntask = $langs->transnoentities("AssignTaskToUser", $usertoprocess->getFullName($langs));
393 }
394 print '<div class="taskiddiv inline-block">';
395 print img_picto('', 'projecttask', 'class="pictofixedwidth"');
396 $formproject->selectTasks($socid ? $socid : -1, $taskid, 'taskid', 32, 0, '-- '.$langs->trans("ChooseANotYetAssignedTask").' --', 1);
397 print '</div>';
398 print ' ';
399 print $formcompany->selectTypeContact($object, '', 'type', 'internal', 'rowid', 0, 'maxwidth150onsmartphone');
400 print '<input type="submit" class="button valignmiddle smallonsmartphone" name="assigntask" value="'.dol_escape_htmltag($titleassigntask).'">';
401 print '</div>';
402 
403 print '<div class="clearboth" style="padding-bottom: 20px;"></div>';
404 
405 
406 $moreforfilter = '';
407 
408 // Filter on categories
409 /*
410 if (! empty($conf->categorie->enabled))
411 {
412  require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
413  $moreforfilter.='<div class="divsearchfield">';
414  $moreforfilter.=$langs->trans('ProjectCategories'). ': ';
415  $moreforfilter.=$formother->select_categories('project', $search_categ, 'search_categ', 1, 1, 'maxwidth300');
416  $moreforfilter.='</div>';
417 }*/
418 
419 // If the user can view user other than himself
420 $moreforfilter .= '<div class="divsearchfield">';
421 $moreforfilter .= '<div class="inline-block hideonsmartphone"></div>';
422 $includeonly = 'hierachyme';
423 if (empty($user->rights->user->user->lire)) {
424  $includeonly = array($user->id);
425 }
426 $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');
427 $moreforfilter .= '</div>';
428 
429 if (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)) {
430  $moreforfilter .= '<div class="divsearchfield">';
431  $moreforfilter .= '<div class="inline-block"></div>';
432  $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).'">';
433  $moreforfilter .= '</div>';
434 
435  $moreforfilter .= '<div class="divsearchfield">';
436  $moreforfilter .= '<div class="inline-block"></div>';
437  $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).'">';
438  $moreforfilter .= '</div>';
439 }
440 
441 if (!empty($moreforfilter)) {
442  print '<div class="liste_titre liste_titre_bydiv centpercent">';
443  print $moreforfilter;
444  $parameters = array();
445  $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
446  print $hookmanager->resPrint;
447  print '</div>';
448 }
449 
450 print '<div class="div-table-responsive">';
451 
452 print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'" id="tablelines3">'."\n";
453 
454 print '<tr class="liste_titre_filter">';
455 if (!empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)) {
456  print '<td class="liste_titre"><input type="text" size="4" name="search_project_ref" value="'.dol_escape_htmltag($search_project_ref).'"></td>';
457 }
458 if (!empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)) {
459  print '<td class="liste_titre"><input type="text" size="4" name="search_thirdparty" value="'.dol_escape_htmltag($search_thirdparty).'"></td>';
460 }
461 print '<td class="liste_titre"><input type="text" size="4" name="search_task_label" value="'.dol_escape_htmltag($search_task_label).'"></td>';
462 print '<td class="liste_titre"></td>';
463 print '<td class="liste_titre right"><input type="text" size="4" name="search_declared_progress" value="'.dol_escape_htmltag($search_declared_progress).'"></td>';
464 print '<td class="liste_titre"></td>';
465 print '<td class="liste_titre"></td>';
466 foreach ($TWeek as $week_number) {
467  print '<td class="liste_titre"></td>';
468 }
469 // Action column
470 print '<td class="liste_titre nowrap" align="right">';
471 $searchpicto = $form->showFilterAndCheckAddButtons(0);
472 print $searchpicto;
473 print '</td>';
474 print "</tr>\n";
475 
476 print '<tr class="liste_titre">';
477 if (!empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)) {
478  print '<td>'.$langs->trans("Project").'</td>';
479 }
480 if (!empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)) {
481  print '<td>'.$langs->trans("ThirdParty").'</td>';
482 }
483 print '<td>'.$langs->trans("Task").'</td>';
484 print '<td align="right" class="leftborder plannedworkload maxwidth75">'.$langs->trans("PlannedWorkload").'</td>';
485 print '<td align="right" class="maxwidth75">'.$langs->trans("ProgressDeclared").'</td>';
486 /*print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpent").'</td>';
487  if ($usertoprocess->id == $user->id) print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpentByYou").'</td>';
488  else print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpentByUser").'</td>';*/
489 print '<td class="right maxwidth100">'.$langs->trans("TimeSpent").'<br>';
490 print '<span class="nowraponall">';
491 print '<span class="opacitymedium nopadding userimg"><img alt="Photo" class="photouserphoto userphoto" src="'.DOL_URL_ROOT.'/theme/common/everybody.png"></span>';
492 print '<span class="opacitymedium paddingleft">'.$langs->trans("Everybody").'</span>';
493 print '</span>';
494 print '</td>';
495 print '<td align="right" class="maxwidth75">'.$langs->trans("TimeSpent").($usertoprocess->firstname ? '<br><span class="nowraponall">'.$usertoprocess->getNomUrl(-2).'<span class="opacitymedium paddingleft">'.dol_trunc($usertoprocess->firstname, 10).'</span></span>' : '').'</td>';
496 
497 foreach ($TWeek as $week_number) {
498  print '<td width="6%" align="center" class="bold hide">'.$langs->trans("Week").' '.$week_number.'<br>('.$TFirstDays[$week_number].'...'.$TLastDays[$week_number].')</td>';
499 }
500 print '<td></td>';
501 print "</tr>\n";
502 
503 $colspan = 5;
504 
505 // By default, we can edit only tasks we are assigned to
506 $restrictviewformytask = (empty($conf->global->PROJECT_TIME_SHOW_TASK_NOT_ASSIGNED) ? 1 : 0);
507 
508 // Get if user is available or not for each day
509 $isavailable = array();
510 // TODO See code into perweek.php to initialize isavailable array
511 
512 
513 if (count($tasksarray) > 0) {
514  //var_dump($tasksarray); // contains only selected tasks
515  //var_dump($tasksarraywithoutfilter); // contains all tasks (if there is a filter, not defined if no filter)
516  //var_dump($tasksrole);
517 
518  $j = 0;
519  $level = 0;
520  $totalforvisibletasks = projectLinesPerMonth($j, $firstdaytoshow, $usertoprocess, 0, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask, $isavailable, 0, $TWeek);
521  //var_dump($totalforvisibletasks);
522 
523  // Show total for all other tasks
524 
525  // Calculate total for all tasks
526  $listofdistinctprojectid = array(); // List of all distinct projects
527  if (is_array($tasksarraywithoutfilter) && count($tasksarraywithoutfilter)) {
528  foreach ($tasksarraywithoutfilter as $tmptask) {
529  $listofdistinctprojectid[$tmptask->fk_project] = $tmptask->fk_project;
530  }
531  }
532  //var_dump($listofdistinctprojectid);
533  $totalforeachweek = array();
534  foreach ($listofdistinctprojectid as $tmpprojectid) {
535  $projectstatic->id = $tmpprojectid;
536  $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
537  foreach ($TWeek as $weekNb) {
538  $totalforeachweek[$weekNb] += $projectstatic->monthWorkLoad[$weekNb];
539  }
540  }
541 
542  //var_dump($totalforeachday);
543  //var_dump($totalforvisibletasks);
544 
545  // Is there a diff between selected/filtered tasks and all tasks ?
546  $isdiff = 0;
547  if (count($totalforeachweek)) {
548  foreach ($TWeek as $weekNb) {
549  $timeonothertasks = ($totalforeachweek[$weekNb] - $totalforvisibletasks[$weekNb]);
550  if ($timeonothertasks) {
551  $isdiff = 1;
552  break;
553  }
554  }
555  }
556 
557  // 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
558  if ($isdiff) {
559  print '<tr class="oddeven othertaskwithtime">';
560  print '<td colspan="'.$colspan.'" class="opacitymedium">';
561  print $langs->trans("OtherFilteredTasks");
562  print '</td>';
563  foreach ($TWeek as $weekNb) {
564  print '<td class="center hide">';
565 
566  $timeonothertasks = ($totalforeachweek[$weekNb] - $totalforvisibletasks[$weekNb]);
567  if ($timeonothertasks) {
568  print '<span class="timesheetalreadyrecorded" title="texttoreplace"><input type="text" class="center smallpadd" size="2" disabled="" id="timespent[-1]['.$weekNb.']" name="task[-1]['.$weekNb.']" value="';
569  print convertSecondToTime($timeonothertasks, 'allhourmin');
570  print '"></span>';
571  }
572  print '</td>';
573  }
574  print ' <td class="liste_total"></td>';
575  print '</tr>';
576  }
577 
578  if ($conf->use_javascript_ajax) {
579  print '<tr class="liste_total">
580  <td class="liste_total" colspan="'.$colspan.'">';
581  print $langs->trans("Total");
582  print '<span class="opacitymediumbycolor"> - '.$langs->trans("ExpectedWorkedHours").': <strong>'.price($usertoprocess->weeklyhours, 1, $langs, 0, 0).'</strong></span>';
583  print '</td>';
584 
585  foreach ($TWeek as $weekNb) {
586  print '<td class="liste_total hide'.$weekNb.'" align="center"><div class="totalDay'.$weekNb.'">'.convertSecondToTime($totalforvisibletasks[$weekNb], 'allhourmin').'</div></td>';
587  }
588  print '<td class="liste_total center"><div class="totalDayAll">&nbsp;</div></td>
589  </tr>';
590  }
591 } else {
592  print '<tr><td colspan="15"><span class="opacitymedium">'.$langs->trans("NoAssignedTasks").'</span></td></tr>';
593 }
594 print "</table>";
595 print '</div>';
596 
597 print '<input type="hidden" id="numberOfLines" name="numberOfLines" value="'.count($tasksarray).'"/>'."\n";
598 print '<input type="hidden" id="numberOfFirstLine" name="numberOfFirstLine" value="'.(reset($TWeek)).'"/>'."\n";
599 
600 print $form->buttonsSaveCancel("Save", '');
601 
602 print '</form>'."\n\n";
603 
604 $modeinput = 'hours';
605 
606 if ($conf->use_javascript_ajax) {
607  print "\n<!-- JS CODE TO ENABLE Tooltips on all object with class classfortooltip -->\n";
608  print '<script type="text/javascript">'."\n";
609  print "jQuery(document).ready(function () {\n";
610  print ' jQuery(".timesheetalreadyrecorded").tooltip({
611  show: { collision: "flipfit", effect:\'toggle\', delay:50 },
612  hide: { effect:\'toggle\', delay: 50 },
613  tooltipClass: "mytooltip",
614  content: function () {
615  return \''.dol_escape_js($langs->trans("TimeAlreadyRecorded", $usertoprocess->getFullName($langs))).'\';
616  }
617  });'."\n";
618 
619  foreach ($TWeek as $week_number) {
620  print ' updateTotal('.$week_number.',\''.$modeinput.'\');';
621  }
622  print "\n});\n";
623  print '</script>';
624 }
625 
626 
627 llxFooter();
628 
629 $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.
if($cancel &&!$id) if($action== 'add'&&!$cancel) if($action== 'delete') if($id) $form
Actions.
Definition: card.php:142
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:470
dol_now($mode= 'auto')
Return date for now.
Class to manage Dolibarr users.
Definition: user.class.php:44
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOCSRFCHECK')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:59
getFirstDayOfEachWeek($TWeek, $year)
Return array of first day of weeks.
Definition: date.lib.php:1099
getWeekNumbersOfMonth($month, $year)
Return array of week numbers.
Definition: date.lib.php:1082
getLastDayOfEachWeek($TWeek, $year)
Return array of last day of weeks.
Definition: date.lib.php:1117
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_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
Definition: date.lib.php:121
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...
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.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form...
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:489
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...
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...
restrictedArea($user, $features, $objectid=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.
if(isModEnabled('facture')&&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur')&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)&&$user->rights->fournisseur->facture->lire)||(isModEnabled('supplier_invoice')&&$user->rights->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->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:742
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.
Class to manage tasks.
Definition: task.class.php:37
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.
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.
dol_trunc($string, $size=40, $trunc= 'right', $stringencoding= 'UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding &#39;…&#39; if string larger than length. ...
project_timesheet_prepare_head($mode, $fuser=null)
Prepare array with list of tabs.
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:236