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_with_closing_comment($thread) { 53 $sql = "SELECT task.id, task.type, task.content_html, task.state, task.cost, task.plan_date, task.close_date, 54 task_closing_comment.content_html AS task_comment_content_html, task.assignee 55 FROM task LEFT JOIN 56 (SELECT content_html, task_id FROM task_comment WHERE closing=1) 57 AS task_closing_comment ON task.id = task_closing_comment.task_id 58 WHERE task.thread_id = ? 59 ORDER BY task.plan_date"; 60 $stmt = $this->model->sqlite->query($sql, $thread->id); 61 $stmt->setFetchMode(\PDO::FETCH_OBJ); 62 63 return $stmt; 64 } 65 66 public function get_by_type($thread) { 67 $stmt = $this->get_with_closing_comment($thread); 68 69 $by_type = array('correction' => array(), 'corrective' => array(), 'preventive' => array()); 70 foreach ($stmt as $task) { 71 $by_type[$task->type][$task->id] = $task; 72 } 73 74 return $by_type; 75 } 76 77 public function users_involvement(\DatePeriod $period=NULL) { 78 if ($period) { 79 $from = $period->getStartDate()->format(\DateTime::ISO8601); 80 $to = $period->getEndDate()->format(\DateTime::ISO8601); 81 82 $sql = "SELECT task_participant.user_id, 83 SUM(task_participant.original_poster) AS original_poster_sum, 84 SUM(task_participant.assignee) AS assignee_sum, 85 SUM(task_participant.commentator) AS commentator_sum 86 FROM task_participant JOIN task ON task_participant.task_id = task.id 87 WHERE task.create_date BETWEEN ? AND ? 88 GROUP BY user_id 89 ORDER BY user_id"; 90 $r = $this->model->sqlite->query($sql, $from, $to); 91 } else { 92 $sql = "SELECT user_id, 93 SUM(original_poster) AS original_poster_sum, 94 SUM(assignee) AS assignee_sum, 95 SUM(commentator) AS commentator_sum 96 FROM task_participant 97 GROUP BY user_id 98 ORDER BY user_id"; 99 $r = $this->model->sqlite->query($sql); 100 } 101 102 return $r; 103 } 104 105 public function report(\DatePeriod $period=NULL) { 106 if ($period) { 107 $from = $period->getStartDate()->format(\DateTime::ISO8601); 108 $to = $period->getEndDate()->format(\DateTime::ISO8601); 109 110 $sql = "SELECT task_program_name, 111 COUNT(CASE WHEN state = 'opened' THEN 1 END) AS opened, 112 COUNT(CASE WHEN state = 'done' AND close_date <= plan_date THEN 1 END) 113 AS closed_on_time, 114 COUNT(CASE WHEN state = 'done' AND close_date > plan_date THEN 1 END) 115 AS closed_after_the_dedline, 116 SUM(cost) AS total_cost, 117 (CASE WHEN state = 'done' THEN 118 SUM(cost) 119 END) AS cost_of_closed, 120 COUNT(*) AS 'count_all' 121 FROM task_view 122 WHERE create_date BETWEEN ? AND ? 123 GROUP BY task_program_name 124 ORDER BY task_program_name"; 125 $r = $this->model->sqlite->query($sql, $from, $to); 126 } else { 127 $sql = "SELECT task_program_name, 128 COUNT(CASE WHEN state = 'opened' THEN 1 END) AS opened, 129 COUNT(CASE WHEN state = 'done' AND close_date <= plan_date THEN 1 END) 130 AS closed_on_time, 131 COUNT(CASE WHEN state = 'done' AND close_date > plan_date THEN 1 END) 132 AS closed_after_the_dedline, 133 SUM(cost) AS total_cost, 134 (CASE WHEN state = 'done' THEN 135 SUM(cost) 136 END) AS cost_of_closed, 137 COUNT(*) AS 'count_all' 138 FROM task_view 139 GROUP BY task_program_name 140 ORDER BY task_program_name"; 141 $r = $this->model->sqlite->query($sql); 142 } 143 144 return $r; 145 } 146 147 public function initial_save(Entity $task, $data) { 148 try { 149 $this->beginTransaction(); 150 parent::initial_save($task, $data); 151 152 $task->set_participant_flags($task->original_poster, array('subscribent', 'original_poster')); 153 $task->set_participant_flags($task->assignee, array('subscribent', 'assignee')); 154 155 if ($task->thread_id != '') { 156 $task->thread->set_participant_flags($task->assignee, array('subscribent', 'task_assignee')); 157 $task->thread->update_last_activity(); 158 } 159 160 $this->commitTransaction(); 161 162 //notifications 163 if ($this->model->user_nick != $task->assignee) { 164 $task->mail_notify_assignee(); 165 } 166 if ($task->thread_id != '') { 167 $task->thread->mail_notify_task_added($task); 168 } 169 } catch(Exception $exception) { 170 $this->rollbackTransaction(); 171 } 172 } 173 174 public function update_save(Entity $task, $data) { 175 try { 176 $this->beginTransaction(); 177 $prev_assignee = $task->assignee; 178 parent::update_save($task, $data); 179 180 if($task->assignee != $prev_assignee) { 181 $task->remove_participant_flags($prev_assignee, array('assignee')); 182 $task->set_participant_flags($task->assignee, array('subscribent', 'assignee')); 183 } 184 185 if ($task->thread_id != '' && $task->assignee != $prev_assignee) { 186 if ($this->model->taskFactory->count(array( 187 'thread_id' => $task->thread_id, 188 'assignee' => $prev_assignee)) == 0) { 189 $task->thread->remove_participant_flags($prev_assignee, array('task_assignee')); 190 } 191 $task->thread->set_participant_flags($task->assignee, array('subscribent', 'task_assignee')); 192 } 193 194 $this->commitTransaction(); 195 //notifications 196 if ($prev_assignee != $task->assignee && $this->model->user_nick != $task->assignee) { 197 $task->mail_notify_assignee(); 198 } 199 } catch(Exception $exception) { 200 $this->rollbackTransaction(); 201 } 202 } 203}