diff options
-rw-r--r-- | app/Controller/Base.php | 1 | ||||
-rw-r--r-- | app/Controller/Task.php | 1 | ||||
-rw-r--r-- | app/Model/Base.php | 69 | ||||
-rw-r--r-- | app/Model/Subtask.php | 39 | ||||
-rw-r--r-- | app/Model/TimeTracking.php | 45 | ||||
-rw-r--r-- | app/Subscriber/Base.php | 2 | ||||
-rw-r--r-- | app/Template/task/show.php | 2 | ||||
-rw-r--r-- | app/Template/task/timesheet.php | 8 | ||||
-rw-r--r-- | assets/css/app.css | 4 | ||||
-rw-r--r-- | assets/css/src/confirm.css | 2 | ||||
-rw-r--r-- | assets/css/src/form.css | 1 | ||||
-rw-r--r-- | tests/units/TimeTrackingTest.php | 48 |
12 files changed, 85 insertions, 137 deletions
diff --git a/app/Controller/Base.php b/app/Controller/Base.php index ac7e8907..7f65e882 100644 --- a/app/Controller/Base.php +++ b/app/Controller/Base.php @@ -56,6 +56,7 @@ use Symfony\Component\EventDispatcher\Event; * @property \Model\TaskValidator $taskValidator * @property \Model\CommentHistory $commentHistory * @property \Model\SubtaskHistory $subtaskHistory + * @property \Model\SubtaskTimeTracking $subtaskTimeTracking * @property \Model\TimeTracking $timeTracking * @property \Model\User $user * @property \Model\UserSession $userSession diff --git a/app/Controller/Task.php b/app/Controller/Task.php index 626ac9e6..67dfe14f 100644 --- a/app/Controller/Task.php +++ b/app/Controller/Task.php @@ -72,7 +72,6 @@ class Task extends Base 'subtasks' => $subtasks, 'task' => $task, 'values' => $values, - 'timesheet' => $this->timeTracking->getTaskTimesheet($task, $subtasks), 'columns_list' => $this->board->getColumnsList($task['project_id']), 'colors_list' => $this->color->getList(), 'date_format' => $this->config->get('application_date_format'), diff --git a/app/Model/Base.php b/app/Model/Base.php index cf5f2e9f..319e53fc 100644 --- a/app/Model/Base.php +++ b/app/Model/Base.php @@ -10,40 +10,41 @@ use Pimple\Container; * @package model * @author Frederic Guillot * - * @property \Core\Session $session - * @property \Core\Template $template - * @property \Model\Acl $acl - * @property \Model\Action $action - * @property \Model\Authentication $authentication - * @property \Model\Board $board - * @property \Model\Category $category - * @property \Model\Comment $comment - * @property \Model\CommentHistory $commentHistory - * @property \Model\Color $color - * @property \Model\Config $config - * @property \Model\DateParser $dateParser - * @property \Model\File $file - * @property \Model\Helper $helper - * @property \Model\LastLogin $lastLogin - * @property \Model\Notification $notification - * @property \Model\Project $project - * @property \Model\ProjectDuplication $projectDuplication - * @property \Model\ProjectPermission $projectPermission - * @property \Model\Subtask $subtask - * @property \Model\SubtaskHistory $subtaskHistory - * @property \Model\Swimlane $swimlane - * @property \Model\Task $task - * @property \Model\TaskCreation $taskCreation - * @property \Model\TaskDuplication $taskDuplication - * @property \Model\TaskExport $taskExport - * @property \Model\TaskFinder $taskFinder - * @property \Model\TaskHistory $taskHistory - * @property \Model\TaskPosition $taskPosition - * @property \Model\TaskValidator $taskValidator - * @property \Model\TimeTracking $timeTracking - * @property \Model\User $user - * @property \Model\UserSession $userSession - * @property \Model\Webhook $webhook + * @property \Core\Session $session + * @property \Core\Template $template + * @property \Model\Acl $acl + * @property \Model\Action $action + * @property \Model\Authentication $authentication + * @property \Model\Board $board + * @property \Model\Category $category + * @property \Model\Comment $comment + * @property \Model\CommentHistory $commentHistory + * @property \Model\Color $color + * @property \Model\Config $config + * @property \Model\DateParser $dateParser + * @property \Model\File $file + * @property \Model\Helper $helper + * @property \Model\LastLogin $lastLogin + * @property \Model\Notification $notification + * @property \Model\Project $project + * @property \Model\ProjectDuplication $projectDuplication + * @property \Model\ProjectPermission $projectPermission + * @property \Model\Subtask $subtask + * @property \Model\SubtaskHistory $subtaskHistory + * @property \Model\Swimlane $swimlane + * @property \Model\Task $task + * @property \Model\TaskCreation $taskCreation + * @property \Model\TaskDuplication $taskDuplication + * @property \Model\TaskExport $taskExport + * @property \Model\TaskFinder $taskFinder + * @property \Model\TaskHistory $taskHistory + * @property \Model\TaskPosition $taskPosition + * @property \Model\TaskValidator $taskValidator + * @property \Model\TimeTracking $timeTracking + * @property \Model\SubtaskTimeTracking $subtaskTimeTracking + * @property \Model\User $user + * @property \Model\UserSession $userSession + * @property \Model\Webhook $webhook */ abstract class Base { diff --git a/app/Model/Subtask.php b/app/Model/Subtask.php index 9ecd2c6a..1d5ed566 100644 --- a/app/Model/Subtask.php +++ b/app/Model/Subtask.php @@ -176,6 +176,9 @@ class Subtask extends Base $subtask_id = $this->persist(self::TABLE, $values); if ($subtask_id) { + + $this->updateTaskTimeTracking($values['task_id']); + $this->container['dispatcher']->dispatch( self::EVENT_CREATE, new SubtaskEvent(array('id' => $subtask_id) + $values) @@ -198,6 +201,11 @@ class Subtask extends Base $result = $this->db->table(self::TABLE)->eq('id', $values['id'])->save($values); if ($result) { + + if (isset($values['task_id'])) { + $this->updateTaskTimeTracking($values['task_id']); + } + $this->container['dispatcher']->dispatch( self::EVENT_UPDATE, new SubtaskEvent($values) @@ -260,6 +268,37 @@ class Subtask extends Base } /** + * Update task time tracking based on subtasks time tracking + * + * @access public + * @param integer $task_id Task id + * @return bool + */ + public function updateTaskTimeTracking($task_id) + { + $result = $this->db + ->table(self::TABLE) + ->eq('task_id', $task_id) + ->columns( + 'SUM(time_spent) AS total_spent', + 'SUM(time_estimated) AS total_estimated' + ) + ->findOne(); + + if (empty($result['total_spent']) && empty($result['total_estimated'])) { + return true; + } + + return $this->db + ->table(Task::TABLE) + ->eq('id', $task_id) + ->update(array( + 'time_spent' => $result['total_spent'], + 'time_estimated' => $result['total_estimated'], + )); + } + + /** * Remove * * @access public diff --git a/app/Model/TimeTracking.php b/app/Model/TimeTracking.php deleted file mode 100644 index 4ddddf12..00000000 --- a/app/Model/TimeTracking.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php - -namespace Model; - -/** - * Time tracking model - * - * @package model - * @author Frederic Guillot - */ -class TimeTracking extends Base -{ - /** - * Calculate time metrics for a task - * - * Use subtasks time metrics if not empty otherwise return task time metrics - * - * @access public - * @param array $task Task properties - * @param array $subtasks Subtasks list - * @return array - */ - public function getTaskTimesheet(array $task, array $subtasks) - { - $timesheet = array( - 'time_spent' => 0, - 'time_estimated' => 0, - 'time_remaining' => 0, - ); - - foreach ($subtasks as &$subtask) { - $timesheet['time_estimated'] += $subtask['time_estimated']; - $timesheet['time_spent'] += $subtask['time_spent']; - } - - if ($timesheet['time_estimated'] == 0 && $timesheet['time_spent'] == 0) { - $timesheet['time_estimated'] = $task['time_estimated']; - $timesheet['time_spent'] = $task['time_spent']; - } - - $timesheet['time_remaining'] = $timesheet['time_estimated'] - $timesheet['time_spent']; - - return $timesheet; - } -} diff --git a/app/Subscriber/Base.php b/app/Subscriber/Base.php index 19f41c84..489d49b0 100644 --- a/app/Subscriber/Base.php +++ b/app/Subscriber/Base.php @@ -16,12 +16,14 @@ use Pimple\Container; * @property \Model\Notification $notification * @property \Model\Project $project * @property \Model\ProjectPermission $projectPermission + * @property \Model\ProjectActivity $projectActivity * @property \Model\ProjectAnalytic $projectAnalytic * @property \Model\ProjectDailySummary $projectDailySummary * @property \Model\Subtask $subtask * @property \Model\Task $task * @property \Model\TaskExport $taskExport * @property \Model\TaskFinder $taskFinder + * @property \Model\SubtaskTimeTracking $subtaskTimeTracking * @property \Model\UserSession $userSession * @property \Model\Webhook $webhook */ diff --git a/app/Template/task/show.php b/app/Template/task/show.php index 3bc6796f..b8243cc6 100644 --- a/app/Template/task/show.php +++ b/app/Template/task/show.php @@ -2,6 +2,6 @@ <?= $this->render('task/time', array('task' => $task, 'values' => $values, 'date_format' => $date_format, 'date_formats' => $date_formats)) ?> <?= $this->render('task/show_description', array('task' => $task)) ?> <?= $this->render('subtask/show', array('task' => $task, 'subtasks' => $subtasks)) ?> -<?= $this->render('task/timesheet', array('timesheet' => $timesheet)) ?> +<?= $this->render('task/timesheet', array('task' => $task)) ?> <?= $this->render('file/show', array('task' => $task, 'files' => $files)) ?> <?= $this->render('task/comments', array('task' => $task, 'comments' => $comments, 'project' => $project)) ?>
\ No newline at end of file diff --git a/app/Template/task/timesheet.php b/app/Template/task/timesheet.php index fa76b84d..0210be7e 100644 --- a/app/Template/task/timesheet.php +++ b/app/Template/task/timesheet.php @@ -1,13 +1,13 @@ -<?php if ($timesheet['time_estimated'] > 0 || $timesheet['time_spent'] > 0): ?> +<?php if ($task['time_estimated'] > 0 || $task['time_spent'] > 0): ?> <div class="page-header"> <h2><?= t('Time tracking') ?></h2> </div> <ul class="listing"> - <li><?= t('Estimate:') ?> <strong><?= $this->e($timesheet['time_estimated']) ?></strong> <?= t('hours') ?></li> - <li><?= t('Spent:') ?> <strong><?= $this->e($timesheet['time_spent']) ?></strong> <?= t('hours') ?></li> - <li><?= t('Remaining:') ?> <strong><?= $this->e($timesheet['time_remaining']) ?></strong> <?= t('hours') ?></li> + <li><?= t('Estimate:') ?> <strong><?= $this->e($task['time_estimated']) ?></strong> <?= t('hours') ?></li> + <li><?= t('Spent:') ?> <strong><?= $this->e($task['time_spent']) ?></strong> <?= t('hours') ?></li> + <li><?= t('Remaining:') ?> <strong><?= $this->e($task['time_estimated'] - $task['time_spent']) ?></strong> <?= t('hours') ?></li> </ul> <?php endif ?>
\ No newline at end of file diff --git a/assets/css/app.css b/assets/css/app.css index 0089d5f8..6c675ccd 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -919,7 +919,6 @@ select { } .form-actions { - clear: both; margin-top: 20px; } @@ -1908,7 +1907,8 @@ a.task-board-nobody { .confirm { max-width: 700px; font-size: 1.1em; -}/* sidebar */ +} +/* sidebar */ .sidebar-container { margin-top: 10px; clear: both; diff --git a/assets/css/src/confirm.css b/assets/css/src/confirm.css index 78f3f1ec..fbc6bdf3 100644 --- a/assets/css/src/confirm.css +++ b/assets/css/src/confirm.css @@ -2,4 +2,4 @@ .confirm { max-width: 700px; font-size: 1.1em; -}
\ No newline at end of file +} diff --git a/assets/css/src/form.css b/assets/css/src/form.css index b6cb891e..7073f2a4 100644 --- a/assets/css/src/form.css +++ b/assets/css/src/form.css @@ -73,7 +73,6 @@ select { } .form-actions { - clear: both; margin-top: 20px; } diff --git a/tests/units/TimeTrackingTest.php b/tests/units/TimeTrackingTest.php deleted file mode 100644 index 447f1c96..00000000 --- a/tests/units/TimeTrackingTest.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php - -require_once __DIR__.'/Base.php'; - -use Model\Subtask; -use Model\TaskModification; -use Model\TaskCreation; -use Model\TaskFinder; -use Model\Project; -use Model\TimeTracking; - -class TimeTrackingTest extends Base -{ - public function testCalculateTime() - { - $tm = new TaskModification($this->container); - $tc = new TaskCreation($this->container); - $tf = new TaskFinder($this->container); - $p = new Project($this->container); - $s = new Subtask($this->container); - $ts = new TimeTracking($this->container); - - $this->assertEquals(1, $p->create(array('name' => 'Project #1'))); - $this->assertEquals(1, $tc->create(array('title' => 'Task #1', 'project_id' => 1, 'time_estimated' => 4.5))); - $this->assertTrue($tm->update(array('id' => 1, 'time_spent' => 3.5))); - - $task = $tf->getById(1); - $this->assertNotEmpty($task); - $this->assertEquals(4.5, $task['time_estimated']); - $this->assertEquals(3.5, $task['time_spent']); - - $timesheet = $ts->getTaskTimesheet($task, array()); - $this->assertNotEmpty($timesheet); - $this->assertEquals(4.5, $timesheet['time_estimated']); - $this->assertEquals(3.5, $timesheet['time_spent']); - $this->assertEquals(1, $timesheet['time_remaining']); - - // Subtasks calculation - $this->assertEquals(1, $s->create(array('title' => 'subtask #1', 'task_id' => 1, 'time_estimated' => 5.5, 'time_spent' => 3))); - $this->assertEquals(2, $s->create(array('title' => 'subtask #2', 'task_id' => 1, 'time_estimated' => '', 'time_spent' => 4))); - - $timesheet = $ts->getTaskTimesheet($task, $s->getAll(1)); - $this->assertNotEmpty($timesheet); - $this->assertEquals(5.5, $timesheet['time_estimated']); - $this->assertEquals(7, $timesheet['time_spent']); - $this->assertEquals(-1.5, $timesheet['time_remaining']); - } -} |