Add 3 new fields for tasks: start date, time estimated and time spent
This commit is contained in:
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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'));
|
||||
}
|
||||
|
||||
|
||||
@@ -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'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
45
app/Model/TimeTracking.php
Normal file
45
app/Model/TimeTracking.php
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user