mirror of
https://github.com/Dolibarr/dolibarr.git
synced 2025-12-06 17:48:25 +01:00
Fix task widget and improve its display
This commit is contained in:
@@ -42,7 +42,7 @@ class box_task extends ModeleBoxes
|
||||
public $db;
|
||||
|
||||
public $param;
|
||||
public $enabled = 0; // Disabled because bugged.
|
||||
public $enabled = 1; // enable because fixed ;-).
|
||||
|
||||
public $info_box_head = array();
|
||||
public $info_box_contents = array();
|
||||
@@ -86,21 +86,31 @@ class box_task extends ModeleBoxes
|
||||
$totaldurationtot=0;
|
||||
|
||||
include_once DOL_DOCUMENT_ROOT."/projet/class/task.class.php";
|
||||
include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT."/core/lib/project.lib.php";
|
||||
$projectstatic = new Project($this->db);
|
||||
$taskstatic=new Task($db);
|
||||
|
||||
|
||||
$textHead = $langs->trans("Tasks")." ".date("Y");
|
||||
$textHead = $langs->trans("CurentlyOpenedTasks");
|
||||
$this->info_box_head = array('text' => $textHead, 'limit'=> dol_strlen($textHead));
|
||||
|
||||
// list the summary of the orders
|
||||
if ($user->rights->projet->lire) {
|
||||
// FIXME fk_statut on a task is not be used. We use the percent. This means this box is useless.
|
||||
$sql = "SELECT pt.fk_statut, count(DISTINCT pt.rowid) as nb, sum(ptt.task_duration) as durationtot, sum(pt.planned_workload) as plannedtot";
|
||||
$sql.= " FROM ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."projet_task_time as ptt";
|
||||
$sql.= " WHERE pt.datec BETWEEN '".$this->db->idate(dol_get_first_day(date("Y"), 1))."' AND '".$this->db->idate(dol_get_last_day(date("Y"), 12))."'";
|
||||
$sql.= " AND pt.rowid = ptt.fk_task";
|
||||
$sql.= " GROUP BY pt.fk_statut ";
|
||||
$sql.= " ORDER BY pt.fk_statut DESC";
|
||||
|
||||
$sql = "SELECT pt.rowid, pt.ref, pt.fk_projet, pt.fk_task_parent, pt.datec, pt.dateo, pt.datee, pt.datev, pt.label, pt.description, pt.duration_effective, pt.planned_workload, pt.progress";
|
||||
$sql.= ", p.rowid project_id, p.ref project_ref, p.title project_title";
|
||||
|
||||
|
||||
$sql.= " FROM ".MAIN_DB_PREFIX."projet_task as pt";
|
||||
$sql.= " JOIN ".MAIN_DB_PREFIX."projet as p ON (pt.fk_projet = p.rowid)";
|
||||
|
||||
$sql.= " WHERE ";
|
||||
$sql.= " pt.entity = ".$conf->entity;
|
||||
$sql.= " AND p.fk_statut = ".Project::STATUS_VALIDATED;
|
||||
$sql.= " AND (pt.progress < 100 OR pt.progress IS NULL ) "; // 100% is done and not displayed
|
||||
|
||||
$sql.= " ORDER BY pt.datee ASC, pt.dateo ASC";
|
||||
$sql.= $db->plimit($max, 0);
|
||||
|
||||
$result = $db->query($sql);
|
||||
@@ -109,23 +119,31 @@ class box_task extends ModeleBoxes
|
||||
$num = $db->num_rows($result);
|
||||
while ($i < $num) {
|
||||
$objp = $db->fetch_object($result);
|
||||
|
||||
$taskstatic->id=$objp->rowid;
|
||||
$taskstatic->ref=$objp->ref;
|
||||
$taskstatic->label=$objp->label;
|
||||
$taskstatic->progress = $objp->progress;
|
||||
$taskstatic->fk_statut = $objp->fk_statut;
|
||||
$taskstatic->date_end = $objp->datee;
|
||||
$taskstatic->planned_workload= $objp->planned_workload;
|
||||
$taskstatic->duration_effective= $objp->duration_effective;
|
||||
|
||||
$projectstatic->id = $objp->project_id;
|
||||
$projectstatic->ref = $objp->project_ref;
|
||||
$projectstatic->title = $objp->project_title;
|
||||
|
||||
$label = $projectstatic->getNomUrl(1).' '.$taskstatic->getNomUrl(1).' '.dol_htmlentities($taskstatic->label);
|
||||
|
||||
|
||||
$this->info_box_contents[$i][] = array(
|
||||
'td' => '',
|
||||
'text' =>$langs->trans("Task")." ".$taskstatic->LibStatut($objp->fk_statut, 0),
|
||||
'text' =>getTaskProgressView($taskstatic, $label),
|
||||
);
|
||||
|
||||
$this->info_box_contents[$i][] = array(
|
||||
'td' => 'class="right"',
|
||||
'text' => $objp->nb." ".$langs->trans("Tasks"),
|
||||
'url' => DOL_URL_ROOT."/projet/tasks/list.php?leftmenu=projects&viewstatut=".$objp->fk_statut,
|
||||
);
|
||||
$totalnb += $objp->nb;
|
||||
$this->info_box_contents[$i][] = array('td' => 'class="right"', 'text' => ConvertSecondToTime($objp->plannedtot, 'all', 25200, 5));
|
||||
$totalplannedtot += $objp->plannedtot;
|
||||
$this->info_box_contents[$i][] = array('td' => 'class="right"', 'text' => ConvertSecondToTime($objp->durationtot, 'all', 25200, 5));
|
||||
$totaldurationtot += $objp->durationtot;
|
||||
|
||||
$this->info_box_contents[$i][] = array('td' => 'class="right" width="18"', 'text' => $taskstatic->LibStatut($objp->fk_statut, 3));
|
||||
|
||||
|
||||
|
||||
$i++;
|
||||
}
|
||||
@@ -134,12 +152,7 @@ class box_task extends ModeleBoxes
|
||||
}
|
||||
}
|
||||
|
||||
// Add the sum at the bottom of the boxes
|
||||
$this->info_box_contents[$i][] = array('tr' => 'class="liste_total"', 'td' => '', 'text' => $langs->trans("Total")." ".$textHead);
|
||||
$this->info_box_contents[$i][] = array('td' => 'class="right" ', 'text' => number_format($totalnb, 0, ',', ' ')." ".$langs->trans("Tasks"));
|
||||
$this->info_box_contents[$i][] = array('td' => 'class="right" ', 'text' => ConvertSecondToTime($totalplannedtot, 'all', 25200, 5));
|
||||
$this->info_box_contents[$i][] = array('td' => 'class="right" ', 'text' => ConvertSecondToTime($totaldurationtot, 'all', 25200, 5));
|
||||
$this->info_box_contents[$i][] = array('td' => '', 'text' => "");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1956,9 +1956,10 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks
|
||||
* @param $task Task
|
||||
* @param $label string|bool true = auto, false = dont display, string = replace output
|
||||
* @param $progressNumber string|bool true = auto, false = dont display, string = replace output
|
||||
* @param $hideOnProgressNull bool
|
||||
* @return string
|
||||
*/
|
||||
function getTaskProgressView($task, $label = true, $progressNumber = true)
|
||||
function getTaskProgressView($task, $label = true, $progressNumber = true, $hideOnProgressNull = false, $showPercent = false)
|
||||
{
|
||||
global $langs, $conf;
|
||||
|
||||
@@ -1969,79 +1970,91 @@ function getTaskProgressView($task, $label = true, $progressNumber = true)
|
||||
if (! empty($conf->global->PROJECT_PLANNED_WORKLOAD_FORMAT)) $plannedworkloadoutputformat=$conf->global->PROJECT_PLANNED_WORKLOAD_FORMAT;
|
||||
if (! empty($conf->global->PROJECT_TIMES_SPENT_FORMAT)) $timespentoutputformat=$conf->global->PROJECT_TIME_SPENT_FORMAT;
|
||||
|
||||
|
||||
|
||||
if ($task->progress != '')
|
||||
{
|
||||
|
||||
// define progress color according to time spend vs workload
|
||||
$progressBarClass = 'progress-bar-info';
|
||||
if ($task->planned_workload){
|
||||
$progressCalculated = round(100 * doubleval($task->duration_effective) / doubleval($task->planned_workload), 2);
|
||||
|
||||
// this conf is actually hidden, by default we use 1% for "be carefull or warning"
|
||||
$warningRatio = !empty($conf->global->PROJECT_TIME_SPEND_WARNING_PERCENT) ? (1 + $conf->global->PROJECT_TIME_SPEND_WARNING_PERCENT / 100) : 1.01;
|
||||
|
||||
if($progressCalculated > doubleval($task->progress)){
|
||||
$progressBarClass = 'progress-bar-danger';
|
||||
}
|
||||
elseif($progressCalculated * $warningRatio >= doubleval($task->progress)){ // warning if close at 1%
|
||||
$progressBarClass = 'progress-bar-warning';
|
||||
}
|
||||
else{
|
||||
$progressBarClass = 'progress-bar-success';
|
||||
}
|
||||
}
|
||||
|
||||
$out.= '<div class="progress-group">';
|
||||
|
||||
if($label !== false)
|
||||
{
|
||||
$out.= ' <span class="progress-text">';
|
||||
if ($task->hasDelay()) $out.= img_warning($langs->trans("Late")).' ';
|
||||
if($label!==true){
|
||||
$out.= $label; // replace label by param
|
||||
}
|
||||
else{
|
||||
$out.= $task->label;
|
||||
}
|
||||
$out.= ' </span>';
|
||||
}
|
||||
|
||||
|
||||
if($progressNumber !== false)
|
||||
{
|
||||
$out.= ' <span class="progress-number">';
|
||||
|
||||
if($progressNumber!==true){
|
||||
$out.= $progressNumber; // replace label by param
|
||||
}
|
||||
else{
|
||||
$out.= '<b title="'.$langs->trans('TimeSpent').'" >';
|
||||
if ($task->duration_effective) $out.= convertSecondToTime($task->duration_effective, $timespentoutputformat);
|
||||
else $out.= '--:--';
|
||||
$out.= '</b>';
|
||||
|
||||
$out.= '/';
|
||||
|
||||
$out.= '<span title="'.$langs->trans('PlannedWorkload').'" >';
|
||||
if ($task->planned_workload) $out.= convertSecondToTime($task->planned_workload, $plannedworkloadoutputformat);
|
||||
else $out.= '--:--';
|
||||
}
|
||||
|
||||
$out.= ' </span>';
|
||||
}
|
||||
|
||||
|
||||
|
||||
$out.= '</span>';
|
||||
$out.= ' <div class="progress sm">';
|
||||
$out.= ' <div title="'.price($task->progress).'%" class="progress-bar '.$progressBarClass.'" style="width: '.doubleval($task->progress).'%"></div>';
|
||||
$out.= ' </div>';
|
||||
$out.= '</div>';
|
||||
|
||||
if(empty($task->progress) && !empty($hideOnProgressNull)){
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
$diff = '';
|
||||
|
||||
// define progress color according to time spend vs workload
|
||||
$progressBarClass = 'progress-bar-info';
|
||||
if ($task->planned_workload){
|
||||
$progressCalculated = round(100 * doubleval($task->duration_effective) / doubleval($task->planned_workload), 2);
|
||||
|
||||
// this conf is actually hidden, by default we use 1% for "be carefull or warning"
|
||||
$warningRatio = !empty($conf->global->PROJECT_TIME_SPEND_WARNING_PERCENT) ? (1 + $conf->global->PROJECT_TIME_SPEND_WARNING_PERCENT / 100) : 1.01;
|
||||
|
||||
$diffTitle = '<br/>'.$langs->trans('ProgressDeclared').' : '.price($task->progress).'%';
|
||||
$diffTitle.= '<br/>'.$langs->trans('ProgressCalculated').' : '.price($progressCalculated).'%';
|
||||
|
||||
if($progressCalculated > doubleval($task->progress)){
|
||||
$progressBarClass = 'progress-bar-danger';
|
||||
$title = $langs->trans('TheReportedProgressIsLessThanTheCalculatedProgressionByX', price(abs($task->progress-$progressCalculated)).'%');
|
||||
$diff = '<span class="text-danger classfortooltip"" title="'.dol_htmlentities($title.$diffTitle).'" ><i class="fa fa-caret-down"></i> '.price($task->progress-$progressCalculated).'%</span>';
|
||||
}
|
||||
elseif($progressCalculated * $warningRatio >= doubleval($task->progress)){ // warning if close at 1%
|
||||
$progressBarClass = 'progress-bar-warning';
|
||||
$title = $langs->trans('TheReportedProgressIsLessThanTheCalculatedProgressionByX', price(abs($task->progress-$progressCalculated)).'%');
|
||||
$diff = '<span class="text-warning classfortooltip" title="'.dol_htmlentities($title.$diffTitle).'" ><i class="fa fa-caret-left"></i> '.price($task->progress-$progressCalculated).'%</span>';
|
||||
}
|
||||
else{
|
||||
$progressBarClass = 'progress-bar-success';
|
||||
$title = $langs->trans('TheReportedProgressIsMoreThanTheCalculatedProgressionByX', price($task->progress-$progressCalculated).'%');
|
||||
$diff = '<span class="text-success classfortooltip" title="'.dol_htmlentities($title.$diffTitle).'" ><i class="fa fa-caret-up"></i> '.price($task->progress-$progressCalculated).'%</span>';
|
||||
}
|
||||
}
|
||||
|
||||
$out.= '<div class="progress-group">';
|
||||
|
||||
if($label !== false)
|
||||
{
|
||||
$out.= ' <span class="progress-text">';
|
||||
if ($task->hasDelay()) $out.= img_warning($langs->trans("Late")).' ';
|
||||
if($label!==true){
|
||||
$out.= $label; // replace label by param
|
||||
}
|
||||
else{
|
||||
$out.= $task->getNomUrl(1).' '.dol_htmlentities($task->label);
|
||||
}
|
||||
$out.= ' </span>';
|
||||
}
|
||||
|
||||
|
||||
if($progressNumber !== false)
|
||||
{
|
||||
$out.= ' <span class="progress-number">';
|
||||
if($progressNumber!==true){
|
||||
$out.= $progressNumber; // replace label by param
|
||||
}
|
||||
else{
|
||||
|
||||
$out.= !empty($diff) ? $diff.' ':'';
|
||||
|
||||
$out.= '<b title="'.$langs->trans('TimeSpent').'" >';
|
||||
if ($task->duration_effective) $out.= convertSecondToTime($task->duration_effective, $timespentoutputformat);
|
||||
else $out.= '--:--';
|
||||
$out.= '</b>';
|
||||
|
||||
$out.= '/';
|
||||
|
||||
$out.= '<span title="'.$langs->trans('PlannedWorkload').'" >';
|
||||
if ($task->planned_workload) $out.= convertSecondToTime($task->planned_workload, $plannedworkloadoutputformat);
|
||||
else $out.= '--:--';
|
||||
}
|
||||
$out.= ' </span>';
|
||||
}
|
||||
|
||||
|
||||
|
||||
$out.= '</span>';
|
||||
$out.= ' <div class="progress sm classfortooltip" title="'.price($task->progress).'%" >';
|
||||
$out.= ' <div class="progress-bar '.$progressBarClass.'" style="width: '.doubleval($task->progress).'%"></div>';
|
||||
$out.= ' </div>';
|
||||
$out.= '</div>';
|
||||
|
||||
|
||||
|
||||
return $out;
|
||||
}
|
||||
/**
|
||||
@@ -2055,10 +2068,12 @@ function getTaskProgressBadge($task, $label = '', $tooltip = '')
|
||||
global $conf;
|
||||
|
||||
$out = '';
|
||||
|
||||
$label = '';
|
||||
$badgeColorClass = '';
|
||||
if ($task->progress != '')
|
||||
{
|
||||
// TODO : manage 100%
|
||||
|
||||
// define color according to time spend vs workload
|
||||
$badgeColorClass = 'badge ';
|
||||
if ($task->planned_workload){
|
||||
@@ -2080,7 +2095,7 @@ function getTaskProgressBadge($task, $label = '', $tooltip = '')
|
||||
}
|
||||
|
||||
if(empty($label)){
|
||||
$label = $task->progress.' %';
|
||||
$label = price($task->progress).' %';
|
||||
}
|
||||
|
||||
if(!empty($label)){
|
||||
|
||||
@@ -77,6 +77,9 @@ MyProjectsArea=My projects Area
|
||||
DurationEffective=Effective duration
|
||||
ProgressDeclared=Declared progress
|
||||
TaskProgressSummary=Task progress
|
||||
CurentlyOpenedTasks=Curently opened tasks
|
||||
TheReportedProgressIsLessThanTheCalculatedProgressionByX=The declared progress is less %s than the calculated progression
|
||||
TheReportedProgressIsMoreThanTheCalculatedProgressionByX=The declared progress is more %s than the calculated progression
|
||||
ProgressCalculated=Calculated progress
|
||||
Time=Time
|
||||
ListOfTasks=List of tasks
|
||||
|
||||
@@ -493,6 +493,24 @@ textarea.centpercent {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.text-warning{
|
||||
color : <?php print $textWarning ; ?>
|
||||
}
|
||||
body[class*="colorblind-"] .text-warning{
|
||||
color : <?php print $colorblind_deuteranopes_textWarning ; ?>
|
||||
}
|
||||
.text-success{
|
||||
color : <?php print $textSuccess ; ?>
|
||||
}
|
||||
body[class*="colorblind-"] .text-success{
|
||||
color : <?php print $colorblind_deuteranopes_textSuccess ; ?>
|
||||
}
|
||||
|
||||
.text-danger{
|
||||
color : <?php print $textDanger ; ?>
|
||||
}
|
||||
|
||||
|
||||
/* Themes for badges */
|
||||
<?php include dol_buildpath($path.'/theme/'.$theme.'/badges.inc.php', 0); ?>
|
||||
|
||||
|
||||
@@ -129,6 +129,8 @@ if (! defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet'); ?>
|
||||
float: right;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Remove margins from progress bars when put in a table */
|
||||
.table tr > td .progress {
|
||||
margin: 0;
|
||||
|
||||
@@ -67,6 +67,14 @@ $topMenuFontSize='1.2em';
|
||||
$toolTipBgColor='rgba(255, 255, 255, 0.96);';
|
||||
$toolTipFontColor='#333';
|
||||
|
||||
// text color
|
||||
$textSuccess ='#28a745';
|
||||
$colorblind_deuteranopes_textSuccess ='#37de5d';
|
||||
$textDanger ='#dc3545';
|
||||
$textWarning ='#f39c12';
|
||||
$colorblind_deuteranopes_textWarning = $textWarning; // currently not tested with a color blind people so use default color
|
||||
|
||||
|
||||
// Badges colors
|
||||
$badgePrimary ='#007bff';
|
||||
$badgeSecondary ='#999999';
|
||||
@@ -84,7 +92,7 @@ $colorblind_deuteranopes_badgeWarning ='#e4e411';
|
||||
|
||||
/* default color for status : After a quick check, somme status can have oposite function according to objects
|
||||
* So this badges status uses default value according to theme eldy status img
|
||||
* TODO: use color definition vars above for define badges color status X -> expemple $badgeStatusValidate, $badgeStatusClosed, $badgeStatusActive ....
|
||||
* TODO: use color definition vars above for define badges color status X -> exemple $badgeStatusValidate, $badgeStatusClosed, $badgeStatusActive ....
|
||||
*/
|
||||
$badgeStatus0='#cbd3d3';
|
||||
$badgeStatus1='#bc9526';
|
||||
|
||||
Reference in New Issue
Block a user