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