dolibarr 21.0.0-alpha
task.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2006-2017 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2010-2012 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
6 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
7 * Copyright (C) 2024 Vincent de Grandpré <vincent@de-grandpre.quebec>
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";
30require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
31require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
32require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
33require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
34require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
35require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
36require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
37require_once DOL_DOCUMENT_ROOT.'/core/modules/project/task/modules_task.php';
38require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
39
40// Load translation files required by the page
41$langs->loadlangs(array('projects', 'companies'));
42
43$action = GETPOST('action', 'aZ09');
44$confirm = GETPOST('confirm', 'alpha');
45//$cancel = GETPOST('cancel', 'aZ09');
46//$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
47//$backtopage = GETPOST('backtopage', 'alpha'); // if not set, a default page will be used
48//$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); // if not set, $backtopage will be used
49//$backtopagejsfields = GETPOST('backtopagejsfields', 'alpha');
50
51$id = GETPOSTINT('id');
52$ref = GETPOST("ref", 'alpha', 1); // task ref
53$taskref = GETPOST("taskref", 'alpha'); // task ref
54$withproject = GETPOSTINT('withproject');
55$project_ref = GETPOST('project_ref', 'alpha');
56$planned_workload = ((GETPOST('planned_workloadhour') != '' || GETPOST('planned_workloadmin') != '') ? (GETPOSTINT('planned_workloadhour') > 0 ? GETPOSTINT('planned_workloadhour') * 3600 : 0) + (GETPOSTINT('planned_workloadmin') > 0 ? GETPOSTINT('planned_workloadmin') * 60 : 0) : '');
57$mode = GETPOST('mode', 'alpha');
58
59// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
60$hookmanager->initHooks(array('projecttaskcard', 'globalcard'));
61
62$object = new Task($db);
63$extrafields = new ExtraFields($db);
64$projectstatic = new Project($db);
65
66// fetch optionals attributes and labels
67$extrafields->fetch_name_optionals_label($object->table_element);
68
69$parameters = array('id' => $id);
70$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
71if ($reshook < 0) {
72 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
73}
74
75if ($id > 0 || $ref) {
76 $object->fetch($id, $ref);
77}
78
79// Security check
80$socid = 0;
81
82restrictedArea($user, 'projet', $object->fk_project, 'projet&project');
83
84
85
86/*
87 * Actions
88 */
89
90if ($action == 'update' && !GETPOST("cancel") && $user->hasRight('projet', 'creer')) {
91 $error = 0;
92
93 if (empty($taskref)) {
94 $error++;
95 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Ref")), null, 'errors');
96 }
97 if (!GETPOST("label")) {
98 $error++;
99 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
100 }
101 if (!$error) {
102 $object->oldcopy = clone $object;
103
104 $tmparray = explode('_', GETPOST('task_parent'));
105 $task_parent = $tmparray[1];
106 if (empty($task_parent)) {
107 $task_parent = 0; // If task_parent is ''
108 }
109
110 $object->ref = $taskref ? $taskref : GETPOST("ref", 'alpha', 2);
111 $object->label = GETPOST("label", "alphanohtml");
112 if (!getDolGlobalString('FCKEDITOR_ENABLE_SOCIETE')) {
113 $object->description = GETPOST('description', "alphanohtml");
114 } else {
115 $object->description = GETPOST('description', "restricthtml");
116 }
117 $object->fk_task_parent = $task_parent;
118 $object->planned_workload = $planned_workload;
119 $object->date_start = dol_mktime(GETPOSTINT('date_starthour'), GETPOSTINT('date_startmin'), 0, GETPOSTINT('date_startmonth'), GETPOSTINT('date_startday'), GETPOSTINT('date_startyear'));
120 $object->date_end = dol_mktime(GETPOSTINT('date_endhour'), GETPOSTINT('date_endmin'), 0, GETPOSTINT('date_endmonth'), GETPOSTINT('date_endday'), GETPOSTINT('date_endyear'));
121 $object->progress = price2num(GETPOST('progress', 'alphanohtml'));
122 $object->budget_amount = GETPOSTFLOAT('budget_amount');
123 $object->billable = (GETPOST('billable', 'aZ') == 'yes' ? 1 : 0);
124
125 // Fill array 'array_options' with data from add form
126 $ret = $extrafields->setOptionalsFromPost(null, $object, '@GETPOSTISSET');
127 if ($ret < 0) {
128 $error++;
129 }
130
131 if (!$error) {
132 $result = $object->update($user);
133 if ($result < 0) {
134 setEventMessages($object->error, $object->errors, 'errors');
135 $action = 'edit';
136 }
137 } else {
138 $action = 'edit';
139 }
140 } else {
141 $action = 'edit';
142 }
143}
144
145if ($action == 'confirm_merge' && $confirm == 'yes' && $user->hasRight('projet', 'creer')) {
146 $task_origin_id = GETPOSTINT('task_origin');
147 $task_origin = new Task($db); // The Task that we will delete
148
149 if ($task_origin_id <= 0) {
150 $langs->load('errors');
151 setEventMessages($langs->trans('ErrorTaskIdIsMandatory', $langs->transnoentitiesnoconv('MergeOriginTask')), null, 'errors');
152 } else {
153 if (!$error && $task_origin->fetch($task_origin_id) < 1) {
154 setEventMessages($langs->trans('ErrorRecordNotFound'), null, 'errors');
155 $error++;
156 }
157 if (!$error) {
158 $result = $object->mergeTask($task_origin_id);
159 if ($result < 0) {
160 $error++;
161 setEventMessages($object->error, $object->errors, 'errors');
162 } else {
163 setEventMessages($langs->trans('TaskMergeSuccess'), null, 'mesgs');
164 }
165 }
166 }
167}
168
169if ($action == 'confirm_clone' && $confirm == 'yes') {
170 //$clone_contacts = GETPOST('clone_contacts') ? 1 : 0;
171 $clone_prog = GETPOST('clone_prog') ? 1 : 0;
172 $clone_time = GETPOST('clone_time') ? 1 : 0;
173 $clone_affectation = GETPOST('clone_affectation') ? 1 : 0;
174 $clone_change_dt = GETPOST('clone_change_dt') ? 1 : 0;
175 $clone_notes = GETPOST('clone_notes') ? 1 : 0;
176 $clone_file = GETPOST('clone_file') ? 1 : 0;
177 $result = $object->createFromClone($user, $object->id, $object->fk_project, $object->fk_task_parent, $clone_change_dt, $clone_affectation, $clone_time, $clone_file, $clone_notes, $clone_prog);
178 if ($result <= 0) {
179 setEventMessages($object->error, $object->errors, 'errors');
180 } else {
181 // Load new object
182 $newobject = new Task($db);
183 $newobject->fetch($result);
184 $newobject->fetch_optionals();
185 $newobject->fetch_thirdparty(); // Load new object
186 $object = $newobject;
187 $action = '';
188 }
189}
190
191if ($action == 'confirm_delete' && $confirm == "yes" && $user->hasRight('projet', 'supprimer')) {
192 $result = $projectstatic->fetch($object->fk_project);
193 $projectstatic->fetch_thirdparty();
194
195 if ($object->delete($user) > 0) {
196 header('Location: '.DOL_URL_ROOT.'/projet/tasks.php?restore_lastsearch_values=1&id='.$projectstatic->id.($withproject ? '&withproject=1' : ''));
197 exit;
198 } else {
199 setEventMessages($object->error, $object->errors, 'errors');
200 $action = '';
201 }
202}
203
204// Retrieve First Task ID of Project if withprojet is on to allow project prev next to work
205if (!empty($project_ref) && !empty($withproject)) {
206 if ($projectstatic->fetch(0, $project_ref) > 0) {
207 $tasksarray = $object->getTasksArray(null, null, $projectstatic->id, $socid, 0);
208 if (count($tasksarray) > 0) {
209 $id = $tasksarray[0]->id;
210 } else {
211 header("Location: ".DOL_URL_ROOT.'/projet/tasks.php?id='.$projectstatic->id.(empty($mode) ? '' : '&mode='.$mode));
212 }
213 }
214}
215
216// Build doc
217if ($action == 'builddoc' && $user->hasRight('projet', 'creer')) {
218 // Save last template used to generate document
219 if (GETPOST('model')) {
220 $object->setDocModel($user, GETPOST('model', 'alpha'));
221 }
222
223 $outputlangs = $langs;
224 if (GETPOST('lang_id', 'aZ09')) {
225 $outputlangs = new Translate("", $conf);
226 $outputlangs->setDefaultLang(GETPOST('lang_id', 'aZ09'));
227 }
228 $result = $object->generateDocument($object->model_pdf, $outputlangs);
229 if ($result <= 0) {
230 setEventMessages($object->error, $object->errors, 'errors');
231 $action = '';
232 }
233}
234
235// Delete file in doc form
236if ($action == 'remove_file' && $user->hasRight('projet', 'creer')) {
237 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
238
239 $langs->load("other");
240 $upload_dir = $conf->project->dir_output;
241 $file = $upload_dir.'/'.dol_sanitizeFileName(GETPOST('file'));
242
243 $ret = dol_delete_file($file);
244 if ($ret) {
245 setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs');
246 } else {
247 setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors');
248 }
249}
250
251
252/*
253 * View
254 */
255$form = new Form($db);
256$formother = new FormOther($db);
257$formfile = new FormFile($db);
258$formproject = new FormProjets($db);
259$result = $projectstatic->fetch($object->fk_project);
260
261$title = $object->ref;
262if (!empty($withproject)) {
263 $title .= ' | ' . $langs->trans("Project") . (!empty($projectstatic->ref) ? ': '.$projectstatic->ref : '') ;
264}
265$help_url = '';
266
267llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-project project-tasks page-task');
268
269
270if ($id > 0 || !empty($ref)) {
271 $res = $object->fetch_optionals();
272 if (getDolGlobalString('PROJECT_ALLOW_COMMENT_ON_TASK') && method_exists($object, 'fetchComments') && empty($object->comments)) {
273 $object->fetchComments();
274 }
275
276
277 if (getDolGlobalString('PROJECT_ALLOW_COMMENT_ON_PROJECT') && method_exists($projectstatic, 'fetchComments') && empty($projectstatic->comments)) {
278 $projectstatic->fetchComments();
279 }
280 if (!empty($projectstatic->socid)) {
281 $projectstatic->fetch_thirdparty();
282 }
283
284 $object->project = clone $projectstatic;
285
286 //$userWrite = $projectstatic->restrictedProjectArea($user, 'write');
287
288 if (!empty($withproject)) {
289 // Tabs for project
290 $tab = 'tasks';
291 $head = project_prepare_head($projectstatic);
292 print dol_get_fiche_head($head, $tab, $langs->trans("Project"), -1, ($projectstatic->public ? 'projectpub' : 'project'), 0, '', '');
293
294 $param = ($mode == 'mine' ? '&mode=mine' : '');
295
296 // Project card
297
298 $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
299
300 $morehtmlref = '<div class="refidno">';
301 // Title
302 $morehtmlref .= $projectstatic->title;
303 // Thirdparty
304 if (!empty($projectstatic->thirdparty->id) && $projectstatic->thirdparty->id > 0) {
305 $morehtmlref .= '<br>'.$projectstatic->thirdparty->getNomUrl(1, 'project');
306 }
307 $morehtmlref .= '</div>';
308
309 // Define a complementary filter for search of next/prev ref.
310 if (!$user->hasRight('projet', 'all', 'lire')) {
311 $objectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 0);
312 $projectstatic->next_prev_filter = "rowid IN (".$db->sanitize(count($objectsListId) ? implode(',', array_keys($objectsListId)) : '0').")";
313 }
314
315 dol_banner_tab($projectstatic, 'project_ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $param);
316
317 print '<div class="fichecenter">';
318 print '<div class="fichehalfleft">';
319 print '<div class="underbanner clearboth"></div>';
320
321 print '<table class="border tableforfield centpercent">';
322
323 // Usage
324 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES') || !getDolGlobalString('PROJECT_HIDE_TASKS') || isModEnabled('eventorganization')) {
325 print '<tr><td class="tdtop">';
326 print $langs->trans("Usage");
327 print '</td>';
328 print '<td>';
329 if (getDolGlobalString('PROJECT_USE_OPPORTUNITIES')) {
330 print '<input type="checkbox" disabled name="usage_opportunity"'.(GETPOSTISSET('usage_opportunity') ? (GETPOST('usage_opportunity', 'alpha') != '' ? ' checked="checked"' : '') : ($projectstatic->usage_opportunity ? ' checked="checked"' : '')).'"> ';
331 $htmltext = $langs->trans("ProjectFollowOpportunity");
332 print $form->textwithpicto($langs->trans("ProjectFollowOpportunity"), $htmltext);
333 print '<br>';
334 }
335 if (!getDolGlobalString('PROJECT_HIDE_TASKS')) {
336 print '<input type="checkbox" disabled name="usage_task"'.(GETPOSTISSET('usage_task') ? (GETPOST('usage_task', 'alpha') != '' ? ' checked="checked"' : '') : ($projectstatic->usage_task ? ' checked="checked"' : '')).'"> ';
337 $htmltext = $langs->trans("ProjectFollowTasks");
338 print $form->textwithpicto($langs->trans("ProjectFollowTasks"), $htmltext);
339 print '<br>';
340 }
341 if (!getDolGlobalString('PROJECT_HIDE_TASKS') && getDolGlobalString('PROJECT_BILL_TIME_SPENT')) {
342 print '<input type="checkbox" disabled name="usage_bill_time"'.(GETPOSTISSET('usage_bill_time') ? (GETPOST('usage_bill_time', 'alpha') != '' ? ' checked="checked"' : '') : ($projectstatic->usage_bill_time ? ' checked="checked"' : '')).'"> ';
343 $htmltext = $langs->trans("ProjectBillTimeDescription");
344 print $form->textwithpicto($langs->trans("BillTime"), $htmltext);
345 print '<br>';
346 }
347 if (isModEnabled('eventorganization')) {
348 print '<input type="checkbox" disabled name="usage_organize_event"'.(GETPOSTISSET('usage_organize_event') ? (GETPOST('usage_organize_event', 'alpha') != '' ? ' checked="checked"' : '') : ($projectstatic->usage_organize_event ? ' checked="checked"' : '')).'"> ';
349 $htmltext = $langs->trans("EventOrganizationDescriptionLong");
350 print $form->textwithpicto($langs->trans("ManageOrganizeEvent"), $htmltext);
351 }
352 print '</td></tr>';
353 }
354
355 // Visibility
356 print '<tr><td class="titlefield">'.$langs->trans("Visibility").'</td><td>';
357 if ($projectstatic->public) {
358 print img_picto($langs->trans('SharedProject'), 'world', 'class="paddingrightonly"');
359 print $langs->trans('SharedProject');
360 } else {
361 print img_picto($langs->trans('PrivateProject'), 'private', 'class="paddingrightonly"');
362 print $langs->trans('PrivateProject');
363 }
364 print '</td></tr>';
365
366 // Budget
367 print '<tr><td>'.$langs->trans("Budget").'</td><td>';
368 if (isset($projectstatic->budget_amount) && strcmp($projectstatic->budget_amount, '')) {
369 print '<span class="amount">'.price($projectstatic->budget_amount, 0, $langs, 1, 0, 0, $conf->currency).'</span>';
370 }
371 print '</td></tr>';
372
373 // Date start - end project
374 print '<tr><td>'.$langs->trans("Dates").'</td><td>';
375 $start = dol_print_date($projectstatic->date_start, 'day');
376 print($start ? $start : '?');
377 $end = dol_print_date($projectstatic->date_end, 'day');
378 print ' - ';
379 print($end ? $end : '?');
380 if ($projectstatic->hasDelay()) {
381 print img_warning("Late");
382 }
383 print '</td></tr>';
384
385 // Other attributes
386 $cols = 2;
387 //include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php';
388
389 print '</table>';
390
391 print '</div>';
392
393 print '<div class="fichehalfright">';
394 print '<div class="underbanner clearboth"></div>';
395
396 print '<table class="border tableforfield centpercent">';
397
398 // Description
399 print '<td class="titlefield tdtop">'.$langs->trans("Description").'</td><td>';
400 print nl2br($projectstatic->description);
401 print '</td></tr>';
402
403 // Categories
404 if (isModEnabled('category')) {
405 print '<tr><td class="valignmiddle">'.$langs->trans("Categories").'</td><td>';
406 print $form->showCategories($projectstatic->id, 'project', 1);
407 print "</td></tr>";
408 }
409
410 print '</table>';
411
412 print '</div>';
413 print '</div>';
414
415 print '<div class="clearboth"></div>';
416
417 print dol_get_fiche_end();
418
419 print '<br>';
420 }
421
422 /*
423 * Actions
424 */
425 /*print '<div class="tabsAction">';
426
427 if ($user->rights->projet->all->creer || $user->rights->projet->creer)
428 {
429 if ($projectstatic->public || $userWrite > 0)
430 {
431 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=create'.$param.'">'.$langs->trans('AddTask').'</a>';
432 }
433 else
434 {
435 print '<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("NotOwnerOfProject").'">'.$langs->trans('AddTask').'</a>';
436 }
437 }
438 else
439 {
440 print '<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("NotEnoughPermissions").'">'.$langs->trans('AddTask').'</a>';
441 }
442
443 print '</div>';
444 */
445
446 // To verify role of users
447 //$userAccess = $projectstatic->restrictedProjectArea($user); // We allow task affected to user even if a not allowed project
448 //$arrayofuseridoftask=$object->getListContactId('internal');
449
450
451 $head = task_prepare_head($object);
452
453 if ($action == 'edit' && $user->hasRight('projet', 'creer')) {
454 print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
455 print '<input type="hidden" name="token" value="'.newToken().'">';
456 print '<input type="hidden" name="action" value="update">';
457 print '<input type="hidden" name="withproject" value="'.$withproject.'">';
458 print '<input type="hidden" name="id" value="'.$object->id.'">';
459
460 print dol_get_fiche_head($head, 'task_task', $langs->trans("Task"), 0, 'projecttask', 0, '', '');
461
462 print '<table class="border centpercent">';
463
464 // Ref
465 print '<tr><td class="titlefield fieldrequired">'.$langs->trans("Ref").'</td>';
466 print '<td><input class="minwidth100" name="taskref" value="'.$object->ref.'"></td></tr>';
467
468 // Label
469 print '<tr><td class="fieldrequired">'.$langs->trans("Label").'</td>';
470 print '<td><input class="minwidth500" name="label" value="'.$object->label.'"></td></tr>';
471
472 // Project
473 if (empty($withproject)) {
474 print '<tr><td>'.$langs->trans("Project").'</td><td>';
475 print $projectstatic->getNomUrl(1);
476 print '</td></tr>';
477
478 // Third party
479 print '<td>'.$langs->trans("ThirdParty").'</td><td>';
480 if ($projectstatic->thirdparty->id) {
481 print $projectstatic->thirdparty->getNomUrl(1);
482 } else {
483 print '&nbsp;';
484 }
485 print '</td></tr>';
486 }
487
488 // Task parent
489 print '<tr><td>'.$langs->trans("ChildOfProjectTask").'</td><td>';
490 print img_picto('', 'projecttask');
491 $formother->selectProjectTasks($object->fk_task_parent, $projectstatic->id, 'task_parent', ($user->admin ? 0 : 1), 0, 0, 0, $object->id, '', 'minwidth100 widthcentpercentminusxx maxwidth500');
492 print '</td></tr>';
493
494 // Date start
495 print '<tr><td>'.$langs->trans("DateStart").'</td><td>';
496 print $form->selectDate($object->date_start, 'date_start', 1, 1, 0, '', 1, 0);
497 print '</td></tr>';
498
499 // Date end
500 print '<tr><td>'.$langs->trans("Deadline").'</td><td>';
501 print $form->selectDate($object->date_end ? $object->date_end : -1, 'date_end', 1, 1, 0, '', 1, 0);
502 print '</td></tr>';
503
504 // Planned workload
505 print '<tr><td>'.$langs->trans("PlannedWorkload").'</td><td>';
506 print $form->select_duration('planned_workload', $object->planned_workload, 0, 'text');
507 print '</td></tr>';
508
509 // Progress declared
510 print '<tr><td>'.$langs->trans("ProgressDeclared").'</td><td>';
511 print $formother->select_percent($object->progress, 'progress', 0, 5, 0, 100, 1);
512 print '</td></tr>';
513
514 // Billable
515 print '<tr><td>'.$langs->trans("Billable").'</td><td>';
516 print $form->selectyesno('billable', $object->billable);
517 print '</td></tr>';
518
519 // Description
520
521 print '<tr><td class="tdtop">'.$langs->trans("Description").'</td>';
522 print '<td>';
523
524 // WYSIWYG editor
525 include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
526 $nbrows = getDolGlobalInt('MAIN_INPUT_DESC_HEIGHT', 0);
527 $doleditor = new DolEditor('description', $object->description, '', 80, 'dolibarr_details', '', false, true, getDolGlobalInt('FCKEDITOR_ENABLE_SOCIETE'), $nbrows, '90%');
528 print $doleditor->Create();
529
530 print '</td></tr>';
531
532
533 print '<tr><td>'.$langs->trans("Budget").'</td>';
534 print '<td><input class="with75" type="text" name="budget_amount" value="'.dol_escape_htmltag(GETPOSTISSET('budget_amount') ? GETPOST('budget_amount') : price2num($object->budget_amount)).'"></td>';
535 print '</tr>';
536
537 // Other options
538 $parameters = array();
539 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
540 print $hookmanager->resPrint;
541 if (empty($reshook)) {
542 print $object->showOptionals($extrafields, 'edit');
543 }
544
545 print '</table>';
546
547 print dol_get_fiche_end();
548
549 print $form->buttonsSaveCancel("Modify");
550
551 print '</form>';
552 } else {
553 /*
554 * Fiche tache en mode visu
555 */
556 $param = ($withproject ? '&withproject=1' : '');
557 $linkback = $withproject ? '<a href="'.DOL_URL_ROOT.'/projet/tasks.php?id='.$projectstatic->id.'&restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>' : '';
558
559 print dol_get_fiche_head($head, 'task_task', $langs->trans("Task"), -1, 'projecttask', 0, '', 'reposition');
560
561 if ($action == 'clone') {
562 $formquestion = array(
563 'text' => $langs->trans("ConfirmClone"),
564 //array('type' => 'checkbox', 'name' => 'clone_contacts', 'label' => $langs->trans("CloneContacts"), 'value' => true),
565 0 => array('type' => 'checkbox', 'name' => 'clone_change_dt', 'label' => $langs->trans("CloneChanges"), 'value' => true),
566 1 => array('type' => 'checkbox', 'name' => 'clone_affectation', 'label' => $langs->trans("CloneAffectation"), 'value' => true),
567 2 => array('type' => 'checkbox', 'name' => 'clone_prog', 'label' => $langs->trans("CloneProgression"), 'value' => true),
568 3 => array('type' => 'checkbox', 'name' => 'clone_time', 'label' => $langs->trans("CloneTimes"), 'value' => true),
569 4 => array('type' => 'checkbox', 'name' => 'clone_file', 'label' => $langs->trans("CloneFile"), 'value' => true),
570 );
571
572 print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans("ToClone"), $langs->trans("ConfirmCloneTask"), "confirm_clone", $formquestion, '', 1, 300, 590);
573 }
574
575 if ($action == 'merge') {
576 $formquestion = array(
577 array(
578 'name' => 'task_origin',
579 'label' => $langs->trans('MergeOriginTask'),
580 'type' => 'other',
581 'value' => $formproject->selectTasks(-1, '', 'task_origin', 24, 0, $langs->trans('SelectTask'), 0, 0, 0, 'maxwidth500 minwidth200', '', '', null, 1)
582 )
583 );
584 print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id.(GETPOST('withproject') ? "&withproject=1" : ""), $langs->trans("MergeTasks"), $langs->trans("ConfirmMergeTasks"), "confirm_merge", $formquestion, 'yes', 1, 250);
585 }
586
587 if ($action == 'delete') {
588 print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".GETPOSTINT("id").'&withproject='.$withproject, $langs->trans("DeleteATask"), $langs->trans("ConfirmDeleteATask"), "confirm_delete");
589 }
590
591 if (!GETPOST('withproject') || empty($projectstatic->id)) {
592 $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1);
593 $object->next_prev_filter = "fk_projet IN (".$db->sanitize($projectsListId).")";
594 } else {
595 $object->next_prev_filter = "fk_projet = ".((int) $projectstatic->id);
596 }
597
598 $morehtmlref = '';
599
600 // Project
601 if (empty($withproject)) {
602 $morehtmlref .= '<div class="refidno">';
603 $morehtmlref .= $langs->trans("Project").': ';
604 $morehtmlref .= $projectstatic->getNomUrl(1);
605 $morehtmlref .= '<br>';
606
607 // Third party
608 $morehtmlref .= $langs->trans("ThirdParty").': ';
609 if (!empty($projectstatic->thirdparty) && is_object($projectstatic->thirdparty)) {
610 $morehtmlref .= $projectstatic->thirdparty->getNomUrl(1);
611 }
612 $morehtmlref .= '</div>';
613 }
614
615 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, $param);
616
617 print '<div class="fichecenter">';
618 print '<div class="fichehalfleft">';
619
620 print '<div class="underbanner clearboth"></div>';
621 print '<table class="border centpercent tableforfield">';
622
623 // Task parent
624 print '<tr><td>'.$langs->trans("ChildOfTask").'</td><td>';
625 if ($object->fk_task_parent > 0) {
626 $tasktmp = new Task($db);
627 $tasktmp->fetch($object->fk_task_parent);
628 print $tasktmp->getNomUrl(1);
629 }
630 print '</td></tr>';
631
632 // Date start - Date end task
633 print '<tr><td class="titlefield">'.$langs->trans("DateStart").' - '.$langs->trans("Deadline").'</td><td colspan="3">';
634 $start = dol_print_date($object->date_start, 'dayhour');
635 print($start ? $start : '?');
636 $end = dol_print_date($object->date_end, 'dayhour');
637 print ' - ';
638 print($end ? $end : '?');
639 if ($object->hasDelay()) {
640 print img_warning("Late");
641 }
642 print '</td></tr>';
643
644 // Planned workload
645 print '<tr><td>'.$langs->trans("PlannedWorkload").'</td><td colspan="3">';
646 if ($object->planned_workload != '') {
647 print convertSecondToTime($object->planned_workload, 'allhourmin');
648 }
649 print '</td></tr>';
650
651 // Description
652 print '<td class="tdtop">'.$langs->trans("Description").'</td><td colspan="3">';
653 print dol_htmlentitiesbr($object->description);
654 print '</td></tr>';
655
656 print '</table>';
657 print '</div>';
658
659 print '<div class="fichehalfright">';
660
661 print '<div class="underbanner clearboth"></div>';
662 print '<table class="border centpercent tableforfield">';
663
664 // Progress declared
665 print '<tr><td class="titlefield">'.$langs->trans("ProgressDeclared").'</td><td colspan="3">';
666 if ($object->progress != '' && $object->progress != '-1') {
667 print $object->progress.' %';
668 }
669 print '</td></tr>';
670
671 // Progress calculated
672 print '<tr><td>'.$langs->trans("ProgressCalculated").'</td><td colspan="3">';
673 if ($object->planned_workload != '') {
674 $tmparray = $object->getSummaryOfTimeSpent();
675 if ($tmparray['total_duration'] > 0 && !empty($object->planned_workload)) {
676 print round($tmparray['total_duration'] / $object->planned_workload * 100, 2).' %';
677 } else {
678 print '0 %';
679 }
680 } else {
681 print '<span class="opacitymedium">'.$langs->trans("WorkloadNotDefined").'</span>';
682 }
683 print '</td></tr>';
684
685 // Budget
686 print '<tr><td>'.$langs->trans("Budget").'</td><td>';
687 if (!is_null($object->budget_amount) && strcmp((string) $object->budget_amount, '')) {
688 print '<span class="amount">'.price($object->budget_amount, 0, $langs, 1, 0, 0, $conf->currency).'</span>';
689 }
690 print '</td></tr>';
691
692 // Billable
693 print '<tr><td>'.$langs->trans("Billable").'</td><td>';
694 print '<span>'.($object->billable ? $langs->trans('Yes') : $langs->trans('No')).'</span>';
695 print '</td></tr>';
696
697 // Other attributes
698 $cols = 3;
699 $parameters = array('socid' => $socid);
700 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
701
702 print '</table>';
703
704 print '</div>';
705
706 print '</div>';
707 print '<div class="clearboth"></div>';
708
709 print dol_get_fiche_end();
710 }
711
712
713 if ($action != 'edit') {
714 /*
715 * Actions
716 */
717
718 print '<div class="tabsAction">';
719
720 $parameters = array();
721 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been
722 // modified by hook
723 if (empty($reshook)) {
724 // Modify
725 if ($user->hasRight('projet', 'creer')) {
726 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=edit&token='.newToken().'&withproject='.((int) $withproject).'">'.$langs->trans('Modify').'</a>';
727 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=clone&token='.newToken().'&withproject='.((int) $withproject).'">'.$langs->trans('Clone').'</a>';
728 print '<a class="butActionDelete classfortooltip" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=merge&token='.newToken().'&withproject='.((int) $withproject).'" title="'.$langs->trans("MergeTasks").'">'.$langs->trans('Merge').'</a>';
729 } else {
730 print '<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("NotAllowed").'">'.$langs->trans('Modify').'</a>';
731 }
732
733 // Delete
734 $permissiontodelete = $user->hasRight('projet', 'supprimer');
735 if ($permissiontodelete) {
736 if (!$object->hasChildren() && !$object->hasTimeSpent()) {
737 print dolGetButtonAction($langs->trans("Delete"), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken().'&withproject='.((int) $withproject), 'delete', $permissiontodelete);
738 } else {
739 print dolGetButtonAction($langs->trans("TaskHasChild"), $langs->trans("Delete"), 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken().'&withproject='.((int) $withproject), 'delete', 0);
740 }
741 } else {
742 print dolGetButtonAction($langs->trans("Delete"), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken().'&withproject='.((int) $withproject), 'delete', $permissiontodelete);
743 }
744
745 print '</div>';
746 }
747
748 print '<div class="fichecenter"><div class="fichehalfleft">';
749 print '<a name="builddoc"></a>'; // ancre
750
751 /*
752 * Generated documents
753 */
754 $filename = dol_sanitizeFileName($projectstatic->ref)."/".dol_sanitizeFileName($object->ref);
755 $filedir = $conf->project->dir_output."/".dol_sanitizeFileName($projectstatic->ref)."/".dol_sanitizeFileName($object->ref);
756 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
757 $genallowed = ($user->hasRight('projet', 'lire'));
758 $delallowed = ($user->hasRight('projet', 'creer'));
759
760 print $formfile->showdocuments('project_task', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf);
761
762 // Show links to link elements
763 $linktoelem = $form->showLinkToObjectBlock($object, null, array('project_task'));
764
765 $compatibleImportElementsList = false;
766 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem, $compatibleImportElementsList);
767
768 print '</div><div class="fichehalfright">';
769
770 // List of actions on element
771 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
772 $formactions = new FormActions($db);
773 $formactions->showactions($object, 'project_task', 0, 1, '', 10, 'withproject='.$withproject);
774
775 print '</div></div>';
776 }
777}
778
779// End of page
780llxFooter();
781$db->close();
$id
Definition account.php:39
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
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:70
Class to manage a WYSIWYG editor.
Class to manage standard extra fields.
Class to manage building of HTML components.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class permettant la generation de composants html autre Only common components are here.
Class to manage building of HTML components.
Class to manage projects.
Class to manage tasks.
Class to manage translations.
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:241
llxFooter()
Footer empty.
Definition document.php:107
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
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.
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
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)
Show tabs of a record.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
newToken()
Return the value of token currently saved into session with name 'newtoken'.
dolGetButtonAction($label, $text='', $actionType='default', $url='', $id='', $userRight=1, $params=array())
Function dolGetButtonAction.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
GETPOSTFLOAT($paramname, $rounding='')
Return the value of a $_GET or $_POST supervariable, converted into float.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_htmlentitiesbr($stringtoencode, $nl2brmode=0, $pagecodefrom='UTF-8', $removelasteolbr=1)
This function is called to encode a string into a HTML string but differs from htmlentities because a...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
task_prepare_head($object)
Prepare array with list of tabs.
project_prepare_head(Project $project, $moreparam='')
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.