diff --git a/module/task/config.php b/module/task/config.php
index d502a7861f..4e62155d34 100644
--- a/module/task/config.php
+++ b/module/task/config.php
@@ -3,7 +3,8 @@ global $lang;
$config->task->create->requiredFields = 'name,estimate,type,pri';
$config->task->edit->requiredFields = $config->task->create->requiredFields;
$config->task->start->requiredFields = 'estimate';
-$config->task->complete->requiredFields = $config->task->start->requiredFields;
+$config->task->finish->requiredFields = 'consumed';
+$config->task->activate->requiredFields = 'left';
$config->task->search['module'] = 'task';
$config->task->search['fields']['name'] = $lang->task->name;
diff --git a/module/task/control.php b/module/task/control.php
index 403c2fcf64..c212e45f3c 100644
--- a/module/task/control.php
+++ b/module/task/control.php
@@ -203,13 +203,12 @@ class task extends control
if(!empty($_POST))
{
$this->loadModel('action');
- $changes = $this->task->changeStatus($taskID);
+ $changes = $this->task->start($taskID);
if(dao::isError()) die(js::error(dao::getError()));
if($this->post->comment != '' or !empty($changes))
{
- $action = !empty($changes) ? 'Started' : 'Commented';
- $actionID = $this->action->create('task', $taskID, $action, $this->post->comment);
+ $actionID = $this->action->create('task', $taskID, 'Started', $this->post->comment);
$this->action->logHistory($actionID, $changes);
$this->sendmail($taskID, $actionID);
}
@@ -222,38 +221,70 @@ class task extends control
}
/**
- * Complete a task.
+ * Finish a task.
*
* @param int $taskID
* @access public
* @return void
*/
- public function complete($taskID)
+ public function finish($taskID)
{
$this->commonAction($taskID);
if(!empty($_POST))
{
$this->loadModel('action');
- $changes = $this->task->changeStatus($taskID);
+ $changes = $this->task->finish($taskID);
if(dao::isError()) die(js::error(dao::getError()));
if($this->post->comment != '' or !empty($changes))
{
- $action = !empty($changes) ? 'Finished' : 'Commented';
- $actionID = $this->action->create('task', $taskID, $action, $this->post->comment);
+ $actionID = $this->action->create('task', $taskID, 'Finished', $this->post->comment);
$this->action->logHistory($actionID, $changes);
$this->sendmail($taskID, $actionID);
}
die(js::locate($this->createLink('task', 'view', "taskID=$taskID"), 'parent'));
}
- $this->view->header->title = $this->view->project->name . $this->lang->colon .$this->lang->task->complete;
- $this->view->position[] = $this->lang->task->complete;
+ $this->view->header->title = $this->view->project->name . $this->lang->colon .$this->lang->task->finish;
+ $this->view->position[] = $this->lang->task->finish;
$this->display();
}
+ /**
+ * Close a task.
+ *
+ * @param int $taskID
+ * @access public
+ * @return void
+ */
+ public function close($taskID)
+ {
+ $this->commonAction($taskID);
+
+ if(!empty($_POST))
+ {
+ $this->loadModel('action');
+ $changes = $this->task->close($taskID);
+ if(dao::isError()) die(js::error(dao::getError()));
+
+ if($this->post->comment != '' or !empty($changes))
+ {
+ $actionID = $this->action->create('task', $taskID, 'Closed', $this->post->comment);
+ $this->action->logHistory($actionID, $changes);
+ $this->sendmail($taskID, $actionID);
+ }
+ die(js::locate($this->createLink('task', 'view', "taskID=$taskID"), 'parent'));
+ }
+
+ $this->view->header->title = $this->view->project->name . $this->lang->colon .$this->lang->task->finish;
+ $this->view->position[] = $this->lang->task->finish;
+
+ $this->display();
+
+ }
+
/**
* Cancel a task.
*
@@ -268,13 +299,12 @@ class task extends control
if(!empty($_POST))
{
$this->loadModel('action');
- $changes = $this->task->changeStatus($taskID);
+ $changes = $this->task->cancel($taskID);
if(dao::isError()) die(js::error(dao::getError()));
if($this->post->comment != '' or !empty($changes))
{
- $action = !empty($changes) ? 'Canceled' : 'Commented';
- $actionID = $this->action->create('task', $taskID, $action, $this->post->comment);
+ $actionID = $this->action->create('task', $taskID, 'Canceled', $this->post->comment);
$this->action->logHistory($actionID, $changes);
$this->sendmail($taskID, $actionID);
}
@@ -301,25 +331,22 @@ class task extends control
if(!empty($_POST))
{
$this->loadModel('action');
- $changes = $this->task->changeStatus($taskID);
+ $changes = $this->task->activate($taskID);
if(dao::isError()) die(js::error(dao::getError()));
if($this->post->comment != '' or !empty($changes))
{
- $action = !empty($changes) ? 'Started' : 'Commented';
- $actionID = $this->action->create('task', $taskID, $action, $this->post->comment);
+ $actionID = $this->action->create('task', $taskID, 'Activated', $this->post->comment);
$this->action->logHistory($actionID, $changes);
$this->sendmail($taskID, $actionID);
}
die(js::locate($this->createLink('task', 'view', "taskID=$taskID"), 'parent'));
}
- $this->view->header->title = $this->view->project->name . $this->lang->colon .$this->lang->task->start;
+ $this->view->header->title = $this->view->project->name . $this->lang->colon .$this->lang->task->activate;
$this->view->position[] = $this->lang->task->activate;
$this->display();
}
-
-
/**
* Delete a task.
diff --git a/module/task/lang/en.php b/module/task/lang/en.php
index 43021d25d9..000500c190 100644
--- a/module/task/lang/en.php
+++ b/module/task/lang/en.php
@@ -17,7 +17,7 @@ $lang->task->delete = "Delete";
$lang->task->view = "Info";
$lang->task->logEfforts= "Efforts";
$lang->task->start = "Start";
-$lang->task->complete = "Complete";
+$lang->task->finish = "Finish";
$lang->task->close = "Close";
$lang->task->cancel = "Cancel";
$lang->task->activate = "Activate";
diff --git a/module/task/lang/zh-cn.php b/module/task/lang/zh-cn.php
index 35a27c08a9..9605fcf375 100644
--- a/module/task/lang/zh-cn.php
+++ b/module/task/lang/zh-cn.php
@@ -17,7 +17,7 @@ $lang->task->delete = "删除任务";
$lang->task->view = "查看任务";
$lang->task->logEfforts= "记录工时";
$lang->task->start = "开始任务";
-$lang->task->complete = "完成任务";
+$lang->task->finish = "完成任务";
$lang->task->close = "关闭任务";
$lang->task->cancel = "取消任务";
$lang->task->activate = "激活任务";
diff --git a/module/task/model.php b/module/task/model.php
index b98a5c4550..274f499a4e 100644
--- a/module/task/model.php
+++ b/module/task/model.php
@@ -35,9 +35,11 @@ class taskModel extends model
->setIF($this->post->estimate != false, 'left', $this->post->estimate)
->setForce('assignedTo', $assignedTo)
->setIF($this->post->story != false, 'storyVersion', $this->loadModel('story')->getVersion($this->post->story))
- ->setDefault('statusCustom', strpos(self::CUSTOM_STATUS_ORDER, $this->post->status) + 1)
+ ->setDefault('openedBy', $this->app->user->account)
+ ->setDefault('openedDate', helper::now())
->remove('after,files,labels')
->get();
+ $this->setStatus($task);
$this->dao->insert(TABLE_TASK)->data($task)
->autoCheck()
@@ -79,15 +81,15 @@ class taskModel extends model
->setIF($this->post->status == 'cancel' and !$this->post->canceledBy, 'canceledBy', $this->app->user->account)
->setIF($this->post->status == 'cancel' and !$this->post->canceledDate, 'canceledDate', $now)
- ->setIF($this->post->status == 'cancel', 'closedBy', $this->post->canceledBy ? $this->post->canceledBy : $this->app->user->account)
- ->setIF($this->post->status == 'cancel', 'closedDate', $this->post->canceledDate? $this->post->canceledDate : $now)
- ->setIF($this->post->status == 'cancel', 'closedReason', 'cancel')
- ->setIF($this->post->status == 'cancel', 'status', 'closed')
+ ->setIF($this->post->status == 'cancel', 'assignedTo', $oldTask->openedBy)
+ ->setIF($this->post->status == 'cancel', 'assignedDate', $now)
->setIF($this->post->status == 'closed' and !$this->post->closedBy, 'closedBy', $this->app->user->account)
->setIF($this->post->status == 'closed' and !$this->post->closedDate, 'closedDate', $now)
->setIF($this->post->consumed > 0 and $this->post->left > 0 and $this->post->status == 'wait', 'status', 'doing')
+ ->setIF($this->post->assignedTo != $oldTask->assignedTo, 'assignedDate', $now)
+
->add('lastEditedBy', $this->app->user->account)
->add('lastEditedDate', $now)
->remove('comment,files,labels')
@@ -116,36 +118,140 @@ class taskModel extends model
if($this->post->story != false) $this->loadModel('story')->setStage($this->post->story);
if(!dao::isError()) return common::createChanges($oldTask, $task);
}
-
+
/**
- * Change status of a task and return the diff info.
+ * Start a task.
*
- * @param int $taskID
+ * @param int $taskID
* @access public
- * @return array the diff info.
+ * @return void
*/
- public function changeStatus($taskID)
+ public function start($taskID)
{
$oldTask = $this->getById($taskID);
+ $now = helper::now();
$task = fixer::input('post')
- ->setDefault('estimate, left, consumed', 0)
- ->setIF($this->post->consumed > 0 and $this->post->left > 0 and $this->post->status == 'wait', 'status', 'doing')
- ->remove('comment')
- ->get();
- $task->statusCustom = strpos(self::CUSTOM_STATUS_ORDER, $task->status) + 1;
+ ->setDefault('status', 'doing')
+ ->setDefault('lastEditedBy', $this->app->user->account)
+ ->setDefault('lastEditedDate', $now)
+ ->remove('comment')->get();
+ $this->setStatus($task);
$this->dao->update(TABLE_TASK)->data($task)
->autoCheck()
- ->batchCheckIF($task->status != 'cancel', $this->config->task->start->requiredFields, 'notempty')
- ->checkIF($task->estimate != false, 'estimate', 'float')
- ->checkIF($task->left != false, 'left', 'float')
- ->checkIF($task->consumed != false, 'consumed', 'float')
- ->checkIF($task->status == 'done', 'consumed', 'notempty')
- ->checkIF($task->left == 0 and $task->status != 'cancel', 'status', 'equal', 'done')
+ ->check('consumed,left', 'float')
->where('id')->eq((int)$taskID)->exec();
if(!dao::isError()) return common::createChanges($oldTask, $task);
}
+ /**
+ * Finish a task.
+ *
+ * @param int $taskID
+ * @access public
+ * @return void
+ */
+ public function finish($taskID)
+ {
+ $oldTask = $this->getById($taskID);
+ $now = helper::now();
+ $task = fixer::input('post')
+ ->setDefault('left', 0)
+ ->setDefault('assignedTo', $oldTask->openedBy)
+ ->setDefault('assignedDate', $now)
+ ->setDefault('status', 'done')
+ ->setDefault('finishedBy, lastEditedBy', $this->app->user->account)
+ ->setDefault('finishedDate, lastEditedDate', $now)
+ ->remove('comment')->get();
+ $this->setStatus($task);
+
+ $this->dao->update(TABLE_TASK)->data($task)
+ ->autoCheck()
+ ->check('consumed', 'notempty')
+ ->where('id')->eq((int)$taskID)->exec();
+ if(!dao::isError()) return common::createChanges($oldTask, $task);
+ }
+
+ /**
+ * Close a task.
+ *
+ * @param int $taskID
+ * @access public
+ * @return void
+ */
+ public function close($taskID)
+ {
+ $oldTask = $this->getById($taskID);
+ $now = helper::now();
+ $task = fixer::input('post')
+ ->setDefault('status', 'closed')
+ ->setDefault('assignedTo', 'closed')
+ ->setDefault('assignedDate', $now)
+ ->setDefault('closedBy, lastEditedBy', $this->app->user->account)
+ ->setDefault('closedDate, lastEditedDate', $now)
+ ->setDefault('closedReason', 'done')
+ ->remove('comment')->get();
+ $this->setStatus($task);
+
+ $this->dao->update(TABLE_TASK)->data($task)->autoCheck()->where('id')->eq((int)$taskID)->exec();
+ if(!dao::isError()) return common::createChanges($oldTask, $task);
+ }
+
+ /**
+ * Cancel a task.
+ *
+ * @param int $taskID
+ * @access public
+ * @return void
+ */
+ public function cancel($taskID)
+ {
+ $oldTask = $this->getById($taskID);
+ $now = helper::now();
+ $task = fixer::input('post')
+ ->setDefault('status', 'cancel')
+ ->setDefault('assignedTo', $oldTask->openedBy)
+ ->setDefault('assignedDate', $now)
+ ->setDefault('finishedBy', '')
+ ->setDefault('finishedDate', '0000-00-00')
+ ->setDefault('canceledBy, lastEditedBy', $this->app->user->account)
+ ->setDefault('canceledDate, lastEditedDate', $now)
+ ->remove('comment')->get();
+ $this->setStatus($task);
+
+ $this->dao->update(TABLE_TASK)->data($task)->autoCheck()->where('id')->eq((int)$taskID)->exec();
+ if(!dao::isError()) return common::createChanges($oldTask, $task);
+ }
+
+ /**
+ * Activate a task.
+ *
+ * @param int $taskID
+ * @access public
+ * @return void
+ */
+ public function activate($taskID)
+ {
+ $oldTask = $this->getById($taskID);
+ $task = fixer::input('post')
+ ->setDefault('left', 0)
+ ->setDefault('status', 'doing')
+ ->setDefault('finishedBy, canceledBy, closedBy, closedReason', '')
+ ->setDefault('finishedDate, canceledDate, closedDate', '0000-00-00')
+ ->setDefault('lastEditedBy', $this->app->user->account)
+ ->setDefault('lastEditedDate', helper::now())
+ ->remove('comment')->get();
+ $this->setStatus($task);
+
+ $this->dao->update(TABLE_TASK)->data($task)
+ ->autoCheck()
+ ->check('left', 'notempty')
+ ->where('id')->eq((int)$taskID)->exec();
+ if(!dao::isError()) return common::createChanges($oldTask, $task);
+
+ }
+
+
/**
* Get task info by Id.
*
@@ -164,6 +270,7 @@ class taskModel extends model
->where('t1.id')->eq((int)$taskID)
->fetch();
if(!$task) return false;
+ if($task->assignedTo == 'closed') $task->assignedToRealName = 'Closed';
foreach($task as $key => $value) if(strpos($key, 'Date') !== false and !(int)substr($value, 0, 4)) $task->$key = '';
if($task->mailto)
{
@@ -377,4 +484,16 @@ class taskModel extends model
}
return $task;
}
+
+ /**
+ * Set the status field of a task.
+ *
+ * @param object $task
+ * @access private
+ * @return void
+ */
+ private function setStatus($task)
+ {
+ $task->statusCustom = strpos(self::CUSTOM_STATUS_ORDER, $task->status) + 1;
+ }
}
diff --git a/module/task/view/activate.html.php b/module/task/view/activate.html.php
index 5253177837..ced2c78f6b 100644
--- a/module/task/view/activate.html.php
+++ b/module/task/view/activate.html.php
@@ -16,16 +16,12 @@
diff --git a/module/task/view/cancel.html.php b/module/task/view/cancel.html.php
index 569fb2d985..d8711c93ec 100644
--- a/module/task/view/cancel.html.php
+++ b/module/task/view/cancel.html.php
@@ -15,31 +15,12 @@
diff --git a/module/task/view/close.html.php b/module/task/view/close.html.php
new file mode 100644
index 0000000000..7764649a48
--- /dev/null
+++ b/module/task/view/close.html.php
@@ -0,0 +1,28 @@
+
+ * @package task
+ * @version $Id: cancel.html.php 935 2010-07-06 07:49:24Z jajacn@126.com $
+ * @link http://www.zentao.net
+ */
+?>
+
+