summaryrefslogtreecommitdiff
path: root/app/Analytic/AverageTimeSpentColumnAnalytic.php
blob: 3556fb9dc2861112346c61794b9e957f72886da4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<?php

namespace Kanboard\Analytic;

use Kanboard\Core\Base;
use Kanboard\Model\TaskModel;

/**
 * Average Time Spent by Column
 *
 * @package  analytic
 * @author   Frederic Guillot
 */
class AverageTimeSpentColumnAnalytic extends Base
{
    /**
     * Build report
     *
     * @access public
     * @param  integer   $project_id    Project id
     * @return array
     */
    public function build($project_id)
    {
        $stats = $this->initialize($project_id);

        $this->processTasks($stats, $project_id);
        $this->calculateAverage($stats);

        return $stats;
    }

    /**
     * Initialize default values for each column
     *
     * @access private
     * @param  integer $project_id
     * @return array
     */
    private function initialize($project_id)
    {
        $stats = array();
        $columns = $this->columnModel->getList($project_id);

        foreach ($columns as $column_id => $column_title) {
            $stats[$column_id] = array(
                'count' => 0,
                'time_spent' => 0,
                'average' => 0,
                'title' => $column_title,
            );
        }

        return $stats;
    }

    /**
     * Calculate time spent for each tasks for each columns
     *
     * @access private
     * @param  array   $stats
     * @param  integer $project_id
     */
    private function processTasks(array &$stats, $project_id)
    {
        $tasks = $this->getTasks($project_id);

        foreach ($tasks as &$task) {
            foreach ($this->getTaskTimeByColumns($task) as $column_id => $time_spent) {
                if (isset($stats[$column_id])) {
                    $stats[$column_id]['count']++;
                    $stats[$column_id]['time_spent'] += $time_spent;
                }
            }
        }
    }

    /**
     * Calculate averages
     *
     * @access private
     * @param  array   $stats
     */
    private function calculateAverage(array &$stats)
    {
        foreach ($stats as &$column) {
            $this->calculateColumnAverage($column);
        }
    }

    /**
     * Calculate column average
     *
     * @access private
     * @param  array   $column
     */
    private function calculateColumnAverage(array &$column)
    {
        if ($column['count'] > 0) {
            $column['average'] = (int) ($column['time_spent'] / $column['count']);
        }
    }

    /**
     * Get time spent for each column for a given task
     *
     * @access private
     * @param  array   $task
     * @return array
     */
    private function getTaskTimeByColumns(array &$task)
    {
        $columns = $this->transitionModel->getTimeSpentByTask($task['id']);

        if (! isset($columns[$task['column_id']])) {
            $columns[$task['column_id']] = 0;
        }

        $columns[$task['column_id']] += $this->getTaskTimeSpentInCurrentColumn($task);

        return $columns;
    }

    /**
     * Calculate time spent of a task in the current column
     *
     * @access private
     * @param  array   $task
     * @return integer
     */
    private function getTaskTimeSpentInCurrentColumn(array &$task)
    {
        $end = $task['date_completed'] ?: time();
        return $end - $task['date_moved'];
    }

    /**
     * Fetch the last 1000 tasks
     *
     * @access private
     * @param  integer $project_id
     * @return array
     */
    private function getTasks($project_id)
    {
        return $this->db
            ->table(TaskModel::TABLE)
            ->columns('id', 'date_completed', 'date_moved', 'column_id')
            ->eq('project_id', $project_id)
            ->desc('id')
            ->limit(1000)
            ->findAll();
    }
}