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