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