summaryrefslogtreecommitdiff
path: root/app/Analytic/AverageLeadCycleTimeAnalytic.php
blob: 62c835596171495afe5bebc22544c4fbd69096d7 (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
<?php

namespace Kanboard\Analytic;

use Kanboard\Core\Base;
use Kanboard\Model\Task;

/**
 * Average Lead and Cycle Time
 *
 * @package  analytic
 * @author   Frederic Guillot
 */
class AverageLeadCycleTimeAnalytic extends Base
{
    /**
     * Build report
     *
     * @access public
     * @param  integer   $project_id    Project id
     * @return array
     */
    public function build($project_id)
    {
        $stats = array(
            'count' => 0,
            'total_lead_time' => 0,
            'total_cycle_time' => 0,
            'avg_lead_time' => 0,
            'avg_cycle_time' => 0,
        );

        $tasks = $this->getTasks($project_id);

        foreach ($tasks as &$task) {
            $stats['count']++;
            $stats['total_lead_time'] += $this->calculateLeadTime($task);
            $stats['total_cycle_time'] += $this->calculateCycleTime($task);
        }

        $stats['avg_lead_time'] = $this->calculateAverage($stats, 'total_lead_time');
        $stats['avg_cycle_time'] = $this->calculateAverage($stats, 'total_cycle_time');

        return $stats;
    }

    /**
     * Calculate average
     *
     * @access private
     * @param  array  &$stats
     * @param  string $field
     * @return float
     */
    private function calculateAverage(array &$stats, $field)
    {
        if ($stats['count'] > 0) {
            return (int) ($stats[$field] / $stats['count']);
        }

        return 0;
    }

    /**
     * Calculate lead time
     *
     * @access private
     * @param  array  &$task
     * @return integer
     */
    private function calculateLeadTime(array &$task)
    {
        $end = $task['date_completed'] ?: time();
        $start = $task['date_creation'];

        return $end - $start;
    }

    /**
     * Calculate cycle time
     *
     * @access private
     * @param  array  &$task
     * @return integer
     */
    private function calculateCycleTime(array &$task)
    {
        $end = (int) $task['date_completed'] ?: time();
        $start = (int) $task['date_started'];

        // Start date can be in the future when defined with the Gantt chart
        if ($start > 0 && $end > $start) {
            return $end - $start;
        }

        return 0;
    }

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