added working template of compare hours
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Kanboard\Controller;
|
||||
use Kanboard\Model\Task as TaskModel;
|
||||
|
||||
/**
|
||||
* Project Analytic controller
|
||||
@@ -166,4 +167,27 @@ class Analytic extends Base
|
||||
'title' => t($title, $project['name']),
|
||||
)));
|
||||
}
|
||||
|
||||
public function compareHours()
|
||||
{
|
||||
$project = $this->getProject();
|
||||
$params = $this->getProjectFilters('analytic', 'compareHours');
|
||||
$query = $this->taskFilter->search('status:all')->filterByProject($params['project']['id'])->getQuery();
|
||||
|
||||
|
||||
$paginator = $this->paginator
|
||||
->setUrl('analytics', 'compare_hours')
|
||||
->setMax(30)
|
||||
->setOrder(TaskModel::TABLE.'.id')
|
||||
->setQuery($query)
|
||||
->calculate();
|
||||
|
||||
$stats = $this->projectAnalytic->getHoursByStatus($project['id']);
|
||||
|
||||
$this->response->html($this->layout('analytic/compare_hours', array(
|
||||
'project' => $project,
|
||||
'paginator' => $paginator,
|
||||
'metrics' => $stats,
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,4 +179,44 @@ class ProjectAnalytic extends Base
|
||||
|
||||
return $stats;
|
||||
}
|
||||
|
||||
|
||||
public function getHoursByStatus($project_id)
|
||||
{
|
||||
$stats = array();
|
||||
$columns = $this->board->getColumnsList($project_id);
|
||||
|
||||
// Get the time spent of the last move for each tasks
|
||||
$tasks = $this->db
|
||||
->table(Task::TABLE)
|
||||
->columns('id', 'time_estimated', 'time_spent', 'is_active')
|
||||
->eq('project_id', $project_id)
|
||||
->desc('id')
|
||||
->limit(1000)
|
||||
->findAll();
|
||||
|
||||
// Init values
|
||||
$stats['closed'] = array(
|
||||
'time_spent' => 0,
|
||||
'time_estimated' => 0,
|
||||
);
|
||||
$stats['open'] = array(
|
||||
'time_spent' => 0,
|
||||
'time_estimated' => 0,
|
||||
);
|
||||
|
||||
|
||||
// Get time spent foreach task/column and take into account the last move
|
||||
foreach ($tasks as &$task) {
|
||||
if ($task['is_active']) {
|
||||
$stats['open']['time_estimated'] += $task['time_estimated'];
|
||||
$stats['open']['time_spent'] += $task['time_spent'];
|
||||
} else {
|
||||
$stats['closed']['time_estimated'] += $task['time_estimated'];
|
||||
$stats['closed']['time_spent'] += $task['time_spent'];
|
||||
}
|
||||
}
|
||||
|
||||
return $stats;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +122,7 @@ class TaskFinder extends Base
|
||||
'tasks.recurrence_parent',
|
||||
'tasks.recurrence_child',
|
||||
'tasks.time_estimated',
|
||||
'tasks.time_spent',
|
||||
User::TABLE.'.username AS assignee_username',
|
||||
User::TABLE.'.name AS assignee_name',
|
||||
Category::TABLE.'.name AS category_name',
|
||||
|
||||
57
app/Template/analytic/compare_hours.php
Normal file
57
app/Template/analytic/compare_hours.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<div class="page-header">
|
||||
<h2><?= t('Compare Estimated Time vs Actual Time') ?></h2>
|
||||
</div>
|
||||
|
||||
<div class="listing">
|
||||
<ul>
|
||||
<li><?= t('Estimated hours: ').'<strong>'.$this->e($metrics['open']['time_estimated']+$metrics['open']['time_estimated']) ?></strong></li>
|
||||
<li><?= t('Actual hours: ').'<strong>'.$this->e($metrics['open']['time_spent']+$metrics['closed']['time_spent']) ?></strong></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<?php if (empty($metrics)): ?>
|
||||
<p class="alert"><?= t('Not enough data to show the graph.') ?></p>
|
||||
<?php else: ?>
|
||||
<section id="analytic-compare-hours">
|
||||
<div id="chart" data-metrics='<?= json_encode($metrics, JSON_HEX_APOS)?>' data-label-spent="<?= t('Hours Spent') ?>" data-label-estimated="<?= t('Hours Estimated') ?>"></div>
|
||||
|
||||
<?php if ($paginator->isEmpty()): ?>
|
||||
<p class="alert"><?= t('No tasks found.') ?></p>
|
||||
<?php elseif (! $paginator->isEmpty()): ?>
|
||||
<table class="table-fixed table-small">
|
||||
<tr>
|
||||
<th class="column-5"><?= $paginator->order(t('Id'), 'tasks.id') ?></th>
|
||||
<th><?= $paginator->order(t('Title'), 'tasks.title') ?></th>
|
||||
<th class="column-5"><?= $paginator->order(t('Status'), 'tasks.is_active') ?></th>
|
||||
<th class="column-10"><?= $paginator->order(t('Estimated Time'), 'tasks.time_estimated') ?></th>
|
||||
<th class="column-10"><?= $paginator->order(t('Actual Time'), 'tasks.time_spent') ?></th>
|
||||
</tr>
|
||||
<?php foreach ($paginator->getCollection() as $task): ?>
|
||||
<tr>
|
||||
<td class="task-table color-<?= $task['color_id'] ?>">
|
||||
<?= $this->url->link('#'.$this->e($task['id']), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?>
|
||||
</td>
|
||||
<td>
|
||||
<?= $this->url->link($this->e($task['title']), 'task', 'show', array('task_id' => $task['id'], 'project_id' => $task['project_id']), false, '', t('View this task')) ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($task['is_active'] == \Kanboard\Model\Task::STATUS_OPEN): ?>
|
||||
<?= t('Open') ?>
|
||||
<?php else: ?>
|
||||
<?= t('Closed') ?>
|
||||
<?php endif ?>
|
||||
</td>
|
||||
<td>
|
||||
<?= $this->e($task['time_estimated']) ?>
|
||||
</td>
|
||||
<td>
|
||||
<?= $this->e($task['time_spent']) ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach ?>
|
||||
</table>
|
||||
|
||||
<?= $paginator ?>
|
||||
<?php endif ?>
|
||||
</section>
|
||||
<?php endif ?>
|
||||
@@ -19,7 +19,10 @@
|
||||
<li <?= $this->app->getRouterAction() === 'leadandcycletime' ? 'class="active"' : '' ?>>
|
||||
<?= $this->url->link(t('Lead and cycle time'), 'analytic', 'leadAndCycleTime', array('project_id' => $project['id'])) ?>
|
||||
</li>
|
||||
<li <?= $this->app->getRouterAction() === 'comparehours' ? 'class="active"' : '' ?>>
|
||||
<?= $this->url->link(t('Compare hours'), 'analytic', 'compareHours', array('project_id' => $project['id'])) ?>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="sidebar-collapse"><a href="#" title="<?= t('Hide sidebar') ?>"><i class="fa fa-chevron-left"></i></a></div>
|
||||
<div class="sidebar-expand" style="display: none"><a href="#" title="<?= t('Expand sidebar') ?>"><i class="fa fa-chevron-right"></i></a></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user