xref: /plugin/bez/mdl/TaskFactory.php (revision 9b93b298b733352a4f0b80f5605eb1f78a853271)
1<?php
2
3namespace dokuwiki\plugin\bez\mdl;
4
5class TaskFactory extends Factory {
6
7    public function get_table_view() {
8        return 'task_view';
9    }
10
11    public function get_years_scope() {
12        $r = $this->model->sqlite->query('SELECT
13                                        MIN(create_date),
14                                        MIN(plan_date),
15                                        DATE(),
16                                        MAX(close_date),
17                                        MAX(plan_date)
18                                        FROM task');
19        $data = $this->model->sqlite->res_fetch_array($r);
20
21        $min_date = min($data[0], $data[1], $data[2]);
22        $max_date = max($data[2], $data[3], $data[4]);
23
24        //get only year
25        $first =  (int) substr($min_date, 0, strpos($min_date, '-'));
26        $last = (int) substr($max_date, 0, strpos($max_date, '-'));
27
28        $years = array();
29        for ($year = $first; $year <= $last; $year++) {
30            $years[] = (string) $year;
31        }
32        return $years;
33    }
34
35    public function get_from_thread(Thread $thread) {
36        $tasks = $this->model->taskFactory->get_all(array('thread_id' => $thread->id),
37                                            'thread_comment_id', false, array('thread' => $thread));
38        $by_thread_comment = array('corrections' => array());
39        foreach ($tasks as $task) {
40            if ($task->thread_comment_id == null) {
41                $by_thread_comment['corrections'][$task->id] = $task;
42                continue;
43            }
44            if (!isset($by_thread_comment[$task->thread_comment_id])) {
45                $by_thread_comment[$task->thread_comment_id] = array();
46            }
47            $by_thread_comment[$task->thread_comment_id][$task->id] = $task;
48        }
49        return $by_thread_comment;
50    }
51
52    public function get_by_type($thread) {
53        $sql = "SELECT task.id, task.type, task.content_html, task.state, task.cost, task.plan_date, task.close_date,
54                        task_comment.content_html AS task_comment_content_html
55                        FROM task LEFT JOIN task_comment ON task.id = task_comment.task_id
56                        WHERE task.thread_id = ?
57                        GROUP BY task.id, task.content_html, task.state, task.cost, task.plan_date, task.close_date,
58                        task_comment.content_html
59                        ORDER BY task_comment.id, thread_comment_id";
60        $stmt = $this->model->sqlite->query($sql, $thread->id);
61        $stmt->setFetchMode(\PDO::FETCH_OBJ);
62
63        $by_type = array('correction' => array(), 'corrective' => array(), 'preventive' => array());
64        foreach ($stmt as $task) {
65            $by_type[$task->type][$task->id] = $task;
66        }
67
68        return $by_type;
69    }
70
71    public function users_involvement(\DatePeriod $period=NULL) {
72        if ($period) {
73            $from = $period->getStartDate()->format(\DateTime::ISO8601);
74            $to = $period->getEndDate()->format(\DateTime::ISO8601);
75
76            $sql = "SELECT task_participant.user_id,
77                       SUM(task_participant.original_poster) AS original_poster_sum,
78                       SUM(task_participant.assignee) AS assignee_sum,
79                       SUM(task_participant.commentator) AS commentator_sum
80                       FROM task_participant JOIN task ON task_participant.task_id = task.id
81                       WHERE task.create_date BETWEEN ? AND ?
82                       GROUP BY user_id
83                       ORDER BY user_id";
84            $r = $this->model->sqlite->query($sql, $from, $to);
85        } else {
86            $sql = "SELECT user_id,
87                       SUM(original_poster) AS original_poster_sum,
88                       SUM(assignee) AS assignee_sum,
89                       SUM(commentator) AS commentator_sum
90                       FROM task_participant
91                       GROUP BY user_id
92                       ORDER BY user_id";
93            $r = $this->model->sqlite->query($sql);
94        }
95
96        return $r;
97    }
98
99    public function report(\DatePeriod $period=NULL) {
100        if ($period) {
101            $from = $period->getStartDate()->format(\DateTime::ISO8601);
102            $to = $period->getEndDate()->format(\DateTime::ISO8601);
103
104            $sql = "SELECT task_program_name,
105                        COUNT(CASE WHEN state = 'opened' THEN 1 END) AS opened,
106                        COUNT(CASE WHEN state = 'done' AND close_date <= plan_date THEN 1 END)
107                          AS closed_on_time,
108                        COUNT(CASE WHEN state = 'done' AND close_date > plan_date THEN 1 END)
109                          AS closed_after_the_dedline,
110                        SUM(cost) AS total_cost,
111                        (CASE WHEN state = 'done' THEN
112                            SUM(cost)
113                            END) AS cost_of_closed,
114                        COUNT(*) AS 'count_all'
115                       FROM task_view
116                       WHERE create_date BETWEEN ? AND ?
117                       GROUP BY task_program_name
118                       ORDER BY task_program_name";
119            $r = $this->model->sqlite->query($sql, $from, $to);
120        } else {
121            $sql = "SELECT task_program_name,
122                        COUNT(CASE WHEN state = 'opened' THEN 1 END) AS opened,
123                        COUNT(CASE WHEN state = 'done' AND close_date <= plan_date THEN 1 END)
124                          AS closed_on_time,
125                        COUNT(CASE WHEN state = 'done' AND close_date > plan_date THEN 1 END)
126                          AS closed_after_the_dedline,
127                        SUM(cost) AS total_cost,
128                        (CASE WHEN state = 'done' THEN
129                            SUM(cost)
130                            END) AS cost_of_closed,
131                        COUNT(*) AS 'count_all'
132                       FROM task_view
133                       GROUP BY task_program_name
134                       ORDER BY task_program_name";
135            $r = $this->model->sqlite->query($sql);
136        }
137
138        return $r;
139    }
140
141    public function initial_save(Entity $task, $data) {
142        try {
143            $this->beginTransaction();
144            parent::initial_save($task, $data);
145
146            $task->set_participant_flags($task->original_poster, array('subscribent', 'original_poster'));
147            $task->set_participant_flags($task->assignee, array('subscribent', 'assignee'));
148
149            if ($task->thread_id != '') {
150                $task->thread->set_participant_flags($task->assignee, array('subscribent', 'task_assignee'));
151                $task->thread->update_last_activity();
152            }
153
154            $this->commitTransaction();
155
156            //notifications
157            if ($this->model->user_nick != $task->assignee) {
158                $task->mail_notify_assignee();
159            }
160            if ($task->thread_id != '') {
161                $task->thread->mail_notify_task_added($task);
162            }
163        } catch(Exception $exception) {
164            $this->rollbackTransaction();
165        }
166    }
167
168    public function update_save(Entity $task, $data) {
169        try {
170            $this->beginTransaction();
171            $prev_assignee = $task->assignee;
172            parent::update_save($task, $data);
173
174            if($task->assignee != $prev_assignee) {
175                $task->remove_participant_flags($prev_assignee, array('assignee'));
176                $task->set_participant_flags($task->assignee, array('subscribent', 'assignee'));
177            }
178
179            if ($task->thread_id != '' && $task->assignee != $prev_assignee) {
180                if ($this->model->taskFactory->count(array(
181                    'thread_id' => $task->thread_id,
182                    'assignee'  => $prev_assignee)) == 0) {
183                    $task->thread->remove_participant_flags($prev_assignee, array('task_assignee'));
184                }
185                $task->thread->set_participant_flags($task->assignee, array('subscribent', 'task_assignee'));
186            }
187
188            $this->commitTransaction();
189            //notifications
190            if ($prev_assignee != $task->assignee && $this->model->user_nick != $task->assignee) {
191                $task->mail_notify_assignee();
192            }
193        } catch(Exception $exception) {
194            $this->rollbackTransaction();
195        }
196    }
197}