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