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