summaryrefslogtreecommitdiff
path: root/app/Model
diff options
context:
space:
mode:
Diffstat (limited to 'app/Model')
-rw-r--r--app/Model/Base.php1
-rw-r--r--app/Model/DateParser.php42
-rw-r--r--app/Model/SubTask.php1
-rw-r--r--app/Model/Task.php10
-rw-r--r--app/Model/TaskExport.php20
-rw-r--r--app/Model/TaskValidator.php24
-rw-r--r--app/Model/TimeTracking.php45
7 files changed, 130 insertions, 13 deletions
diff --git a/app/Model/Base.php b/app/Model/Base.php
index 2b13e815..ea4afc07 100644
--- a/app/Model/Base.php
+++ b/app/Model/Base.php
@@ -34,6 +34,7 @@ use PicoDb\Database;
* @property \Model\TaskExport $taskExport
* @property \Model\TaskHistory $taskHistory
* @property \Model\TaskValidator $taskValidator
+ * @property \Model\TimeTracking $timeTracking
* @property \Model\User $user
* @property \Model\Webhook $webhook
*/
diff --git a/app/Model/DateParser.php b/app/Model/DateParser.php
index 88e67686..38265f98 100644
--- a/app/Model/DateParser.php
+++ b/app/Model/DateParser.php
@@ -97,4 +97,46 @@ class DateParser extends Base
{
return mktime(0, 0, 0, date('m', $timestamp), date('d', $timestamp), date('Y', $timestamp));
}
+
+ /**
+ * Format date (form display)
+ *
+ * @access public
+ * @param array $values Database values
+ * @param array $fields Date fields
+ * @param string $format Date format
+ */
+ public function format(array &$values, array $fields, $format = '')
+ {
+ if ($format === '') {
+ $format = $this->config->get('application_date_format');
+ }
+
+ foreach ($fields as $field) {
+
+ if (! empty($values[$field])) {
+ $values[$field] = date($format, $values[$field]);
+ }
+ else {
+ $values[$field] = '';
+ }
+ }
+ }
+
+ /**
+ * Convert date (form input data)
+ *
+ * @access public
+ * @param array $values Database values
+ * @param array $fields Date fields
+ */
+ public function convert(array &$values, array $fields)
+ {
+ foreach ($fields as $field) {
+
+ if (! empty($values[$field]) && ! is_numeric($values[$field])) {
+ $values[$field] = $this->getTimestamp($values[$field]);
+ }
+ }
+ }
}
diff --git a/app/Model/SubTask.php b/app/Model/SubTask.php
index 0126030a..886ad1f3 100644
--- a/app/Model/SubTask.php
+++ b/app/Model/SubTask.php
@@ -82,6 +82,7 @@ class SubTask extends Base
->eq('task_id', $task_id)
->columns(self::TABLE.'.*', User::TABLE.'.username', User::TABLE.'.name')
->join(User::TABLE, 'id', 'user_id')
+ ->asc(self::TABLE.'.id')
->findAll();
foreach ($subtasks as &$subtask) {
diff --git a/app/Model/Task.php b/app/Model/Task.php
index 54dc0a2f..fe7bbdcd 100644
--- a/app/Model/Task.php
+++ b/app/Model/Task.php
@@ -89,6 +89,9 @@ class Task extends Base
tasks.date_completed,
tasks.date_modification,
tasks.date_due,
+ tasks.date_started,
+ tasks.time_estimated,
+ tasks.time_spent,
tasks.color_id,
tasks.project_id,
tasks.column_id,
@@ -363,12 +366,9 @@ class Task extends Base
*/
public function prepare(array &$values)
{
- if (! empty($values['date_due']) && ! is_numeric($values['date_due'])) {
- $values['date_due'] = $this->dateParser->getTimestamp($values['date_due']);
- }
-
+ $this->dateParser->convert($values, array('date_due', 'date_started'));
$this->removeFields($values, array('another_task', 'id'));
- $this->resetFields($values, array('date_due', 'score', 'category_id'));
+ $this->resetFields($values, array('date_due', 'date_started', 'score', 'category_id', 'time_estimated', 'time_spent'));
$this->convertIntegerFields($values, array('is_active'));
}
diff --git a/app/Model/TaskExport.php b/app/Model/TaskExport.php
index 815f5997..b929823e 100644
--- a/app/Model/TaskExport.php
+++ b/app/Model/TaskExport.php
@@ -27,7 +27,7 @@ class TaskExport extends Base
$results = array($this->getColumns());
foreach ($tasks as &$task) {
- $results[] = array_values($this->formatOutput($task));
+ $results[] = array_values($this->format($task));
}
return $results;
@@ -60,7 +60,10 @@ class TaskExport extends Base
tasks.title,
tasks.date_creation,
tasks.date_modification,
- tasks.date_completed
+ tasks.date_completed,
+ tasks.date_started,
+ tasks.time_estimated,
+ tasks.time_spent
FROM tasks
LEFT JOIN users ON users.id = tasks.owner_id
LEFT JOIN users AS creators ON creators.id = tasks.creator_id
@@ -89,16 +92,14 @@ class TaskExport extends Base
* @param array $task Task properties
* @return array
*/
- public function formatOutput(array &$task)
+ public function format(array &$task)
{
$colors = $this->color->getList();
- $task['score'] = $task['score'] ?: '';
+
$task['is_active'] = $task['is_active'] == Task::STATUS_OPEN ? e('Open') : e('Closed');
$task['color_id'] = $colors[$task['color_id']];
- $task['date_creation'] = date('Y-m-d', $task['date_creation']);
- $task['date_due'] = $task['date_due'] ? date('Y-m-d', $task['date_due']) : '';
- $task['date_modification'] = $task['date_modification'] ? date('Y-m-d', $task['date_modification']) : '';
- $task['date_completed'] = $task['date_completed'] ? date('Y-m-d', $task['date_completed']) : '';
+
+ $this->dateParser->format($task, array('date_due', 'date_modification', 'date_creation', 'date_started', 'date_completed'), 'Y-m-d');
return $task;
}
@@ -127,6 +128,9 @@ class TaskExport extends Base
e('Creation date'),
e('Modification date'),
e('Completion date'),
+ e('Start date'),
+ e('Time estimated'),
+ e('Time spent'),
);
}
}
diff --git a/app/Model/TaskValidator.php b/app/Model/TaskValidator.php
index 1c7b0b14..816008cf 100644
--- a/app/Model/TaskValidator.php
+++ b/app/Model/TaskValidator.php
@@ -31,6 +31,9 @@ class TaskValidator extends Base
new Validators\Integer('category_id', t('This value must be an integer')),
new Validators\MaxLength('title', t('The maximum length is %d characters', 200), 200),
new Validators\Date('date_due', t('Invalid date'), $this->dateParser->getDateFormats()),
+ new Validators\Date('date_started', t('Invalid date'), $this->dateParser->getDateFormats()),
+ new Validators\Numeric('time_spent', t('This value must be numeric')),
+ new Validators\Numeric('time_estimated', t('This value must be numeric')),
);
}
@@ -189,4 +192,25 @@ class TaskValidator extends Base
$v->getErrors()
);
}
+
+ /**
+ * Validate time tracking modification (form)
+ *
+ * @access public
+ * @param array $values Form values
+ * @return array $valid, $errors [0] = Success or not, [1] = List of errors
+ */
+ public function validateTimeModification(array $values)
+ {
+ $rules = array(
+ new Validators\Required('id', t('The id is required')),
+ );
+
+ $v = new Validator($values, array_merge($rules, $this->commonValidationRules()));
+
+ return array(
+ $v->execute(),
+ $v->getErrors()
+ );
+ }
}
diff --git a/app/Model/TimeTracking.php b/app/Model/TimeTracking.php
new file mode 100644
index 00000000..4ddddf12
--- /dev/null
+++ b/app/Model/TimeTracking.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace Model;
+
+/**
+ * Time tracking model
+ *
+ * @package model
+ * @author Frederic Guillot
+ */
+class TimeTracking extends Base
+{
+ /**
+ * Calculate time metrics for a task
+ *
+ * Use subtasks time metrics if not empty otherwise return task time metrics
+ *
+ * @access public
+ * @param array $task Task properties
+ * @param array $subtasks Subtasks list
+ * @return array
+ */
+ public function getTaskTimesheet(array $task, array $subtasks)
+ {
+ $timesheet = array(
+ 'time_spent' => 0,
+ 'time_estimated' => 0,
+ 'time_remaining' => 0,
+ );
+
+ foreach ($subtasks as &$subtask) {
+ $timesheet['time_estimated'] += $subtask['time_estimated'];
+ $timesheet['time_spent'] += $subtask['time_spent'];
+ }
+
+ if ($timesheet['time_estimated'] == 0 && $timesheet['time_spent'] == 0) {
+ $timesheet['time_estimated'] = $task['time_estimated'];
+ $timesheet['time_spent'] = $task['time_spent'];
+ }
+
+ $timesheet['time_remaining'] = $timesheet['time_estimated'] - $timesheet['time_spent'];
+
+ return $timesheet;
+ }
+}