dolibarr 24.0.0-beta
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 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
7 * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
8 * Copyright (C) 2025 Alexandre Spangaro <alexandre@inovea-conseil.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
30require "../../main.inc.php";
39require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
40require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
41require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
42require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
43require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
44require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
45require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
46require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php';
47
48// Load translation files required by the page
49$langs->loadLangs(array('projects', 'users', 'companies'));
50
51$action = GETPOST('action', 'aZ09');
52$mode = GETPOST("mode", 'alpha');
53$id = GETPOSTINT('id');
54$taskid = GETPOSTINT('taskid');
55
56$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'timespent';
57
58$mine = 0;
59if ($mode == 'mine') {
60 $mine = 1;
61}
62
63$projectid = GETPOSTISSET("id") ? GETPOSTINT("id", 1) : GETPOSTINT("projectid");
64
65$hookmanager->initHooks(array('timesheetpermonthcard'));
66
67// Security check
68$socid = 0;
69// For external user, no check is done on company because readability is managed by public status of project and assignment.
70// if ($user->socid > 0) $socid=$user->socid;
71$result = restrictedArea($user, 'projet', $projectid);
72
73$now = dol_now();
74
75$year = GETPOSTINT('reyear') ? GETPOSTINT('reyear') : (GETPOSTINT("year") ? GETPOSTINT("year") : date("Y"));
76$month = GETPOSTINT('remonth') ? GETPOSTINT('remonth') : (GETPOSTINT("month") ? GETPOSTINT("month") : date("m"));
77$day = GETPOSTINT('reday') ? GETPOSTINT('reday') : (GETPOSTINT("day") ? GETPOSTINT("day") : date("d"));
78$week = GETPOSTINT("week") ? GETPOSTINT("week") : date("W");
79
80$day = (int) $day;
81
82//$search_categ = GETPOST("search_categ", 'alpha');
83$search_usertoprocessid = GETPOSTINT('search_usertoprocessid');
84$search_task_ref = GETPOST('search_task_ref', 'alpha');
85$search_task_label = GETPOST('search_task_label', 'alpha');
86$search_project_ref = GETPOST('search_project_ref', 'alpha');
87$search_thirdparty = GETPOST('search_thirdparty', 'alpha');
88$search_declared_progress = GETPOST('search_declared_progress', 'alpha');
89
90$sortfield = GETPOST('sortfield', 'aZ09comma');
91$sortorder = GETPOST('sortorder', 'aZ09comma');
92
93$startdayarray = dol_get_prev_month($month, $year);
94
95$prev = $startdayarray;
96$prev_year = $prev['year'];
97$prev_month = $prev['month'];
98$prev_day = 1;
99
100$next = dol_get_next_month($month, $year);
101$next_year = $next['year'];
102$next_month = $next['month'];
103$next_day = 1;
104$TWeek = getWeekNumbersOfMonth($month, $year);
105$firstdaytoshow = dol_mktime(0, 0, 0, $month, 1, $year);
106$TFirstDays = getFirstDayOfEachWeek($TWeek, $year);
107$TFirstDays[reset($TWeek)] = '01'; //first day of month
108$TLastDays = getLastDayOfEachWeek($TWeek, $year);
109$TLastDays[end($TWeek)] = date("t", strtotime($year.'-'.$month.'-'.$day)); //last day of month
110if (empty($search_usertoprocessid) || $search_usertoprocessid == $user->id) {
111 $usertoprocess = $user;
112 $search_usertoprocessid = $usertoprocess->id;
113} elseif ($search_usertoprocessid > 0) {
114 $usertoprocess = new User($db);
115 $usertoprocess->fetch($search_usertoprocessid);
116 $search_usertoprocessid = $usertoprocess->id;
117} else {
118 $usertoprocess = new User($db);
119}
120
121$object = new Task($db);
122
123// Extra fields
124$extrafields = new ExtraFields($db);
125
126// fetch optionals attributes and labels
127$extrafields->fetch_name_optionals_label($object->table_element);
128
129// Definition of fields for list
130$arrayfields = array();
131/*$arrayfields=array(
132 // Project
133 'p.opp_amount'=>array('label'=>$langs->trans("OpportunityAmountShort"), 'checked'=>0, 'enabled'=>($conf->global->PROJECT_USE_OPPORTUNITIES?1:0), 'position'=>103),
134 'p.fk_opp_status'=>array('label'=>$langs->trans("OpportunityStatusShort"), 'checked'=>0, 'enabled'=>($conf->global->PROJECT_USE_OPPORTUNITIES?1:0), 'position'=>104),
135 'p.opp_percent'=>array('label'=>$langs->trans("OpportunityProbabilityShort"), 'checked'=>0, 'enabled'=>($conf->global->PROJECT_USE_OPPORTUNITIES?1:0), 'position'=>105),
136 'p.budget_amount'=>array('label'=>$langs->trans("Budget"), 'checked'=>0, 'position'=>110),
137 'p.usage_bill_time'=>array('label'=>$langs->trans("BillTimeShort"), 'checked'=>0, 'position'=>115),
138 );*/
139$arrayfields['t.planned_workload'] = array('label' => 'PlannedWorkload', 'checked' => '1', 'enabled' => '1', 'position' => 5);
140$arrayfields['t.progress'] = array('label' => 'ProgressDeclared', 'checked' => '1', 'enabled' => '1', 'position' => 10);
141$arrayfields['timeconsumed'] = array('label' => 'TimeConsumed', 'checked' => '1', 'enabled' => '1', 'position' => 15);
142/*foreach($object->fields as $key => $val)
143 {
144 // If $val['visible']==0, then we never show the field
145 if (!empty($val['visible'])) $arrayfields['t.'.$key]=array('label'=>$val['label'], 'checked'=>(($val['visible']<0)?0:1), 'enabled'=>$val['enabled'], 'position'=>$val['position']);
146 }*/
147// Extra fields
148$extrafieldsobjectkey = 'projet_task';
149$extrafieldsobjectprefix = 'efpt.';
150include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
151
152$arrayfields = dol_sort_array($arrayfields, 'position');
153
154$search_array_options = array();
155$search_array_options_project = $extrafields->getOptionalsFromPost('projet', '', 'search_');
156$search_array_options_task = $extrafields->getOptionalsFromPost('projet_task', '', 'search_task_');
157
158$error = 0;
159
160
161/*
162 * Actions
163 */
164
165$parameters = array('id' => $id, 'taskid' => $taskid, 'projectid' => $projectid, 'TWeek' => $TWeek, 'TFirstDays' => $TFirstDays, 'TLastDays' => $TLastDays);
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
171// Purge criteria
172if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
173 $action = '';
174 //$search_categ = '';
175 $search_usertoprocessid = $user->id;
176 $search_task_ref = '';
177 $search_task_label = '';
178 $search_project_ref = '';
179 $search_thirdparty = '';
180 $search_declared_progress = '';
181
182 $search_array_options_project = array();
183 $search_array_options_task = array();
184
185 // We redefine $usertoprocess
186 $usertoprocess = $user;
187}
188if (GETPOST("button_search_x", 'alpha') || GETPOST("button_search.x", 'alpha') || GETPOST("button_search", 'alpha')) {
189 $action = '';
190}
191
192if (GETPOST('submitdateselect')) {
193 if (GETPOSTINT('remonth') && GETPOSTINT('reday') && GETPOSTINT('reyear')) {
194 $daytoparse = dol_mktime(0, 0, 0, GETPOSTINT('remonth'), GETPOSTINT('reday'), GETPOSTINT('reyear'));
195 }
196
197 $action = '';
198}
199
200include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
201
202if ($action == 'addtime' && $user->hasRight('projet', 'lire') && GETPOST('assigntask') && GETPOST('formfilteraction') != 'listafterchangingselectedfields') {
203 $action = 'assigntask';
204
205 if ($taskid > 0) {
206 $result = $object->fetch($taskid);
207 if ($result < 0) {
208 $error++;
209 }
210 } else {
211 setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Task")), null, 'errors');
212 $error++;
213 }
214 if (!GETPOST('type')) {
215 setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")), null, 'errors');
216 $error++;
217 }
218
219 if (!$error) {
220 $idfortaskuser = $usertoprocess->id;
221 $result = $object->add_contact($idfortaskuser, GETPOST("type"), 'internal');
222
223 if ($result >= 0 || $result == -2) { // Contact add ok or already contact of task
224 // 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)
225 $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';
226 $sql .= ' AND ec.fk_socpeople = '.((int) $idfortaskuser)." AND ec.element_id = ".((int) $object->fk_project)." AND tc.element = 'project' AND source = 'internal'";
227 $resql = $db->query($sql);
228 if ($resql) {
229 $obj = $db->fetch_object($resql);
230 if (!$obj) { // User is not already linked to project, so we will create link to first type
231 $project = new Project($db);
232 $project->fetch($object->fk_project);
233 // Get type
234 $listofprojcontact = $project->liste_type_contact('internal');
235
236 if (count($listofprojcontact)) {
237 $tmparray = array_keys($listofprojcontact);
238 $typeforprojectcontact = reset($tmparray);
239 $result = $project->add_contact($idfortaskuser, $typeforprojectcontact, 'internal');
240 }
241 }
242 } else {
244 }
245 }
246 }
247
248 if ($result < 0) {
249 $error++;
250 if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
251 $langs->load("errors");
252 setEventMessages($langs->trans("ErrorTaskAlreadyAssigned"), null, 'warnings');
253 } else {
254 setEventMessages($object->error, $object->errors, 'errors');
255 }
256 }
257
258 if (!$error) {
259 setEventMessages("TaskAssignedToEnterTime", null);
260 $taskid = 0;
261 }
262
263 $action = '';
264}
265
266if ($action == 'addtime' && $user->hasRight('projet', 'lire') && GETPOST('formfilteraction') != 'listafterchangingselectedfields') {
267 $timetoadd = GETPOST('task');
268 if (empty($timetoadd)) {
269 setEventMessages($langs->trans("ErrorTimeSpentIsEmpty"), null, 'errors');
270 } else {
271 foreach ($timetoadd as $tmptaskid => $tmpvalue) { // Loop on each task
272 $updateoftaskdone = 0;
273 foreach ($tmpvalue as $key => $val) { // Loop on each day
274 $amountoadd = $timetoadd[$tmptaskid][$key];
275 if (!empty($amountoadd)) {
276 $tmpduration = explode(':', $amountoadd);
277 $newduration = 0;
278 if (!empty($tmpduration[0])) {
279 $newduration += (int) ((float) $tmpduration[0] * 3600);
280 }
281 if (!empty($tmpduration[1])) {
282 $newduration += (int) ((float) $tmpduration[1] * 60);
283 }
284 if (!empty($tmpduration[2])) {
285 $newduration += ((int) $tmpduration[2]);
286 }
287
288 if ($newduration > 0) {
289 $object->fetch($tmptaskid);
290
291 if (GETPOSTISSET($tmptaskid.'progress')) {
292 $object->progress = GETPOSTINT($tmptaskid.'progress');
293 } else {
294 unset($object->progress);
295 }
296
297 $object->timespent_duration = $newduration;
298 $object->timespent_fk_user = $usertoprocess->id;
299 $object->timespent_date = dol_time_plus_duree($firstdaytoshow, $key, 'd');
300 $object->timespent_datehour = $object->timespent_date;
301 $object->timespent_note = $object->description;
302
303 $result = $object->addTimeSpent($user);
304 if ($result < 0) {
305 setEventMessages($object->error, $object->errors, 'errors');
306 $error++;
307 break;
308 }
309
310 $updateoftaskdone++;
311 }
312 }
313 }
314
315 if (!$updateoftaskdone) { // Check to update progress if no update were done on task.
316 $object->fetch($tmptaskid);
317 //var_dump($object->progress);
318 //var_dump(GETPOST($tmptaskid . 'progress', 'int')); exit;
319 if ($object->progress != GETPOSTINT($tmptaskid.'progress')) {
320 $object->progress = GETPOSTINT($tmptaskid.'progress');
321 $result = $object->update($user);
322 if ($result < 0) {
323 setEventMessages($object->error, $object->errors, 'errors');
324 $error++;
325 break;
326 }
327 }
328 }
329 }
330
331 if (!$error) {
332 setEventMessages($langs->trans("RecordSaved"), null, 'mesgs');
333
334 $param = '';
335 $param .= ($mode ? '&mode='.urlencode($mode) : '');
336 $param .= ($projectid ? 'id='.urlencode((string) ($projectid)) : '');
337 $param .= ($search_usertoprocessid ? '&search_usertoprocessid='.urlencode((string) $search_usertoprocessid) : '');
338 $param .= ($day ? '&day='.urlencode((string) ($day)) : '').($month ? '&month='.urlencode((string) ($month)) : '').($year ? '&year='.urlencode((string) ($year)) : '');
339 $param .= ($search_project_ref ? '&search_project_ref='.urlencode($search_project_ref) : '');
340 $param .= ($search_usertoprocessid > 0 ? '&search_usertoprocessid='.urlencode((string) $search_usertoprocessid) : '');
341 $param .= ($search_thirdparty ? '&search_thirdparty='.urlencode($search_thirdparty) : '');
342 $param .= ($search_declared_progress ? '&search_declared_progress='.urlencode($search_declared_progress) : '');
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 /*$search_array_options=$search_array_options_project;
347 $search_options_pattern='search_options_';
348 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
349 */
350
351 $search_array_options = $search_array_options_task;
352 $search_options_pattern = 'search_task_options_';
353 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
354
355 // Redirect to avoid submit twice on back
356 header('Location: '.$_SERVER["PHP_SELF"].'?'.$param);
357 exit;
358 }
359 }
360}
361
362
363
364/*
365 * View
366 */
367
368$form = new Form($db);
369$formother = new FormOther($db);
370$formcompany = new FormCompany($db);
371$formproject = new FormProjets($db);
372$projectstatic = new Project($db);
373$project = new Project($db);
374$taskstatic = new Task($db);
375$thirdpartystatic = new Societe($db);
376$holiday = new Holiday($db);
377
378$title = $langs->trans("TimeSpent");
379
380$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
381//var_dump($projectsListId);
382if ($id) {
383 $project->fetch($id);
384 $project->fetch_thirdparty();
385}
386
387$onlyopenedproject = 1; // or -1
388$morewherefilter = '';
389
390if ($search_project_ref) {
391 $morewherefilter .= natural_search(array("p.ref", "p.title"), $search_project_ref);
392}
393if ($search_task_ref) {
394 $morewherefilter .= natural_search("t.ref", $search_task_ref);
395}
396if ($search_task_label) {
397 $morewherefilter .= natural_search(array("t.ref", "t.label"), $search_task_label);
398}
399if ($search_thirdparty) {
400 $morewherefilter .= natural_search("s.nom", $search_thirdparty);
401}
402if ($search_declared_progress) {
403 $morewherefilter .= natural_search("t.progress", $search_declared_progress, 1);
404}
405
406$sql = &$morewherefilter;
407
408/*$search_array_options = $search_array_options_project;
409 $extrafieldsobjectprefix='efp.';
410 $search_options_pattern='search_options_';
411 $extrafieldsobjectkey='projet';
412 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
413 */
414$search_array_options = $search_array_options_task;
415$extrafieldsobjectprefix = 'efpt.';
416$search_options_pattern = 'search_task_options_';
417$extrafieldsobjectkey = 'projet_task';
418include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
419
420$tasksarraywithoutfilter = array(); // Default
421
422$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 tasks of open project i am allowed to see and that match filter, not only my tasks. Later only mine will be editable later.
423if ($morewherefilter) { // Get all task without any filter, so we can show total of time spent for not visible tasks
424 $tasksarraywithoutfilter = $taskstatic->getTasksArray(null, null, ($project->id ? $project->id : 0), $socid, 0, '', (string) $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.
425}
426$projectsrole = $taskstatic->getUserRolesForProjectsOrTasks($usertoprocess, null, ($project->id ? (string) $project->id : '0'), 0, $onlyopenedproject);
427$tasksrole = $taskstatic->getUserRolesForProjectsOrTasks(null, $usertoprocess, ($project->id ? (string) $project->id : '0'), 0, $onlyopenedproject);
428//var_dump($tasksarray);
429//var_dump($projectsrole);
430//var_dump($taskrole);
431
432
433llxHeader('', $title, '', '', 0, 0, array('/core/js/timesheet.js'), '', '', 'mod-project project-activity page-activity_permonth');
434
435//print_barre_liste($title, $page, $_SERVER["PHP_SELF"], "", $sortfield, $sortorder, "", $num, '', 'project');
436
437$param = '';
438$param .= ($mode ? '&mode='.urlencode($mode) : '');
439$param .= ($search_project_ref ? '&search_project_ref='.urlencode($search_project_ref) : '');
440$param .= ($search_usertoprocessid > 0 ? '&search_usertoprocessid='.urlencode((string) $search_usertoprocessid) : '');
441$param .= ($search_thirdparty ? '&search_thirdparty='.urlencode($search_thirdparty) : '');
442$param .= ($search_task_ref ? '&search_task_ref='.urlencode($search_task_ref) : '');
443$param .= ($search_task_label ? '&search_task_label='.urlencode($search_task_label) : '');
444
445$search_array_options = $search_array_options_project;
446$search_options_pattern = 'search_options_';
447include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
448
449$search_array_options = $search_array_options_task;
450$search_options_pattern = 'search_task_options_';
451include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
452
453// Show navigation bar
454$nav = '<a class="inline-block valignmiddle" href="?year='.$prev_year."&month=".$prev_month."&day=".$prev_day.$param.'">'.img_previous($langs->trans("Previous"))."</a>\n";
455$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";
456$nav .= '<a class="inline-block valignmiddle" href="?year='.$next_year."&month=".$next_month."&day=".$next_day.$param.'">'.img_next($langs->trans("Next"))."</a>\n";
457$nav .= ' '.$form->selectDate(-1, '', 0, 0, 2, "addtime", 1, ($conf->dol_optimize_smallscreen ? 0 : 1)).' ';
458$nav .= ' <button type="submit" name="submitdateselect" value="x" class="bordertransp nobordertransp button_search_x"><span class="fa fa-search"></span></button>';
459
460$picto = 'clock';
461
462print '<form name="addtime" method="POST" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
463print '<input type="hidden" name="token" value="'.newToken().'">';
464print '<input type="hidden" name="action" value="addtime">';
465print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
466print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
467print '<input type="hidden" name="mode" value="'.$mode.'">';
468print '<input type="hidden" name="day" value="'.$day.'">';
469print '<input type="hidden" name="month" value="'.$month.'">';
470print '<input type="hidden" name="year" value="'.$year.'">';
471
472$head = project_timesheet_prepare_head($mode, $usertoprocess);
473print dol_get_fiche_head($head, 'inputpermonth', $langs->trans('TimeSpent'), -1, $picto);
474
475// Show description of content
476$s = '';
477if ($mine || ($usertoprocess->id == $user->id)) {
478 $s .= $langs->trans("MyTasksDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'<br>';
479} else {
480 if (empty($usertoprocess->id) || $usertoprocess->id < 0) {
481 if ($user->hasRight('projet', 'all', 'lire') && !$socid) {
482 $s .= $langs->trans("ProjectsDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'<br>';
483 } else {
484 $s .= $langs->trans("ProjectsPublicTaskDesc").'.'.($onlyopenedproject ? ' '.$langs->trans("OnlyOpenedProject") : '').'<br>';
485 }
486 }
487}
488if ($mine || ($usertoprocess->id == $user->id)) {
489 $s .= $langs->trans("OnlyYourTaskAreVisible");
490} else {
491 $s .= $langs->trans("AllTaskVisibleButEditIfYouAreAssigned");
492}
493print info_admin($s, 0, 0, 'info', 'nomargintop nomarginbottom hideonsmartphone');
494
495print dol_get_fiche_end();
496
497print '<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.
498
499print '<div class="colorbacktimesheet valignmiddle'.($conf->dol_optimize_smallscreen ? ' center' : ' float').'">';
500$titleassigntask = $langs->transnoentities("AssignTaskToMe");
501if ($usertoprocess->id != $user->id) {
502 $titleassigntask = $langs->transnoentities("AssignTaskToUser", $usertoprocess->getFullName($langs));
503}
504print '<div class="taskiddiv inline-block">';
505print img_picto('', 'projecttask', 'class="pictofixedwidth"');
506$formproject->selectTasks($socid ? $socid : -1, $taskid, 'taskid', 32, 0, '-- '.$langs->trans("ChooseANotYetAssignedTask").' --', 1, 0, 0, 'widthcentpercentminusx maxwidth500', '', 'all', $usertoprocess);
507print '</div>';
508print ' ';
509print $formcompany->selectTypeContact($object, '', 'type', 'internal', 'position', 0, 'maxwidth150onsmartphone');
510print '<input type="submit" class="button valignmiddle smallonsmartphone small" name="assigntask" value="'.dol_escape_htmltag($titleassigntask).'">';
511print '</div>';
512
513print '<div class="clearboth" style="padding-bottom: 20px;"></div>';
514
515
516$moreforfilter = '';
517
518// Filter on categories
519/*
520if (isModEnabled("categorie")) {
521 require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
522 $moreforfilter.='<div class="divsearchfield">';
523 $moreforfilter.=$langs->trans('ProjectCategories'). ': ';
524 $moreforfilter.=$formother->select_categories('project', $search_categ, 'search_categ', 1, 1, 'maxwidth300');
525 $moreforfilter.='</div>';
526}*/
527
528// If the user can view user other than himself
529$includeonly = 'hierarchyme';
530if (!$user->hasRight('user', 'user', 'lire')) {
531 $includeonly = array($user->id);
532}
533$selecteduser = $search_usertoprocessid ? $search_usertoprocessid : $usertoprocess->id;
534$moreforfiltertmp = $form->select_dolusers($selecteduser, 'search_usertoprocessid', 0, null, 0, $includeonly, array(), '0', 0, 0, '', 0, '', 'maxwidth200');
535if ($form->num > 1 || empty($conf->dol_optimize_smallscreen)) {
536 $moreforfilter .= '<div class="divsearchfield">';
537 $moreforfilter .= '<div class="inline-block hideonsmartphone"></div>';
538 $moreforfilter .= img_picto($langs->trans('Filter').' '.$langs->trans('User'), 'user', 'class="paddingright pictofixedwidth"');
539 $moreforfilter .= $moreforfiltertmp;
540 $moreforfilter .= '</div>';
541} else {
542 $moreforfilter .= '<input type="hidden" name="search_usertoprocessid" value="'.$selecteduser.'">';
543}
544
545if (!getDolGlobalString('PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT')) {
546 $moreforfilter .= '<div class="divsearchfield">';
547 $moreforfilter .= '<div class="inline-block"></div>';
548 $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">';
549 $moreforfilter .= '</div>';
550
551 $moreforfilter .= '<div class="divsearchfield">';
552 $moreforfilter .= '<div class="inline-block"></div>';
553 $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">';
554 $moreforfilter .= '</div>';
555}
556
557if (!empty($moreforfilter)) {
558 print '<div class="liste_titre liste_titre_bydiv centpercent">';
559 print $moreforfilter;
560 $parameters = array();
561 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
562 print $hookmanager->resPrint;
563 print '</div>';
564}
565
566$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
567
568$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
569
570// This must be after the $selectedfields
571$addcolspan = 0;
572if (!empty($arrayfields['t.planned_workload']['checked'])) {
573 $addcolspan++;
574}
575if (!empty($arrayfields['t.progress']['checked'])) {
576 $addcolspan++;
577}
578foreach ($arrayfields as $key => $val) {
579 if ($val['checked'] && substr($key, 0, 5) == 'efpt.') {
580 $addcolspan++;
581 }
582}
583
584print '<div class="div-table-responsive">';
585
586print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'" id="tablelines3">'."\n";
587
588print '<tr class="liste_titre_filter">';
589if (getDolGlobalString('PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT')) {
590 print '<td class="liste_titre"><input type="text" class="maxwidth75" name="search_project_ref" value="'.dol_escape_htmltag($search_project_ref).'"></td>';
591}
592if (getDolGlobalString('PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT')) {
593 print '<td class="liste_titre"><input type="text" class="maxwidth75" name="search_thirdparty" value="'.dol_escape_htmltag($search_thirdparty).'"></td>';
594}
595print '<td class="liste_titre"><input type="text" class="maxwidth75" name="search_task_label" value="'.dol_escape_htmltag($search_task_label).'"></td>';
596// TASK fields
597$search_options_pattern = 'search_task_options_';
598$extrafieldsobjectkey = 'projet_task';
599$extrafieldsobjectprefix = 'efpt.';
600include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php';
601if (!empty($arrayfields['t.planned_workload']['checked'])) {
602 print '<td class="liste_titre"></td>';
603}
604if (!empty($arrayfields['t.progress']['checked'])) {
605 print '<td class="liste_titre right"><input type="text" class="width50" name="search_declared_progress" value="'.dol_escape_htmltag($search_declared_progress).'"></td>';
606}
607if (!empty($arrayfields['timeconsumed']['checked'])) {
608 print '<td class="liste_titre"></td>';
609 print '<td class="liste_titre"></td>';
610}
611foreach ($TWeek as $week_number) {
612 print '<td class="liste_titre"></td>';
613}
614// Action column
615print '<td class="liste_titre nowrap right">';
616$searchpicto = $form->showFilterAndCheckAddButtons(0);
617print $searchpicto;
618print '</td>';
619print "</tr>\n";
620
621print '<tr class="liste_titre">';
622if (getDolGlobalString('PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT')) {
623 print '<th>'.$langs->trans("Project").'</th>';
624}
625if (getDolGlobalString('PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT')) {
626 print '<th>'.$langs->trans("ThirdParty").'</th>';
627}
628print '<th>'.$langs->trans("Task").'</th>';
629
630// TASK fields
631$extrafieldsobjectkey = 'projet_task';
632$extrafieldsobjectprefix = 'efpt.';
633include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php';
634
635if (!empty($arrayfields['t.planned_workload']['checked'])) {
636 print '<th class="leftborder plannedworkload maxwidth75 maxwidth100 right">'.$form->textwithpicto($langs->trans("PlannedWorkloadShort"), $langs->trans("PlannedWorkload")).'</th>';
637}
638if (!empty($arrayfields['t.progress']['checked'])) {
639 print '<th class="right maxwidth75">'.$langs->trans("ProgressDeclared").'</th>';
640}
641if (!empty($arrayfields['timeconsumed']['checked'])) {
642 print '<th class="right maxwidth100">'.$langs->trans("TimeSpentSmall").'<br>';
643 print '<span class="nowraponall">';
644 print '<span class="opacitymedium nopadding userimg"><img alt="Photo" class="photouserphoto userphotosmall" src="'.DOL_URL_ROOT.'/theme/common/everybody.png"></span>';
645 print '<span class="opacitymedium paddingleft">'.$langs->trans("EverybodySmall").'</span>';
646 print '</span>';
647 print '</th>';
648 print '<th class="right maxwidth75">'.$langs->trans("TimeSpentSmall").($usertoprocess->firstname ? '<br><span class="nowraponall">'.$usertoprocess->getNomUrl(-3).'<span class="opacitymedium paddingleft">'.dol_trunc($usertoprocess->firstname, 10).'</span></span>' : '').'</th>';
649}
650foreach ($TWeek as $week_number) {
651 print '<th width="6%" class="center bold hide"><a href="'.DOL_URL_ROOT.'/projet/activity/perweek.php?year='.$year.'&month='.$month.'&day='.$TFirstDays[$week_number].'">'.$langs->trans("WeekShort").' '.$week_number.'<br>('.$TFirstDays[$week_number].'...'.$TLastDays[$week_number].')</a></th>';
652}
653
654//print '<td></td>';
655print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
656
657print "</tr>\n";
658
659$colspan = 1;
660
661
662// Get if user is available or not for each day
663$isavailable = array();
664// TODO See code into perweek.php to initialize isavailable array
665
666// By default, we can edit only tasks we are assigned to
667$restrictviewformytask = getDolGlobalInt('PROJECT_TIME_SHOW_TASK_NOT_ASSIGNED', 2);
668if (count($tasksarray) > 0) {
669 //var_dump($tasksarray); // contains only selected tasks
670 //var_dump($tasksarraywithoutfilter); // contains all tasks (if there is a filter, not defined if no filter)
671 //var_dump($tasksrole);
672
673 $j = 0;
674 $level = 0;
675 $totalforvisibletasks = projectLinesPerMonth($j, $firstdaytoshow, $usertoprocess, 0, $tasksarray, $level, $projectsrole, $tasksrole, $mine, $restrictviewformytask, $isavailable, 0, $TWeek, $arrayfields);
676 //var_dump($totalforvisibletasks);
677
678 // Show total for all other tasks
679
680 // Calculate total for all tasks
681 $listofdistinctprojectid = array(); // List of all distinct projects
682 if (!empty($tasksarraywithoutfilter) && is_array($tasksarraywithoutfilter) && count($tasksarraywithoutfilter)) {
683 foreach ($tasksarraywithoutfilter as $tmptask) {
684 $listofdistinctprojectid[$tmptask->fk_project] = $tmptask->fk_project;
685 }
686 }
687 //var_dump($listofdistinctprojectid);
688 $totalforeachweek = array();
689 '@phan-var-force array<string,int> $totalforeachweek';
690
691 foreach ($listofdistinctprojectid as $tmpprojectid) {
692 $projectstatic->id = $tmpprojectid;
693 $projectstatic->loadTimeSpentMonth($firstdaytoshow, 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
694 foreach ($TWeek as $weekNb) {
695 $totalforeachweek[$weekNb] += $projectstatic->monthWorkLoad[$weekNb];
696 }
697 }
698
699 //var_dump($totalforeachday);
700 //var_dump($totalforvisibletasks);
701
702 // Is there a diff between selected/filtered tasks and all tasks ?
703 $isdiff = 0;
704 if (count($totalforeachweek)) {
705 foreach ($TWeek as $weekNb) {
706 $timeonothertasks = ($totalforeachweek[$weekNb] - $totalforvisibletasks[$weekNb]);
707 if ($timeonothertasks) {
708 $isdiff = 1;
709 break;
710 }
711 }
712 }
713
714 // 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
715 if ($isdiff) {
716 print '<tr class="oddeven othertaskwithtime">';
717 print '<td colspan="'.$colspan.'" class="opacitymedium">';
718 print $langs->trans("OtherFilteredTasks");
719 print '</td>';
720 if (!empty($arrayfields['t.planned_workload']['checked'])) {
721 print '<td class="liste_total"></td>';
722 }
723 if (!empty($arrayfields['t.progress']['checked'])) {
724 print '<td class="liste_total"></td>';
725 }
726 if (!empty($arrayfields['timeconsumed']['checked'])) {
727 print '<td class="liste_total"></td>';
728 print '<td class="liste_total"></td>';
729 }
730 $j = 0;
731 foreach ($TWeek as $weekNb) {
732 $j++;
733 print '<td class="center hide'.($j <= 1 ? ' borderleft' : '').'">';
734
735 $timeonothertasks = ($totalforeachweek[$weekNb] - $totalforvisibletasks[$weekNb]);
736 if ($timeonothertasks) {
737 print '<span class="timesheetalreadyrecorded" title="texttoreplace"><input type="text" class="center smallpadd width50" disabled="" id="timespent[-1]['.$weekNb.']" name="task[-1]['.$weekNb.']" value="';
738 print convertSecondToTime($timeonothertasks, 'allhourmin');
739 print '"></span>';
740 }
741 print '</td>';
742 }
743 print ' <td class="liste_total"></td>';
744 print '</tr>';
745 }
746
747 if ($conf->use_javascript_ajax) {
748 print '<tr class="liste_total">';
749 print '<td class="liste_total" colspan="'.($colspan + $addcolspan).'">';
750 print $langs->trans("Total");
751 print '<span class="opacitymediumbycolor"> - '.$langs->trans("ExpectedWorkedHours").': <strong>'.price($usertoprocess->weeklyhours, 1, $langs, 0, 0).'</strong></span>';
752 print '</td>';
753 if (!empty($arrayfields['timeconsumed']['checked'])) {
754 print '<td class="liste_total"></td>';
755 print '<td class="liste_total"></td>';
756 }
757
758 $j = 0;
759 foreach ($TWeek as $weekNb) {
760 $j++;
761 print '<td class="liste_total hide'.$weekNb.' center'.($j <= 1 ? ' borderleft' : '').'"><div class="totalDay'.$weekNb.'">'.convertSecondToTime($totalforvisibletasks[$weekNb], 'allhourmin').'</div></td>';
762 }
763 print '<td class="liste_total center"><div class="totalDayAll">&nbsp;</div></td>
764 </tr>';
765 }
766
767 $THolidays = array();
768 $totaldayholiday = 0;
769 foreach ($TWeek as $weekNb) {
770 $weekstart = dol_stringtotime($year.$month.($TFirstDays[$weekNb]));
771 $weekend = dol_stringtotime($year.$month.$TLastDays[$weekNb]);
772 $filter = " AND cp.statut = ".((int) Holiday::STATUS_APPROVED);
773 $filter .= " AND ('".$db->idate($weekstart)."' BETWEEN cp.date_debut AND cp.date_fin";
774 $filter .= " OR '".$db->idate($weekend)."' BETWEEN cp.date_debut AND cp.date_fin)";
775 $holiday->fetchByUser($usertoprocess->id, '', $filter);
776 $THolidays[$weekNb] = array();
777 $THolidays[$weekNb]["ids"] = array();
778 $THolidays[$weekNb]["days"] = 0;
779 foreach ($holiday->holiday as $key => $h) {
780 if (!empty($THolidays[$weekNb]["ids"]) && in_array($h["id"], $THolidays[$weekNb]["ids"])) {
781 continue;
782 }
783 $startweekholiday = (int) (($h["date_debut"] <= $weekstart) ? $weekstart : $h["date_debut"]);
784 $endweekholiday = (int) (($h["date_fin"] >= $weekend) ? $weekend : $h["date_fin"]);
785 $halfdays = (int) $h["halfday"];
786 $nbdays = num_open_day($startweekholiday, $endweekholiday, 0, 1, $halfdays, $usertoprocess->country_id);
787
788 $THolidays[$weekNb]["ids"][] = $h["id"];
789 $THolidays[$weekNb]["days"] += $nbdays;
790 $totaldayholiday += $nbdays;
791 }
792 }
793
794 //Calculate nb holiday
795 print '<tr class="liste_total">';
796 print '<td class="liste_total" colspan="'.($colspan + $addcolspan).'">';
797 print $langs->trans("Total");
798 print '<span class="opacitymediumbycolor"> - '.$langs->trans("NbUseDaysCP").': <strong>'.price($totaldayholiday, 1, $langs, 0, 0).'</strong></span>';
799 print '</td>';
800 if (!empty($arrayfields['timeconsumed']['checked'])) {
801 print '<td class="liste_total"></td>';
802 print '<td class="liste_total"></td>';
803 }
804 $j = 0;
805 foreach ($TWeek as $weekNb) {
806 $j++;
807 print '<td class="liste_total_holidays '.($THolidays[$weekNb]["days"] > 0 ? "onholidayallday" : "").' hide'.$weekNb.' center'.($j <= 1 ? ' borderleft' : '').'"><div class="totalDay'.$weekNb.'holidays">'.$THolidays[$weekNb]["days"].'</div></td>';
808 }
809 print '<td class="liste_total_holidays center"><div class="totalDayAllHolidays">&nbsp;</div></td>
810 </tr>';
811} else {
812 print '<tr><td colspan="15"><span class="opacitymedium">'.$langs->trans("NoAssignedTasks").'</span></td></tr>';
813}
814print "</table>";
815print '</div>';
816
817print '<input type="hidden" id="numberOfLines" name="numberOfLines" value="'.count($tasksarray).'"/>'."\n";
818print '<input type="hidden" id="numberOfFirstLine" name="numberOfFirstLine" value="'.(reset($TWeek)).'"/>'."\n";
819
820print $form->buttonsSaveCancel("Save", '');
821
822print '</form>'."\n\n";
823
824$modeinput = 'hours';
825
826if ($conf->use_javascript_ajax) {
827 print "\n<!-- JS CODE TO ENABLE Tooltips on all object with class classfortooltip -->\n";
828 print '<script type="text/javascript">'."\n";
829 print "jQuery(document).ready(function () {\n";
830 print ' jQuery(".timesheetalreadyrecorded").tooltip({
831 show: { collision: "flipfit", effect:\'toggle\', delay:50 },
832 hide: { effect:\'toggle\', delay: 50 },
833 tooltipClass: "mytooltip",
834 content: function () {
835 return \''.dol_escape_js($langs->trans("TimeAlreadyRecorded", $usertoprocess->getFullName($langs))).'\';
836 }
837 });'."\n";
838
839 foreach ($TWeek as $week_number) {
840 print " updateTotal(".((int) $week_number).", '".dol_escape_js($modeinput)."');";
841 }
842 print "\n});\n";
843 print '</script>';
844}
845
846// End of page
847llxFooter();
848$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.
dol_get_prev_month($month, $year)
Return previous month.
Definition date.lib.php:523
getLastDayOfEachWeek($TWeek, $year)
Return array of last day of weeks.
getWeekNumbersOfMonth($month, $year)
Return array of week numbers.
num_open_day($timestampStart, $timestampEnd, $inhour=0, $lastday=0, $halfday=0, $countryCodeOrId='', $user_id=0)
Function to return number of working days (and text of units) between two dates (working days)
getFirstDayOfEachWeek($TWeek, $year)
Return array of first day of weeks.
dol_get_next_month($month, $year)
Return next month.
Definition date.lib.php:542
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
dol_stringtotime($string, $gm=1)
Convert a string date into a GM Timestamps date Warning: YYYY-MM-DDTHH:MM:SS+02:00 (RFC3339) is not s...
Definition date.lib.php:435
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.
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.
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_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_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
project_timesheet_prepare_head($mode, $fuser=null)
Prepare array with list of tabs.
projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask, &$isavailable, $oldprojectforbreak=0, $TWeek=array(), $arrayfields=array(), $extrafields=null)
Output a task line into a perday input mode.
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.