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