| | <?php |
| |
|
| | namespace Kanboard\Model; |
| |
|
| | use DateTime; |
| | use Kanboard\Core\Base; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | class SubtaskTimeTrackingModel extends Base |
| | { |
| | |
| | |
| | |
| | |
| | |
| | const TABLE = 'subtask_time_tracking'; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function getTimerQuery($user_id) |
| | { |
| | $sql = $this->db |
| | ->table(self::TABLE) |
| | ->columns('start') |
| | ->eq($this->db->escapeIdentifier('user_id',self::TABLE), $user_id) |
| | ->eq($this->db->escapeIdentifier('end',self::TABLE), 0) |
| | ->eq($this->db->escapeIdentifier('subtask_id',self::TABLE), SubtaskModel::TABLE.'.id') |
| | ->limit(1) |
| | ->buildSelectQuery(); |
| | |
| | |
| | $sql = substr_replace($sql, $user_id, strpos($sql, '?'), 1); |
| | $sql = substr_replace($sql, 0, strpos($sql, '?'), 1); |
| | $sql = substr_replace($sql, SubtaskModel::TABLE.'.id', strpos($sql, '?'), 1); |
| | return $sql; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function getUserQuery($user_id) |
| | { |
| | return $this->db |
| | ->table(self::TABLE) |
| | ->columns( |
| | self::TABLE.'.id', |
| | self::TABLE.'.subtask_id', |
| | self::TABLE.'.end', |
| | self::TABLE.'.start', |
| | self::TABLE.'.time_spent', |
| | SubtaskModel::TABLE.'.task_id', |
| | SubtaskModel::TABLE.'.title AS subtask_title', |
| | TaskModel::TABLE.'.title AS task_title', |
| | TaskModel::TABLE.'.project_id', |
| | TaskModel::TABLE.'.color_id' |
| | ) |
| | ->join(SubtaskModel::TABLE, 'id', 'subtask_id') |
| | ->join(TaskModel::TABLE, 'id', 'task_id', SubtaskModel::TABLE) |
| | ->eq(self::TABLE.'.user_id', $user_id); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function getTaskQuery($task_id) |
| | { |
| | return $this->db |
| | ->table(self::TABLE) |
| | ->columns( |
| | self::TABLE.'.id', |
| | self::TABLE.'.subtask_id', |
| | self::TABLE.'.end', |
| | self::TABLE.'.start', |
| | self::TABLE.'.time_spent', |
| | self::TABLE.'.user_id', |
| | SubtaskModel::TABLE.'.task_id', |
| | SubtaskModel::TABLE.'.title AS subtask_title', |
| | TaskModel::TABLE.'.project_id', |
| | UserModel::TABLE.'.username', |
| | UserModel::TABLE.'.name AS user_fullname' |
| | ) |
| | ->join(SubtaskModel::TABLE, 'id', 'subtask_id') |
| | ->join(TaskModel::TABLE, 'id', 'task_id', SubtaskModel::TABLE) |
| | ->join(UserModel::TABLE, 'id', 'user_id', self::TABLE) |
| | ->eq(TaskModel::TABLE.'.id', $task_id); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function getUserTimesheet($user_id) |
| | { |
| | return $this->db |
| | ->table(self::TABLE) |
| | ->eq('user_id', $user_id) |
| | ->findAll(); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function hasTimer($subtask_id, $user_id) |
| | { |
| | return $this->db->table(self::TABLE)->eq('subtask_id', $subtask_id)->eq('user_id', $user_id)->eq('end', 0)->exists(); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function toggleTimer($subtask_id, $user_id, $status) |
| | { |
| | if ($this->configModel->get('subtask_time_tracking') == 1) { |
| | if ($status == SubtaskModel::STATUS_INPROGRESS) { |
| | return $this->subtaskTimeTrackingModel->logStartTime($subtask_id, $user_id); |
| | } elseif ($status == SubtaskModel::STATUS_DONE) { |
| | return $this->subtaskTimeTrackingModel->logEndTime($subtask_id, $user_id); |
| | } |
| | } |
| |
|
| | return false; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function logStartTime($subtask_id, $user_id) |
| | { |
| | return |
| | ! $this->hasTimer($subtask_id, $user_id) && |
| | $this->db |
| | ->table(self::TABLE) |
| | ->insert(array('subtask_id' => $subtask_id, 'user_id' => $user_id, 'start' => time(), 'end' => 0)); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function logEndTime($subtask_id, $user_id) |
| | { |
| | $time_spent = $this->getTimeSpent($subtask_id, $user_id); |
| |
|
| | if ($time_spent > 0) { |
| | $this->updateSubtaskTimeSpent($subtask_id, $time_spent); |
| | } |
| |
|
| | return $this->db |
| | ->table(self::TABLE) |
| | ->eq('subtask_id', $subtask_id) |
| | ->eq('user_id', $user_id) |
| | ->eq('end', 0) |
| | ->update(array( |
| | 'end' => time(), |
| | 'time_spent' => $time_spent, |
| | )); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function getTimeSpent($subtask_id, $user_id) |
| | { |
| | $hook = 'model:subtask-time-tracking:calculate:time-spent'; |
| | $start_time = $this->db |
| | ->table(self::TABLE) |
| | ->eq('subtask_id', $subtask_id) |
| | ->eq('user_id', $user_id) |
| | ->eq('end', 0) |
| | ->findOneColumn('start'); |
| |
|
| | if (empty($start_time)) { |
| | return 0; |
| | } |
| |
|
| | $end = new DateTime; |
| | $start = new DateTime; |
| | $start->setTimestamp($start_time); |
| |
|
| | if ($this->hook->exists($hook)) { |
| | return $this->hook->first($hook, array( |
| | 'user_id' => $user_id, |
| | 'start' => $start, |
| | 'end' => $end, |
| | )); |
| | } |
| |
|
| | return $this->dateParser->getHours($start, $end); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function updateSubtaskTimeSpent($subtask_id, $time_spent) |
| | { |
| | $subtask = $this->subtaskModel->getById($subtask_id); |
| |
|
| | return $this->subtaskModel->update(array( |
| | 'id' => $subtask['id'], |
| | 'time_spent' => $subtask['time_spent'] + $time_spent, |
| | 'task_id' => $subtask['task_id'], |
| | ), false); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function updateTaskTimeTracking($task_id) |
| | { |
| | $values = $this->calculateSubtaskTime($task_id); |
| |
|
| | return $this->db |
| | ->table(TaskModel::TABLE) |
| | ->eq('id', $task_id) |
| | ->update($values); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | public function calculateSubtaskTime($task_id) |
| | { |
| | return $this->db |
| | ->table(SubtaskModel::TABLE) |
| | ->eq('task_id', $task_id) |
| | ->columns( |
| | 'SUM(time_spent) AS time_spent', |
| | 'SUM(time_estimated) AS time_estimated' |
| | ) |
| | ->findOne(); |
| | } |
| | } |
| |
|