From 697a2e557639d1bb19ef7cc4f640b6a27c59bf6b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 29 Mar 2019 14:34:55 +0100 Subject: [PATCH] Show time to bill and billed in list of tasks --- htdocs/core/lib/project.lib.php | 95 +++++++++++++++++------ htdocs/projet/class/task.class.php | 35 ++++++++- htdocs/projet/tasks.php | 118 +++++++++++++++++++++++------ htdocs/projet/tasks/list.php | 2 +- 4 files changed, 199 insertions(+), 51 deletions(-) diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 92df28d9922..d7711b510da 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -334,20 +334,21 @@ function project_admin_prepare_head() /** * Show task lines with a particular parent * - * @param string $inc Line number (start to 0, then increased by recursive call) - * @param string $parent Id of parent project to show (0 to show all) - * @param Task[] $lines Array of lines - * @param int $level Level (start to 0, then increased/decrease by recursive call), or -1 to show all level in order of $lines without the recursive groupment feature. - * @param string $var Color - * @param int $showproject Show project columns - * @param int $taskrole Array of roles of user for each tasks - * @param int $projectsListId List of id of project allowed to user (string separated with comma) - * @param int $addordertick Add a tick to move task - * @param int $projectidfortotallink 0 or Id of project to use on total line (link to see all time consumed for project) + * @param string $inc Line number (start to 0, then increased by recursive call) + * @param string $parent Id of parent project to show (0 to show all) + * @param Task[] $lines Array of lines + * @param int $level Level (start to 0, then increased/decrease by recursive call), or -1 to show all level in order of $lines without the recursive groupment feature. + * @param string $var Color + * @param int $showproject Show project columns + * @param int $taskrole Array of roles of user for each tasks + * @param int $projectsListId List of id of project allowed to user (string separated with comma) + * @param int $addordertick Add a tick to move task + * @param int $projectidfortotallink 0 or Id of project to use on total line (link to see all time consumed for project) * @param string $filterprogresscalc filter text + * @param string $showbilltime Add the column 'TimeToBill' and 'TimeBilled' * @return void */ -function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$taskrole, $projectsListId = '', $addordertick = 0, $projectidfortotallink = 0, $filterprogresscalc = '') +function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$taskrole, $projectsListId = '', $addordertick = 0, $projectidfortotallink = 0, $filterprogresscalc = '', $showbilltime=0) { global $user, $bc, $langs, $conf, $db; global $projectstatic, $taskstatic; @@ -370,12 +371,14 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t $numlines=count($lines); // We declare counter as global because we want to edit them into recursive call - global $total_projectlinesa_spent,$total_projectlinesa_planned,$total_projectlinesa_spent_if_planned; + global $total_projectlinesa_spent,$total_projectlinesa_planned,$total_projectlinesa_spent_if_planned,$total_projectlinesa_tobill,$total_projectlinesa_billed; if ($level == 0) { $total_projectlinesa_spent=0; $total_projectlinesa_planned=0; $total_projectlinesa_spent_if_planned=0; + $total_projectlinesa_tobill=0; + $total_projectlinesa_billed=0; } for ($i = 0 ; $i < $numlines ; $i++) @@ -439,15 +442,25 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t print ''."\n"; + $projectstatic->id=$lines[$i]->fk_project; + $projectstatic->ref=$lines[$i]->projectref; + $projectstatic->public=$lines[$i]->public; + $projectstatic->title=$lines[$i]->projectlabel; + $projectstatic->bill_time=$lines[$i]->bill_time; + + $taskstatic->id=$lines[$i]->id; + $taskstatic->ref=$lines[$i]->ref; + $taskstatic->label=($taskrole[$lines[$i]->id]?$langs->trans("YourRole").': '.$taskrole[$lines[$i]->id]:''); + $taskstatic->projectstatus = $lines[$i]->projectstatus; + $taskstatic->progress = $lines[$i]->progress; + $taskstatic->fk_statut = $lines[$i]->status; + $taskstatic->datee = $lines[$i]->date_end; + if ($showproject) { // Project ref print ""; //if ($showlineingray) print ''; - $projectstatic->id=$lines[$i]->fk_project; - $projectstatic->ref=$lines[$i]->projectref; - $projectstatic->public=$lines[$i]->public; - $projectstatic->title=$lines[$i]->projectlabel; if ($lines[$i]->public || in_array($lines[$i]->fk_project, $projectsArrayId) || ! empty($user->rights->projet->all->lire)) print $projectstatic->getNomUrl(1); else print $projectstatic->getNomUrl(1, 'nolink'); //if ($showlineingray) print ''; @@ -468,9 +481,6 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t } else { - $taskstatic->id=$lines[$i]->id; - $taskstatic->ref=$lines[$i]->ref; - $taskstatic->label=($taskrole[$lines[$i]->id]?$langs->trans("YourRole").': '.$taskrole[$lines[$i]->id]:''); print $taskstatic->getNomUrl(1, 'withproject'); } print ''; @@ -495,10 +505,6 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t // Date end print ''; - $taskstatic->projectstatus = $lines[$i]->projectstatus; - $taskstatic->progress = $lines[$i]->progress; - $taskstatic->fk_statut = $lines[$i]->status; - $taskstatic->datee = $lines[$i]->date_end; print dol_print_date($lines[$i]->date_end, 'dayhour'); if ($taskstatic->hasDelay()) print img_warning($langs->trans("Late")); print ''; @@ -548,6 +554,35 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t } print ''; + if ($showbilltime) + { + // Time not billed + print ''; + if ($lines[$i]->bill_time) + { + print convertSecondToTime($lines[$i]->tobill, 'allhourmin'); + $total_projectlinesa_tobill += $lines[$i]->tobill; + } + else + { + print ''.$langs->trans("NA").''; + } + print ''; + + // Time billed + print ''; + if ($lines[$i]->bill_time) + { + print convertSecondToTime($lines[$i]->billed, 'allhourmin'); + $total_projectlinesa_billed += $lines[$i]->billed; + } + else + { + print ''.$langs->trans("NA").''; + } + print ''; + } + // Contacts of task if (! empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST)) { @@ -582,7 +617,7 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t if ($level >= 0) // Call sublevels { $level++; - if ($lines[$i]->id) projectLinesa($inc, $lines[$i]->id, $lines, $level, $var, $showproject, $taskrole, $projectsListId, $addordertick); + if ($lines[$i]->id) projectLinesa($inc, $lines[$i]->id, $lines, $level, $var, $showproject, $taskrole, $projectsListId, $addordertick, $projectidfortotallink, $filterprogresscalc, $showbilltime); $level--; } @@ -597,7 +632,8 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t } } - if (($total_projectlinesa_planned > 0 || $total_projectlinesa_spent > 0) && $level <= 0) + if (($total_projectlinesa_planned > 0 || $total_projectlinesa_spent > 0 || $total_projectlinesa_tobill > 0 || $total_projectlinesa_billed > 0) + && $level <= 0) { print ''; print ''.$langs->trans("Total").''; @@ -617,6 +653,15 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t if ($total_projectlinesa_planned) print round(100 * $total_projectlinesa_spent / $total_projectlinesa_planned, 2).' %'; print ''; print ''; + if ($showbilltime) + { + print ''; + print convertSecondToTime($total_projectlinesa_tobill, 'allhourmin'); + print ''; + print ''; + print convertSecondToTime($total_projectlinesa_billed, 'allhourmin'); + print ''; + } // Contacts of task if (! empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST)) { diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 73a6d9d2493..ba7130ff031 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -729,9 +729,10 @@ class Task extends CommonObject * @param string $morewherefilter Add more filter into where SQL request (must start with ' AND ...') * @param string $filteronprojuser Filter on user that is a contact of project * @param string $filterontaskuser Filter on user assigned to task + * @param int $includebilltime Calculate also the time to bill and billed * @return array Array of tasks */ - public function getTasksArray($usert = null, $userp = null, $projectid = 0, $socid = 0, $mode = 0, $filteronproj = '', $filteronprojstatus = '-1', $morewherefilter = '', $filteronprojuser = 0, $filterontaskuser = 0) + public function getTasksArray($usert = null, $userp = null, $projectid = 0, $socid = 0, $mode = 0, $filteronproj = '', $filteronprojstatus = '-1', $morewherefilter = '', $filteronprojuser = 0, $filterontaskuser = 0, $includebilltime = 0) { global $conf; @@ -742,10 +743,14 @@ class Task extends CommonObject // List of tasks (does not care about permissions. Filtering will be done later) $sql = "SELECT "; if ($filteronprojuser > 0 || $filterontaskuser > 0) $sql.= " DISTINCT"; // We may get several time the same record if user has several roles on same project/task - $sql.= " p.rowid as projectid, p.ref, p.title as plabel, p.public, p.fk_statut as projectstatus,"; + $sql.= " p.rowid as projectid, p.ref, p.title as plabel, p.public, p.fk_statut as projectstatus, p.bill_time,"; $sql.= " t.rowid as taskid, t.ref as taskref, t.label, t.description, t.fk_task_parent, t.duration_effective, t.progress, t.fk_statut as status,"; $sql.= " t.dateo as date_start, t.datee as date_end, t.planned_workload, t.rang,"; $sql.= " s.rowid as thirdparty_id, s.nom as thirdparty_name, s.email as thirdparty_email"; + if ($includebilltime) + { + $sql.=" , SUM(tt.task_duration * ".$this->db->ifsql("invoice_id IS NULL", "1", "0").") as tobill, SUM(tt.task_duration * ".$this->db->ifsql("invoice_id IS NULL", "0", "1").") as billed"; + } $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON p.fk_soc = s.rowid"; if ($mode == 0) @@ -756,6 +761,10 @@ class Task extends CommonObject $sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc"; } $sql.= ", ".MAIN_DB_PREFIX."projet_task as t"; + if ($includebilltime) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_time as tt ON tt.fk_task = t.rowid"; + } if ($filterontaskuser > 0) { $sql.= ", ".MAIN_DB_PREFIX."element_contact as ec2"; @@ -774,12 +783,20 @@ class Task extends CommonObject if ($filterontaskuser > 0) { $sql.= ", ".MAIN_DB_PREFIX."projet_task as t"; + if ($includebilltime) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_time as tt ON tt.fk_task = t.rowid"; + } $sql.= ", ".MAIN_DB_PREFIX."element_contact as ec2"; $sql.= ", ".MAIN_DB_PREFIX."c_type_contact as ctc2"; } else { $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t on t.fk_projet = p.rowid"; + if ($includebilltime) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_time as tt ON tt.fk_task = t.rowid"; + } } $sql.= " WHERE p.entity IN (".getEntity('project').")"; } @@ -809,6 +826,15 @@ class Task extends CommonObject if ($filteronproj) $sql.= natural_search(array("p.ref", "p.title"), $filteronproj); if ($filteronprojstatus && $filteronprojstatus != '-1') $sql.= " AND p.fk_statut IN (".$filteronprojstatus.")"; if ($morewherefilter) $sql.=$morewherefilter; + if ($includebilltime) + { + $sql.=" GROUP BY p.rowid, p.ref, p.title, p.public, p.fk_statut, p.bill_time,"; + $sql.=" t.datec, t.dateo, t.datee, t.tms,"; + $sql.=" t.rowid, t.ref, t.label, t.description, t.fk_task_parent, t.duration_effective, t.progress, t.fk_statut,"; + $sql.=" t.dateo, t.datee, t.planned_workload, t.rang,"; + $sql.=" s.rowid, s.nom, s.email"; + } + $sql.= " ORDER BY p.ref, t.rang, t.dateo"; //print $sql;exit; @@ -849,12 +875,17 @@ class Task extends CommonObject $tasks[$i]->projectref = $obj->ref; $tasks[$i]->projectlabel = $obj->plabel; $tasks[$i]->projectstatus = $obj->projectstatus; + $tasks[$i]->bill_time = $obj->bill_time; $tasks[$i]->label = $obj->label; $tasks[$i]->description = $obj->description; $tasks[$i]->fk_parent = $obj->fk_task_parent; // deprecated $tasks[$i]->fk_task_parent = $obj->fk_task_parent; $tasks[$i]->duration = $obj->duration_effective; $tasks[$i]->planned_workload= $obj->planned_workload; + + $tasks[$i]->tobill = $obj->tobill; + $tasks[$i]->billed = $obj->billed; + $tasks[$i]->progress = $obj->progress; $tasks[$i]->fk_statut = $obj->status; $tasks[$i]->public = $obj->public; diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index 915ac8b9bd4..1375a7a4844 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -19,7 +19,7 @@ /** * \file htdocs/projet/tasks.php - * \ingroup projet + * \ingroup project * \brief List all tasks of a project */ @@ -33,12 +33,18 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; // Load translation files required by the page -$langs->loadLangs(array("users", "projects")); +$langs->loadLangs(array('projects', 'users', 'companies')); + +$action = GETPOST('action', 'alpha'); +$massaction=GETPOST('massaction', 'alpha'); +$show_files=GETPOST('show_files', 'int'); +$confirm=GETPOST('confirm', 'alpha'); +$toselect = GETPOST('toselect', 'array'); $id = GETPOST('id', 'int'); $ref = GETPOST('ref', 'alpha'); $taskref = GETPOST('taskref', 'alpha'); -$action = GETPOST('action', 'alpha'); + $backtopage=GETPOST('backtopage', 'alpha'); $cancel=GETPOST('cancel', 'alpha'); @@ -78,6 +84,8 @@ $socid=0; //if ($user->societe_id > 0) $socid = $user->societe_id; // For external user, no check is done on company because readability is managed by public status of project and assignement. $result = restrictedArea($user, 'projet', $id, 'projet&project'); +$diroutputmassaction=$conf->projet->dir_output . '/tasks/temp/massgeneration/'.$user->id; + // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('projecttaskscard','globalcard')); @@ -90,6 +98,34 @@ $planned_workload=$planned_workloadhour*3600+$planned_workloadmin*60; $userAccess=0; +$arrayfields=array( + 't.ref'=>array('label'=>$langs->trans("RefTask"), 'checked'=>1, 'position'=>80), + 't.label'=>array('label'=>$langs->trans("LabelTask"), 'checked'=>1, 'position'=>80), + 't.dateo'=>array('label'=>$langs->trans("DateStart"), 'checked'=>1, 'position'=>100), + 't.datee'=>array('label'=>$langs->trans("DateEnd"), 'checked'=>1, 'position'=>101), + 'p.ref'=>array('label'=>$langs->trans("ProjectRef"), 'checked'=>1), + 'p.title'=>array('label'=>$langs->trans("ProjectLabel"), 'checked'=>0), + 's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>0), + 'p.fk_statut'=>array('label'=>$langs->trans("ProjectStatus"), 'checked'=>1), + 't.planned_workload'=>array('label'=>$langs->trans("PlannedWorkload"), 'checked'=>1, 'position'=>102), + 't.duration_effective'=>array('label'=>$langs->trans("TimeSpent"), 'checked'=>1, 'position'=>103), + 't.progress_calculated'=>array('label'=>$langs->trans("ProgressCalculated"), 'checked'=>1, 'position'=>104), + 't.progress'=>array('label'=>$langs->trans("ProgressDeclared"), 'checked'=>1, 'position'=>105), + 't.tobill'=>array('label'=>$langs->trans("TimeToBill"), 'checked'=>0, 'position'=>110), + 't.billed'=>array('label'=>$langs->trans("TimeBilled"), 'checked'=>0, 'position'=>111), + 't.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), + 't.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), + //'t.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), +); +// Extra fields +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($extrafields->attribute_list[$key])) $arrayfields["ef.".$key]=array('label'=>$extrafields->attribute_label[$key], 'checked'=>(($extrafields->attribute_list[$key]<0)?0:1), 'position'=>$extrafields->attribute_pos[$key], 'enabled'=>(abs($extrafields->attribute_list[$key])!=3 && $extrafields->attribute_perms[$key])); + } +} + /* * Actions @@ -99,24 +135,38 @@ $parameters=array('id'=>$id); $reshook=$hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -// Purge search criteria -if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) // All tests are required to be compatible with all browsers +if (empty($reshook)) { - $search_user_id=""; - $search_taskref=''; - $search_tasklabel=''; - $search_dtstartday=''; - $search_dtstartmonth=''; - $search_dtstartyear=''; - $search_dtendday=''; - $search_dtendmonth=''; - $search_dtendyear=''; - $search_planedworkload=''; - $search_timespend=''; - $search_progresscalc=''; - $search_progressdeclare=''; - $toselect=''; - $search_array_options=array(); + // Selection of new fields + include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; + + // Purge search criteria + if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) // All tests are required to be compatible with all browsers + { + $search_user_id=""; + $search_taskref=''; + $search_tasklabel=''; + $search_dtstartday=''; + $search_dtstartmonth=''; + $search_dtstartyear=''; + $search_dtendday=''; + $search_dtendmonth=''; + $search_dtendyear=''; + $search_planedworkload=''; + $search_timespend=''; + $search_progresscalc=''; + $search_progressdeclare=''; + $toselect=''; + $search_array_options=array(); + } + + // Mass actions + $objectclass='Task'; + $objectlabel='Tasks'; + $permtoread = $user->rights->projet->lire; + $permtodelete = $user->rights->projet->supprimer; + $uploaddir = $conf->projet->dir_output.'/tasks'; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; } $morewherefilterarray=array(); @@ -297,11 +347,17 @@ if ($action == 'createtask' && $user->rights->projet->creer) * View */ +$now = dol_now(); $form=new Form($db); $formother=new FormOther($db); +$socstatic=new Societe($db); +$projectstatic = new Project($db); $taskstatic = new Task($db); $userstatic=new User($db); +$varpage=empty($contextpage)?$_SERVER["PHP_SELF"]:$contextpage; +$selectedfields=$form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields + $title=$langs->trans("Project").' - '.$langs->trans("Tasks").' - '.$object->ref.' '.$object->name; if (! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/projectnameonly/', $conf->global->MAIN_HTML_TITLE) && $object->name) $title=$object->ref.' '.$object->name.' - '.$langs->trans("Tasks"); $help_url="EN:Module_Projects|FR:Module_Projets|ES:Módulo_Proyectos"; @@ -624,7 +680,7 @@ elseif ($id > 0 || ! empty($ref)) // Get list of tasks in tasksarray and taskarrayfiltered // We need all tasks (even not limited to a user because a task to user can have a parent that is not affected to him). $filteronthirdpartyid = $socid; - $tasksarray=$taskstatic->getTasksArray(0, 0, $object->id, $filteronthirdpartyid, 0, '', -1, $morewherefilter); + $tasksarray=$taskstatic->getTasksArray(0, 0, $object->id, $filteronthirdpartyid, 0, '', -1, $morewherefilter, 0, 0, 1); // We load also tasks limited to a particular user $tmpuser=new User($db); if ($search_user_id > 0) $tmpuser->fetch($search_user_id); @@ -699,6 +755,15 @@ elseif ($id > 0 || ! empty($ref)) print ''; print ''; + if ($object->bill_time) + { + print ''; + print ''; + + print ''; + print ''; + } + if (! empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST)) print ''; // Action column @@ -718,6 +783,11 @@ elseif ($id > 0 || ! empty($ref)) print_liste_field_titre("TimeSpent", $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'right '); print_liste_field_titre("ProgressCalculated", $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'right '); print_liste_field_titre("ProgressDeclared", $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'right '); + if ($object->bill_time) + { + print_liste_field_titre("TimeToBill", $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'right '); + print_liste_field_titre("TimeBilled", $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'right '); + } if (! empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST)) print_liste_field_titre("TaskRessourceLinks", $_SERVER["PHP_SELF"], '', '', '', $sortfield, $sortorder); print_liste_field_titre('', $_SERVER["PHP_SELF"], "", '', '', 'width="80"', $sortfield, $sortorder, 'center maxwidthsearch '); print "\n"; @@ -726,11 +796,13 @@ elseif ($id > 0 || ! empty($ref)) { // Show all lines in taskarray (recursive function to go down on tree) $j=0; $level=0; - $nboftaskshown=projectLinesa($j, 0, $tasksarray, $level, true, 0, $tasksrole, $object->id, 1, $object->id, $filterprogresscalc); + $nboftaskshown=projectLinesa($j, 0, $tasksarray, $level, true, 0, $tasksrole, $object->id, 1, $object->id, $filterprogresscalc, ($object->bill_time?1:0)); } else { - print ''.$langs->trans("NoTasks").''; + $colspan=10; + if ($object->bill_time) $colspan+=2; + print ''.$langs->trans("NoTasks").''; } print ""; diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index 7293850f212..a7906b63b3c 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -21,7 +21,7 @@ /** * \file htdocs/projet/tasks/list.php * \ingroup project - * \brief List all task of a project + * \brief List all tasks of a project */ require "../../main.inc.php";