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