+ adjust the story process.
This commit is contained in:
@@ -32,6 +32,7 @@ $lang->colon = '::';
|
||||
$lang->reset = '重填';
|
||||
$lang->edit = '编辑';
|
||||
$lang->delete = '删除';
|
||||
$lang->close = '关闭';
|
||||
$lang->activate = '激活';
|
||||
$lang->delete = '删除';
|
||||
$lang->save = '保存';
|
||||
@@ -48,6 +49,7 @@ $lang->year = '年';
|
||||
$lang->downArrow = '↓';
|
||||
$lang->goback = '返回';
|
||||
$lang->selectAll = '全选';
|
||||
$lang->attatch = '附件';
|
||||
|
||||
/* 主导航菜单。*/
|
||||
$lang->menu->index = '首页|index|index';
|
||||
|
||||
@@ -32,10 +32,11 @@ $lang->product->delete = "删除产品";
|
||||
|
||||
$lang->product->roadmap = '路线图';
|
||||
|
||||
$lang->product->selectProduct = "请选择产品";
|
||||
$lang->product->saveButton = " 保存 (S) ";
|
||||
$lang->product->confirmDelete = " 您确定删除该产品吗?";
|
||||
$lang->product->ajaxGetProjects= "接口:获得项目列表";
|
||||
$lang->product->selectProduct = "请选择产品";
|
||||
$lang->product->saveButton = " 保存 (S) ";
|
||||
$lang->product->confirmDelete = " 您确定删除该产品吗?";
|
||||
$lang->product->ajaxGetProjects = "接口:获得项目列表";
|
||||
$lang->product->ajaxGetPlans = "接口:获得计划列表";
|
||||
|
||||
$lang->product->errorFormat = '产品数据格式不正确';
|
||||
$lang->product->errorEmptyName = '产品名称不能为空';
|
||||
|
||||
@@ -83,13 +83,16 @@ function search(active)
|
||||
<?php $vars = "productID=$productID&browseType=$browseType¶m=$moduleID&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";?>
|
||||
<th><?php common::printOrderLink('id', $orderBy, $vars, $lang->story->id);?></th>
|
||||
<th><?php common::printOrderLink('pri', $orderBy, $vars, $lang->story->pri);?></th>
|
||||
<th class='w-p40'><?php common::printOrderLink('title', $orderBy, $vars, $lang->story->title);?></th>
|
||||
<th class='w-p30'><?php common::printOrderLink('title', $orderBy, $vars, $lang->story->title);?></th>
|
||||
<th><?php common::printOrderLink('plan', $orderBy, $vars, $lang->story->plan);?></th>
|
||||
<th><?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->story->assignedTo);?></th>
|
||||
<th><?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->story->openedBy);?></th>
|
||||
<th><?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->story->assignedTo);?></th>
|
||||
<th><?php common::printOrderLink('estimate', $orderBy, $vars, $lang->story->estimate);?></th>
|
||||
<th><?php common::printOrderLink('status', $orderBy, $vars, $lang->story->status);?></th>
|
||||
<th class='w-100px'><?php common::printOrderLink('lastEditedDate', $orderBy, $vars, $lang->story->lastEditedDate);?></th>
|
||||
<th><?php common::printOrderLink('stage', $orderBy, $vars, $lang->story->stage);?></th>
|
||||
<th><?php common::printOrderLink('closedBy', $orderBy, $vars, $lang->story->closedBy);?></th>
|
||||
<th><?php common::printOrderLink('closedReason', $orderBy, $vars, $lang->story->closedReason);?></th>
|
||||
<th class='w-100px'><?php common::printOrderLink('lastEditedDate', $orderBy, $vars, $lang->story->lastEdited);?></th>
|
||||
<th><?php echo $lang->action;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -102,12 +105,15 @@ function search(active)
|
||||
<tr class='a-center'>
|
||||
<td><?php if($canView) echo html::a($viewLink, sprintf('%03d', $story->id)); else printf('%03d', $story->id);?></td>
|
||||
<td><?php echo $story->pri;?></td>
|
||||
<td class='a-left nobr'><nobr><?php echo $story->title;?></nobr></td>
|
||||
<td class='a-left nobr'><nobr><?php echo html::a($viewLink, $story->title);?></nobr></td>
|
||||
<td><?php echo $story->planTitle;?></td>
|
||||
<td><?php echo $users[$story->assignedTo];?></td>
|
||||
<td><?php echo $users[$story->openedBy];?></td>
|
||||
<td><?php echo $users[$story->assignedTo];?></td>
|
||||
<td><?php echo $story->estimate;?></td>
|
||||
<td class='<?php echo $story->status;?>'><?php $statusList = (array)$lang->story->statusList; echo $statusList[$story->status];?></td>
|
||||
<td class='<?php echo $story->status;?>'><?php echo $lang->story->statusList[$story->status];?></td>
|
||||
<td><?php echo $lang->story->stageList[$story->stage];?></td>
|
||||
<td><?php echo $users[$story->closedBy];?></td>
|
||||
<td><?php echo $lang->story->reasonList[$story->closedReason];?></td>
|
||||
<td><?php echo substr($story->lastEditedDate, 5, 11);?></td>
|
||||
<td>
|
||||
<?php if(common::hasPriv('story', 'edit')) echo html::a($this->createLink('story', 'edit', "story={$story->id}"), $lang->edit);?>
|
||||
|
||||
@@ -45,7 +45,7 @@ class story extends control
|
||||
}
|
||||
|
||||
/* 设置产品相关数据。*/
|
||||
$product = $this->product->findByID($productID);
|
||||
$product = $this->product->getById($productID);
|
||||
$products = $this->product->getPairs();
|
||||
$users = $this->user->getPairs();
|
||||
$moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'product');
|
||||
@@ -66,29 +66,12 @@ class story extends control
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/* 编辑需求:生成表单。*/
|
||||
public function edit($storyID)
|
||||
/* 变更、编辑时的共同操作。 */
|
||||
private function commonAction($storyID)
|
||||
{
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$this->loadModel('action');
|
||||
$changes = $this->story->update($storyID);
|
||||
if(dao::isError()) die(js::error(dao::getError()));
|
||||
$files = $this->loadModel('file')->saveUpload('story', $storyID);
|
||||
if($this->post->comment != '' or !empty($changes) or !empty($files))
|
||||
{
|
||||
$action = !empty($changes) ? 'Edited' : 'Commented';
|
||||
$fileAction = '';
|
||||
if(!empty($files)) $fileAction = "Add Files " . join(',', $files) . "\n" ;
|
||||
$actionID = $this->action->create('story', $storyID, $action, $fileAction . $this->post->comment);
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
die(js::locate($this->createLink('story', 'view', "storyID=$storyID"), 'parent'));
|
||||
}
|
||||
|
||||
/* 获取数据。*/
|
||||
$story = $this->story->findByID($storyID);
|
||||
$product = $this->product->findByID($story->product);
|
||||
$story = $this->story->getById($storyID);
|
||||
$product = $this->product->getById($story->product);
|
||||
$products = $this->product->getPairs();
|
||||
$users = $this->user->getPairs();
|
||||
$moduleOptionMenu = $this->tree->getOptionMenu($product->id, $viewType = 'product');
|
||||
@@ -97,24 +80,75 @@ class story extends control
|
||||
$this->product->setMenu($products, $product->id);
|
||||
|
||||
/* 赋值到模板。*/
|
||||
$this->view->header->title = $product->name . $this->lang->colon . $this->lang->story->edit . $this->lang->colon . $story->title;
|
||||
$this->view->position[] = html::a($this->createLink('product', 'browse', "product=$product->id"), $product->name);
|
||||
$this->view->position[] = $this->lang->story->edit;
|
||||
$this->view->product = $product;
|
||||
$this->view->products = $products;
|
||||
$this->view->story = $story;
|
||||
$this->view->users = $users;
|
||||
$this->view->moduleOptionMenu = $moduleOptionMenu;
|
||||
$this->view->plans = $this->loadModel('productplan')->getPairs($product->id);
|
||||
$this->view->actions = $this->action->getList('story', $storyID);
|
||||
}
|
||||
|
||||
/* 编辑需求。*/
|
||||
public function edit($storyID)
|
||||
{
|
||||
$this->loadModel('action');
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$changes = $this->story->update($storyID);
|
||||
if(dao::isError()) die(js::error(dao::getError()));
|
||||
if($this->post->comment != '' or !empty($changes))
|
||||
{
|
||||
$action = !empty($changes) ? 'Changed' : 'Commented';
|
||||
$actionID = $this->action->create('story', $storyID, $action, $this->post->comment);
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
die(js::locate($this->createLink('story', 'view', "storyID=$storyID"), 'parent'));
|
||||
}
|
||||
|
||||
$this->commonAction($storyID);
|
||||
|
||||
/* 赋值到模板。*/
|
||||
$this->view->header->title = $this->view->product->name . $this->lang->colon . $this->lang->story->edit . $this->lang->colon . $this->view->story->title;
|
||||
$this->view->position[] = $this->lang->story->edit;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/* 变更需求。*/
|
||||
public function change($storyID)
|
||||
{
|
||||
$this->loadModel('action');
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$changes = $this->story->change($storyID);
|
||||
if(dao::isError()) die(js::error(dao::getError()));
|
||||
$files = $this->loadModel('file')->saveUpload('story', $storyID);
|
||||
if($this->post->comment != '' or !empty($changes) or !empty($files))
|
||||
{
|
||||
$action = (!empty($changes) or !empty($files)) ? 'Changed' : 'Commented';
|
||||
$fileAction = '';
|
||||
if(!empty($files)) $fileAction = "Add Files " . join(',', $files) . "\n" ;
|
||||
$actionID = $this->action->create('story', $storyID, $action, $fileAction . $this->post->comment);
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
die(js::locate($this->createLink('story', 'view', "storyID=$storyID"), 'parent'));
|
||||
}
|
||||
|
||||
$this->commonAction($storyID);
|
||||
|
||||
/* 赋值到模板。*/
|
||||
$this->view->header->title = $this->view->product->name . $this->lang->colon . $this->lang->story->change . $this->lang->colon . $this->view->story->title;
|
||||
$this->view->position[] = $this->lang->story->change;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/* 需求详情。*/
|
||||
public function view($storyID)
|
||||
public function view($storyID, $version = 0)
|
||||
{
|
||||
$this->loadModel('action');
|
||||
$storyID = (int)$storyID;
|
||||
$story = $this->dao->findByID((int)$storyID)->from(TABLE_STORY)->fetch();
|
||||
$story = $this->story->getById($storyID, $version);
|
||||
$story->files = $this->loadModel('file')->getByObject('story', $storyID);
|
||||
$product = $this->dao->findById($story->product)->from(TABLE_PRODUCT)->fields('name, id')->fetch();
|
||||
$plan = $this->dao->findById($story->plan)->from(TABLE_PRODUCTPLAN)->fetch('title');
|
||||
@@ -149,13 +183,50 @@ class story extends control
|
||||
}
|
||||
else
|
||||
{
|
||||
$story = $this->story->findById($storyID);
|
||||
$story = $this->story->getById($storyID);
|
||||
$this->story->delete($storyID);
|
||||
echo js::locate($this->createLink('product', 'browse', "productID=$story->product"), 'parent');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* 评审一条需求。*/
|
||||
public function review($storyID)
|
||||
{
|
||||
$this->loadModel('action');
|
||||
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$this->story->reivew($storyID);
|
||||
$action = "Reviewed";
|
||||
$actionID = $this->action->create('story', $storyID, $action, $this->post->comment);
|
||||
$this->action->logHistory($actionID);
|
||||
die(js::locate(inlink('view', "storyID=$storyID"), 'parent'));
|
||||
}
|
||||
|
||||
/* 获取需求和产品信息。*/
|
||||
$story = $this->story->getById($storyID);
|
||||
$product = $this->dao->findById($story->product)->from(TABLE_PRODUCT)->fields('name, id')->fetch();
|
||||
|
||||
/* 设置菜单。*/
|
||||
$this->product->setMenu($this->product->getPairs(), $product->id);
|
||||
|
||||
/* 设置评审结果可选值。*/
|
||||
if($story->status == 'draft') unset($this->lang->story->reviewResultList['revert']);
|
||||
|
||||
/* 导航信息。*/
|
||||
$this->view->header->title = $product->name . $this->lang->colon . $this->lang->story->view . $this->lang->colon . $story->title;
|
||||
$this->view->position[] = html::a($this->createLink('product', 'browse', "product=$product->id"), $product->name);
|
||||
$this->view->position[] = $this->lang->story->view;
|
||||
|
||||
/* 赋值。*/
|
||||
$this->view->product = $product;
|
||||
$this->view->story = $story;
|
||||
$this->view->actions = $this->action->getList('story', $storyID);
|
||||
$this->view->users = $this->loadModel('user')->getPairs();
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/* 需求的任务列表。*/
|
||||
public function tasks($storyID, $projectID = 0)
|
||||
{
|
||||
|
||||
@@ -24,51 +24,71 @@
|
||||
$lang->story->common = '需求';
|
||||
$lang->story->create = "新增需求";
|
||||
$lang->story->edit = "编辑需求";
|
||||
$lang->story->change = "变更";
|
||||
$lang->story->delete = "删除需求";
|
||||
$lang->story->browse = "需求列表";
|
||||
$lang->story->view = "需求详情";
|
||||
$lang->story->manage = "操作";
|
||||
$lang->story->tasks = "任务";
|
||||
$lang->story->tasks = "相关任务";
|
||||
$lang->story->bugs = "Bug";
|
||||
|
||||
$lang->story->confirmDelete = "您确认删除该需求吗?";
|
||||
$lang->story->reviewDelete = "您确认删除该需求吗?";
|
||||
$lang->story->errorFormat = '需求数据有误';
|
||||
$lang->story->errorEmptyTitle = '标题不能为空';
|
||||
$lang->story->linkStory = '关联需求';
|
||||
$lang->story->ajaxGetProjectStories = '接口:获取项目需求列表';
|
||||
$lang->story->ajaxGetProductStories = '接口:获取产品需求列表';
|
||||
|
||||
$lang->story->statusList->wait = '未开始';
|
||||
$lang->story->statusList->doing = '进行中';
|
||||
$lang->story->statusList->done = '已完成';
|
||||
$lang->story->statusList[''] = '';
|
||||
$lang->story->statusList['draft'] = '草稿';
|
||||
$lang->story->statusList['active'] = '激活';
|
||||
$lang->story->statusList['closed'] = '已关闭';
|
||||
$lang->story->statusList['changed'] = '已变更';
|
||||
|
||||
$lang->story->stageList[''] = '';
|
||||
$lang->story->stageList['wait'] = '未开始';
|
||||
$lang->story->stageList['planned'] = '已安排';
|
||||
$lang->story->stageList['developing'] = '研发中';
|
||||
$lang->story->stageList['developed'] = '研发完毕';
|
||||
$lang->story->stageList['testing'] = '测试中';
|
||||
$lang->story->stageList['tested'] = '测试完毕';
|
||||
$lang->story->stageList['verified'] = '已验收';
|
||||
$lang->story->stageList['released'] = '已发布';
|
||||
|
||||
$lang->story->reasonList[''] = '';
|
||||
$lang->story->reasonList['done'] = '完成';
|
||||
$lang->story->reasonList['subdivided'] = '已细分';
|
||||
$lang->story->reasonList['duplicate'] = '重复';
|
||||
$lang->story->reasonList['postponed'] = '延期';
|
||||
$lang->story->reasonList['willnotdo'] = '不做';
|
||||
$lang->story->reasonList['cancel'] = '已取消';
|
||||
//$lang->story->reasonList['isbug'] = '是个Bug';
|
||||
|
||||
$lang->story->reviewResultList[''] = '';
|
||||
$lang->story->reviewResultList['pass'] = '通过';
|
||||
$lang->story->reviewResultList['revert'] = '撤销变更';
|
||||
$lang->story->reviewResultList['reject'] = '拒绝';
|
||||
|
||||
$lang->story->priList[3] = '一般';
|
||||
$lang->story->priList[1] = '最高';
|
||||
$lang->story->priList[2] = '较高';
|
||||
$lang->story->priList[4] = '最低';
|
||||
|
||||
$lang->story->labProductAndModule = '产品::模块';
|
||||
|
||||
$lang->story->legendRelated = '相关信息';
|
||||
$lang->story->legendBasicInfo = '基本信息';
|
||||
$lang->story->legendLifeTime = '需求的一生';
|
||||
$lang->story->legendRelated = '相关信息';
|
||||
$lang->story->legendMailto = '抄送给';
|
||||
$lang->story->legendAttatch = '附件';
|
||||
$lang->story->legendLinkBugs = '相关Bug';
|
||||
$lang->story->legendCases = '相关用例';
|
||||
$lang->story->legendOpenInfo = '创建信息';
|
||||
$lang->story->legendResolveInfo = '解决信息';
|
||||
$lang->story->legendCloseInfo = '关闭信息';
|
||||
$lang->story->legendProjectAndTask = '项目::任务';
|
||||
$lang->story->legendProjectAndTask = '项目任务';
|
||||
$lang->story->legendLinkStories = '相关需求';
|
||||
$lang->story->legendChildStories = '细分需求';
|
||||
$lang->story->legendSpec = '需求描述';
|
||||
$lang->story->legendAction = '操作';
|
||||
$lang->story->legendHistory = '历史记录';
|
||||
$lang->story->legendComment = '备注';
|
||||
$lang->story->legendVersion = '历史版本';
|
||||
$lang->story->legendMisc = '其他相关';
|
||||
|
||||
$lang->story->buttonEdit = '编辑';
|
||||
$lang->story->buttonActivate = '激活';
|
||||
$lang->story->buttonResolve = '解决';
|
||||
$lang->story->buttonClose = '关闭';
|
||||
$lang->story->buttonToList = '返回';
|
||||
$lang->story->review = '评审';
|
||||
$lang->story->close = '关闭';
|
||||
|
||||
$lang->story->id = '编号';
|
||||
$lang->story->product = '所属产品';
|
||||
@@ -80,7 +100,8 @@ $lang->story->spec = '需求描述';
|
||||
$lang->story->type = '需求类型 ';
|
||||
$lang->story->pri = '优先级';
|
||||
$lang->story->estimate = '预计工时';
|
||||
$lang->story->status = '状态';
|
||||
$lang->story->status = '当前状态';
|
||||
$lang->story->stage = '所处阶段';
|
||||
$lang->story->mailto = '抄送给';
|
||||
$lang->story->openedBy = '由谁创建';
|
||||
$lang->story->openedDate = '创建日期';
|
||||
@@ -88,9 +109,17 @@ $lang->story->assignedTo = '指派给';
|
||||
$lang->story->assignedDate = '指派日期';
|
||||
$lang->story->lastEditedBy = '最后修改';
|
||||
$lang->story->lastEditedDate = '最后修改日期';
|
||||
$lang->story->lastEdited = '最后修改';
|
||||
$lang->story->closedBy = '由谁关闭';
|
||||
$lang->story->closedDate = '关闭日期';
|
||||
$lang->story->closedReason = '关闭原因';
|
||||
$lang->story->reviewedBy = '由谁评审';
|
||||
$lang->story->reviewedDate = '评审时间';
|
||||
$lang->story->version = '版本号';
|
||||
$lang->story->attatchment = '附件';
|
||||
$lang->story->project = '项目';
|
||||
$lang->story->plan = '计划';
|
||||
$lang->story->project = '所属项目';
|
||||
$lang->story->plan = '所属计划';
|
||||
$lang->story->comment = '备注';
|
||||
$lang->story->linkStories = '相关需求';
|
||||
$lang->story->childStories = '细分需求';
|
||||
$lang->story->duplicateStory = '重复需求';
|
||||
$lang->story->reviewResult = '评审结果';
|
||||
|
||||
@@ -26,66 +26,163 @@
|
||||
class storyModel extends model
|
||||
{
|
||||
/* 获取某一条需求的信息。*/
|
||||
public function findByID($storyID)
|
||||
public function getById($storyID, $version = 0)
|
||||
{
|
||||
return $this->dao->findById((int)$storyID)->from(TABLE_STORY)->fetch();
|
||||
$story = $this->dao->findById((int)$storyID)->from(TABLE_STORY)->fetch();
|
||||
if(!$story) return false;
|
||||
if(substr($story->closedDate, 0, 4) == '0000') $story->closedDate = '';
|
||||
if($version == 0) $version = $story->version;
|
||||
$story->spec = $this->dao->select('spec')->from(TABLE_STORYSPEC)->where('story')->eq($storyID)->andWhere('version')->eq($version)->fetch('spec');
|
||||
$story->projects = $this->dao->select('t1.project, t2.name')
|
||||
->from(TABLE_PROJECTSTORY)->alias('t1')
|
||||
->leftJoin(TABLE_PROJECT)->alias('t2')
|
||||
->on('t1.project = t2.id')
|
||||
->where('t1.story')->eq($storyID)
|
||||
->orderBy('t1.project DESC')
|
||||
->fetchPairs();
|
||||
$story->tasks = $this->dao->select('id,name,project')->from(TABLE_TASK)->where('story')->eq($storyID)->orderBy('id DESC')->fetchAll();
|
||||
//$story->bugCount = $this->dao->select('COUNT(*)')->alias('count')->from(TABLE_BUG)->where('story')->eq($storyID)->fetch('count');
|
||||
//$story->caseCount = $this->dao->select('COUNT(*)')->alias('count')->from(TABLE_CASE)->where('story')->eq($storyID)->fetch('count');
|
||||
if($story->toBug) $story->toBugTitle = $this->dao->findById($story->toBug)->from(TABLE_BUG)->fetch('title');
|
||||
if($story->plan) $story->planTitle = $this->dao->findById($story->plan)->from(TABLE_PRODUCTPLAN)->fetch('title');
|
||||
$extraStories = array();
|
||||
if($story->duplicateStory) $extraStories = array($story->duplicateStory);
|
||||
if($story->linkStories) $extraStories = explode(',', $story->linkStories);
|
||||
if($story->childStories) $extraStories = array_merge($extraStories, explode(',', $story->childStories));
|
||||
$extraStories = array_unique($extraStories);
|
||||
if(!empty($extraStories)) $story->extraStories = $this->dao->select('id,title')->from(TABLE_STORY)->where('id')->in($extraStories)->fetchPairs();
|
||||
return $story;
|
||||
}
|
||||
|
||||
/* 新增需求。*/
|
||||
function create()
|
||||
public function create()
|
||||
{
|
||||
$now = date('Y-m-d H:i:s', time());
|
||||
$story = fixer::input('post')
|
||||
->cleanInt('product,module,pri,plan')
|
||||
->cleanFloat('estimate')
|
||||
->stripTags('title')
|
||||
->specialChars('spec')
|
||||
->setDefault('plan', 0)
|
||||
->add('openedBy', $this->app->user->account)
|
||||
->add('openedDate', $now)
|
||||
->add('assignedDate', 0)
|
||||
->add('version', 1)
|
||||
->add('status', 'draft')
|
||||
->setIF($this->post->assignedTo != '', 'assignedDate', $now)
|
||||
->remove('files,labels')
|
||||
->join('mailto', ',')
|
||||
->remove('files,labels,spec')
|
||||
->get();
|
||||
$this->dao->insert(TABLE_STORY)->data($story)->autoCheck()->check('title', 'notempty')->exec();
|
||||
$this->dao->insert(TABLE_STORY)->data($story)->autoCheck()->batchCheck('title,estimate', 'notempty')->exec();
|
||||
if(!dao::isError())
|
||||
{
|
||||
$storyID = $this->dao->lastInsertID();
|
||||
$this->loadModel('file')->saveUpload('story', $storyID);
|
||||
$spec = htmlspecialchars($this->post->spec);
|
||||
$this->dao->insert(TABLE_STORYSPEC)->set('story')->eq($storyID)->set('version')->eq(1)->set('spec')->eq($spec)->exec();
|
||||
return $storyID;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 更新需求。*/
|
||||
function update($storyID)
|
||||
/* 变更需求。*/
|
||||
public function change($storyID)
|
||||
{
|
||||
$now = date('Y-m-d H:i:s', time());
|
||||
$oldStory = $this->findByID($storyID);
|
||||
$story = fixer::input('post')
|
||||
$now = date('Y-m-d H:i:s', time());
|
||||
$oldStory = $this->getById($storyID);
|
||||
$specChanged = false;
|
||||
if($this->post->spec != $oldStory->spec or $this->post->title != $oldStory->title or $this->loadModel('file')->getCount()) $specChanged = true;
|
||||
|
||||
$story = fixer::input('post')
|
||||
->stripTags('title')
|
||||
->add('lastEditedBy', $this->app->user->account)
|
||||
->add('lastEditedDate', $now)
|
||||
->setIF($this->post->assignedTo != $oldStory->assignedTo, 'assignedDate', $now)
|
||||
->setIF($specChanged, 'version', $oldStory->version + 1)
|
||||
->setIF($specChanged, 'status', 'changed')
|
||||
->setIF($specChanged, 'reviewedBy', '')
|
||||
->setIF($specChanged, 'closedBy', '')
|
||||
->setIF($specChanged, 'closedReason', '')
|
||||
->setIF($specChanged and $oldStory->reviewedBy, 'reviewedDate', '')
|
||||
->setIF($specChanged and $oldStory->closedBy, 'closedDate', '')
|
||||
->remove('files,labels,spec,comment')
|
||||
->get();
|
||||
|
||||
$this->dao->update(TABLE_STORY)
|
||||
->data($story)
|
||||
->autoCheck()
|
||||
->check('title', 'notempty')
|
||||
->where('id')->eq((int)$storyID)->exec();
|
||||
if(!dao::isError())
|
||||
{
|
||||
if($specChanged)
|
||||
{
|
||||
$spec = htmlspecialchars($this->post->spec);
|
||||
$this->dao->insert(TABLE_STORYSPEC)->set('story')->eq($storyID)->set('version')->eq($oldStory->version + 1)->set('spec')->eq($spec)->exec();
|
||||
$story->spec = $this->post->spec;
|
||||
}
|
||||
else
|
||||
{
|
||||
unset($oldStory->spec);
|
||||
}
|
||||
return common::createChanges($oldStory, $story);
|
||||
}
|
||||
}
|
||||
|
||||
/* 更新需求。*/
|
||||
public function update($storyID)
|
||||
{
|
||||
$now = date('Y-m-d H:i:s', time());
|
||||
$oldStory = $this->getById($storyID);
|
||||
|
||||
$story = fixer::input('post')
|
||||
->cleanInt('product,module,pri,plan')
|
||||
->stripTags('title')
|
||||
->specialChars('spec')
|
||||
->remove('comment')
|
||||
->add('assignedDate', $oldStory->assignedDate)
|
||||
->add('lastEditedBy', $this->app->user->account)
|
||||
->add('lastEditedDate', $now)
|
||||
->setDefault('plan', 0)
|
||||
->setIF($this->post->assignedTo != $oldStory->assignedTo, 'assignedDate', $now)
|
||||
->remove('files,labels')
|
||||
->setDefault('status', $oldStory->status)
|
||||
->setIF($this->post->assignedTo != $oldStory->assignedTo, 'assignedDate', $now)
|
||||
->setIF($this->post->closedBy != false and $oldStory->closedDate == '', 'closedDate', $now)
|
||||
->setIF($this->post->closedReason != false and $oldStory->closedDate == '', 'closedDate', $now)
|
||||
->setIF($this->post->closedBy != false or $this->post->closedReason != false, 'status', 'closed')
|
||||
->setIF($this->post->closedReason != false and $this->post->closedBy == false, 'closedBy', $this->app->user->account)
|
||||
->setIF($oldStory->status == 'draft', 'stage', '')
|
||||
->remove('files,labels,comment')
|
||||
->get();
|
||||
$this->dao->update(TABLE_STORY)->data($story)->autoCheck()->check('title', 'notempty')->where('id')->eq((int)$storyID)->exec();
|
||||
|
||||
$this->dao->update(TABLE_STORY)
|
||||
->data($story)
|
||||
->autoCheck()
|
||||
->check('title', 'notempty')
|
||||
->checkIF($story->closedBy, 'closedReason', 'notempty')
|
||||
->checkIF($story->status == 'closed', 'stage', 'notempty')
|
||||
->checkIF($story->closedReason == 'duplicate', 'duplicateStory', 'notempty')
|
||||
->checkIF($story->closedReason == 'subdivided', 'childStories', 'notempty')
|
||||
->where('id')->eq((int)$storyID)->exec();
|
||||
if(!dao::isError()) return common::createChanges($oldStory, $story);
|
||||
}
|
||||
|
||||
/* 删除一条需求。*/
|
||||
function delete($storyID)
|
||||
public function delete($storyID)
|
||||
{
|
||||
$this->dao->delete()->from(TABLE_STORY)->where('id')->eq((int)$storyID)->limit(1)->exec();
|
||||
}
|
||||
|
||||
/* 评审需求。*/
|
||||
public function review($storyID)
|
||||
{
|
||||
$oldStory = $this->dao->findById($storyID)->from(TABLE_STORY)->fetch();
|
||||
$story->confirmedBy = $this->app->user->account;
|
||||
$story->confirmedDate = date('Y-m-d H:i:s');
|
||||
$story->status = 'active';
|
||||
if($oldStory->status == 'changed') $story->version = $oldStory->version + 1;
|
||||
$this->dao->update(TABLE_STORY)->data($story)->where('id')->eq($storyID)->exec();
|
||||
return true;
|
||||
}
|
||||
|
||||
/* 获得某一个产品某一个模块下面的所有需求列表。*/
|
||||
function getProductStories($productID = 0, $moduleIds = 0, $status = 'all', $orderBy = 'id|desc', $pager = null)
|
||||
public function getProductStories($productID = 0, $moduleIds = 0, $status = 'all', $orderBy = 'id|desc', $pager = null)
|
||||
{
|
||||
return $this->dao->select('t1.*, t2.title as planTitle')
|
||||
->from(TABLE_STORY)->alias('t1')
|
||||
@@ -97,7 +194,7 @@ class storyModel extends model
|
||||
}
|
||||
|
||||
/* 获得某一个产品某一个模块下面的所有需求id=>title列表。*/
|
||||
function getProductStoryPairs($productID = 0, $moduleIds = 0, $status = 'all', $order = 'id|desc')
|
||||
public function getProductStoryPairs($productID = 0, $moduleIds = 0, $status = 'all', $order = 'id|desc')
|
||||
{
|
||||
$sql = $this->dao->select('t1.id, t1.title, t1.module, t2.name AS product')
|
||||
->from(TABLE_STORY)->alias('t1')->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product = t2.id')
|
||||
@@ -128,7 +225,7 @@ class storyModel extends model
|
||||
}
|
||||
|
||||
/* 获得某一个项目相关的所有需求列表。*/
|
||||
function getProjectStories($projectID = 0, $orderBy='id|desc', $pager = null)
|
||||
public function getProjectStories($projectID = 0, $orderBy='id|desc', $pager = null)
|
||||
{
|
||||
return $this->dao->select('t1.*, t2.*')->from(TABLE_PROJECTSTORY)->alias('t1')
|
||||
->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id')
|
||||
@@ -138,7 +235,7 @@ class storyModel extends model
|
||||
}
|
||||
|
||||
/* 获得某一个项目相关的需求id=>title的列表。*/
|
||||
function getProjectStoryPairs($projectID = 0, $productID = 0)
|
||||
public function getProjectStoryPairs($projectID = 0, $productID = 0)
|
||||
{
|
||||
$sql = $this->dao->select('t2.id, t2.title, t2.module, t3.name AS product')
|
||||
->from(TABLE_PROJECTSTORY)->alias('t1')
|
||||
@@ -168,7 +265,7 @@ class storyModel extends model
|
||||
}
|
||||
|
||||
/* 获得指派给某一个用户的需求列表。*/
|
||||
function getUserStories($account, $status = 'all', $orderBy = 'id|desc', $pager = null)
|
||||
public function getUserStories($account, $status = 'all', $orderBy = 'id|desc', $pager = null)
|
||||
{
|
||||
return $this->dao->select('t1.*, t2.title as planTitle, t3.name as productTitle')
|
||||
->from(TABLE_STORY)->alias('t1')
|
||||
|
||||
59
trunk/module/story/view/change.html.php
Normal file
59
trunk/module/story/view/change.html.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* The change view file of story module of ZenTaoMS.
|
||||
*
|
||||
* ZenTaoMS is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ZenTaoMS is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with ZenTaoMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @copyright Copyright: 2009 Chunsheng Wang
|
||||
* @author Chunsheng Wang <wwccss@263.net>
|
||||
* @package story
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.cn
|
||||
*/
|
||||
?>
|
||||
<?php include './header.html.php';?>
|
||||
<div class='yui-d0'>
|
||||
<form method='post' enctype='multipart/form-data' target='hiddenwin'>
|
||||
<table class='table-1'>
|
||||
<caption><?php echo $lang->story->change;?></caption>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->reviewedBy;?></th>
|
||||
<td><?php echo html::select('assignedTo', $users, '', 'class="select-3"');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->title;?></th>
|
||||
<td><?php echo html::input('title', $story->title, 'class="text-1"');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->spec;?></th>
|
||||
<td><?php echo html::textarea('spec', $story->spec, 'rows=5 class="area-1"');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->comment;?></th>
|
||||
<td><?php echo html::textarea('comment', '', 'rows=5 class="area-1"');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->attatch;?></th>
|
||||
<td><?php echo $this->fetch('file', 'buildform', 'filecount=2');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan='2' class='a-center'>
|
||||
<?php echo html::submitButton() . html::linkButton($lang->goback, inlink('view', "storyID=$story->id"));?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php include '../../common/action.html.php';?>
|
||||
</form>
|
||||
</div>
|
||||
<?php include '../../common/footer.html.php';?>
|
||||
@@ -22,72 +22,54 @@
|
||||
* @link http://www.zentao.cn
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/header.html.php';?>
|
||||
<script language='Javascript'>
|
||||
function loadModuleMenu(productID)
|
||||
{
|
||||
link = createLink('tree', 'ajaxGetOptionMenu', 'productID=' + productID + '&viewtype=product');
|
||||
$('#moduleIdBox').load(link);
|
||||
}
|
||||
</script>
|
||||
<div id='doc3'>
|
||||
<?php include './header.html.php';?>
|
||||
<style>
|
||||
#plan {width:245px}
|
||||
</style>
|
||||
<div class='yui-d0'>
|
||||
<form method='post' enctype='multipart/form-data' target='hiddenwin'>
|
||||
<table align='center' class='table-1'>
|
||||
<caption><?php echo $lang->story->create;?></caption>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->product;?></th>
|
||||
<td class='a-left'>
|
||||
<?php echo html::select('product', $products, $product->id, "onchange=loadModuleMenu(this.value); class='select-3'");?>
|
||||
<td>
|
||||
<?php echo html::select('product', $products, $product->id, "onchange=loadProduct(this.value); class='select-3'");?>
|
||||
<span id='moduleIdBox'><?php echo html::select('module', $moduleOptionMenu, $moduleID);?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->plan;?></th>
|
||||
<td class='a-left'>
|
||||
<?php echo html::select('plan', $plans, '', 'class=select-3');?>
|
||||
</td>
|
||||
<td><span id='planIdBox'><?php echo html::select('plan', $plans, '', 'class=select-3');?></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->pri;?></th>
|
||||
<td class='a-left'>
|
||||
<?php echo html::select('pri', (array)$lang->story->priList, '', 'class=select-3');?>
|
||||
</td>
|
||||
<td><?php echo html::select('pri', (array)$lang->story->priList, '', 'class=select-3');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->assignedTo;?></th>
|
||||
<td class='a-left'>
|
||||
<?php echo html::select('assignedTo', $users, $app->user->account, 'class=select-3');?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->estimate;?></th>
|
||||
<td class='a-left'><input type='text' name='estimate' id='estimate' class='text-3' /></td>
|
||||
<td><input type='text' name='estimate' id='estimate' class='text-3' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->status;?></th>
|
||||
<td class='a-left'>
|
||||
<?php echo html::select('status', (array)$lang->story->statusList, '', 'class=select-3');?>
|
||||
</td>
|
||||
</tr>
|
||||
<th class='rowhead'><?php echo $lang->story->assignedTo;?></th>
|
||||
<td><?php echo html::select('assignedTo', $users, '', 'class=select-3');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->title;?></th>
|
||||
<td class='a-left'><input type='text' name='title' class='text-1' /></td>
|
||||
<td><input type='text' name='title' class='text-1' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->spec;?></th>
|
||||
<td class='a-left'><textarea name='spec' rows='8' class='text-1'></textarea></td>
|
||||
<td><textarea name='spec' rows='8' class='text-1'></textarea></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><nobr><?php echo $lang->story->mailto;?></nobr></th>
|
||||
<td><?php echo html::input('mailto', '', 'class="text-1"');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->legendAttatch;?></th>
|
||||
<td class='a-left'><?php echo $this->fetch('file', 'buildform');?></td>
|
||||
<td><?php echo $this->fetch('file', 'buildform');?></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan='2'>
|
||||
<input type='submit' value='<?php echo $lang->save;?>' class='button-s' />
|
||||
<input type='reset' value='<?php echo $lang->reset;?>' class='button-r' />
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td colspan='2' class='a-center'><?php echo html::submitButton() . html::resetButton();?></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<?php
|
||||
/**
|
||||
* The edit view of story module of ZenTaoMS.
|
||||
* The edit view file of story module of ZenTaoMS.
|
||||
*
|
||||
* ZenTaoMS is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* ZenTaoMS is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
@@ -22,79 +22,114 @@
|
||||
* @link http://www.zentao.cn
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/header.html.php';?>
|
||||
<script language='Javascript'>
|
||||
function loadModuleMenu(productID)
|
||||
{
|
||||
link = createLink('tree', 'ajaxGetOptionMenu', 'productID=' + productID + '&viewtype=product');
|
||||
$('#moduleIdBox').load(link);
|
||||
}
|
||||
</script>
|
||||
<?php include './header.html.php';?>
|
||||
<style>
|
||||
#module, #plan {width:90%}
|
||||
</style>
|
||||
<form method='post' enctype='multipart/form-data' target='hiddenwin'>
|
||||
<div class='yui-d0'>
|
||||
<form method='post' enctype='multipart/form-data' target='hiddenwin'>
|
||||
<table class='table-1'>
|
||||
<caption><?php echo $lang->story->edit;?></caption>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->product;?></th>
|
||||
<td class='a-left'>
|
||||
<?php echo html::select('product', $products, $story->product, "onchange=loadModuleMenu(this.value); class='select-3'");?>
|
||||
<span id='moduleIdBox'><?php echo html::select('module', $moduleOptionMenu, $story->module);?></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->plan;?></th>
|
||||
<td class='a-left'>
|
||||
<?php echo html::select('plan', $plans, $story->plan, 'class=select-3');?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->pri;?></th>
|
||||
<td class='a-left'>
|
||||
<?php echo html::select('pri', (array)$lang->story->priList, $story->pri, 'class=select-3');?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->openedBy;?></th>
|
||||
<td class='a-left'>
|
||||
<?php echo html::select('openedBy', $users, $story->openedBy, 'class=select-3');?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->assignedTo;?></th>
|
||||
<td class='a-left'>
|
||||
<?php echo html::select('assignedTo', $users, $story->assignedTo, 'class=select-3');?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->estimate;?></th>
|
||||
<td class='a-left'><input type='text' name='estimate' id='estimate' class='text-3' value='<?php echo $story->estimate;?>' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->status;?></th>
|
||||
<td class='a-left'>
|
||||
<?php echo html::select('status', (array)$lang->story->statusList, $story->status, 'class=select-3');?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->title;?></th>
|
||||
<td class='a-left'><input type='text' name='title' value='<?php echo $story->title;?>' class='text-1' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->spec;?></th>
|
||||
<td class='a-left'><textarea name='spec' rows='5' class='text-1'><?php echo $story->spec;?></textarea></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->comment;?></th>
|
||||
<td class='a-left'><textarea name='comment' rows='4' class='text-1'></textarea></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->legendAttatch;?></th>
|
||||
<td class='a-left'><?php echo $this->fetch('file', 'buildform');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan='2' class='a-center'><?php echo html::submitButton() . html::resetButton();?></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
<div id='titlebar'>
|
||||
<div id='main'>STORY #<?php echo $story->id . $lang->colon . $story->title;?></div>
|
||||
<div><?php echo html::submitButton()?></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='yui-d0 yui-t8'>
|
||||
<div class='yui-main'>
|
||||
<div class='yui-b'>
|
||||
<fieldset>
|
||||
<legend><?php echo $lang->story->legendSpec;?></legend>
|
||||
<div class='content'><?php echo nl2br($story->spec);?></div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend><?php echo $lang->story->comment;?></legend>
|
||||
<textarea name='comment' rows='5' class='area-1'></textarea>
|
||||
</fieldset>
|
||||
<div class='a-center'><?php echo html::submitButton() . html::linkButton($lang->goback, inlink('view', "storyID=$story->id"));?></div>
|
||||
<?php include '../../common/action.html.php';?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='yui-b'>
|
||||
<fieldset>
|
||||
<legend><?php echo $lang->story->legendBasicInfo;?></legend>
|
||||
<table class='table-1'>
|
||||
<tr>
|
||||
<td class='rowhead w-p20'><?php echo $lang->story->product;?></td>
|
||||
<td><?php echo html::select('product', $products, $story->product, 'class="select-1" onchange="loadProduct(this.value)";');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->module;?></td>
|
||||
<td><span id='moduleIdBox'><?php echo html::select('module', $moduleOptionMenu, $story->module, 'class="select-1"');?></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->plan;?></td>
|
||||
<td><span id='planIdBox'><?php echo html::select('plan', $plans, $story->plan, 'class=select-1');?></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->status;?></td>
|
||||
<td><?php echo $lang->story->statusList[$story->status];?></td>
|
||||
</tr>
|
||||
<?php if($story->status != 'draft'):?>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->stage;?></td>
|
||||
<td><?php echo html::select('stage', $lang->story->stageList, $story->stage, 'class=select-1');?></td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
</table>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend><?php echo $lang->story->legendLifeTime;?></legend>
|
||||
<table class='table-1'>
|
||||
<tr>
|
||||
<td class='rowhead w-p20'><?php echo $lang->story->openedBy;?></td>
|
||||
<td><?php echo $users[$story->openedBy];?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->assignedTo;?></td>
|
||||
<td><?php echo html::select('assignedTo', $users, $story->assignedTo, 'class="select-1"');?></td>
|
||||
</tr>
|
||||
<?php if($story->reviewedBy):?>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->reviewedBy;?></td>
|
||||
<td><?php echo html::textarea('reviewedBy', $story->reviewedBy, 'class="area-1"');?></td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<?php if($story->closedBy):?>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->closedBy;?></td>
|
||||
<td><?php echo html::select('closedBy', $users, $story->closedBy, 'class="select-1"');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->closedReason;?></td>
|
||||
<td><?php echo html::select('closedReason', $lang->story->reasonList, $story->closedReason, 'class="select-1"');?></td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
</table>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend><?php echo $lang->story->legendMisc;?></legend>
|
||||
<table class='table-1'>
|
||||
<tr>
|
||||
<td class='rowhead w-p20'><?php echo $lang->story->duplicateStory;?></td>
|
||||
<td><?php echo html::input('duplicateStory', $story->duplicateStory, "class='text-1'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='rowhead w-p20'><?php echo $lang->story->linkStories;?></td>
|
||||
<td><?php echo html::input('linkStories', $story->linkStories, "class='text-1'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->childStories;?></td>
|
||||
<td><?php echo html::input('childStories', $story->childStories, "class='text-1'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->mailto;?></td>
|
||||
<td><?php echo html::textarea('mailto', $story->mailto, "class='area-1'");?></td>
|
||||
</tr>
|
||||
</table>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<?php include '../../common/footer.html.php';?>
|
||||
|
||||
16
trunk/module/story/view/header.html.php
Normal file
16
trunk/module/story/view/header.html.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php include '../../common/header.html.php';?>
|
||||
<?php include '../../common/autocomplete.html.php';?>
|
||||
<script language='Javascript'>
|
||||
function loadProduct(productID)
|
||||
{
|
||||
moduleLink = createLink('tree', 'ajaxGetOptionMenu', 'productID=' + productID + '&viewtype=product');
|
||||
planLink = createLink('product', 'ajaxGetPlans', 'productID=' + productID + '&planID=' + $('#plan').val());
|
||||
$('#moduleIdBox').load(moduleLink);
|
||||
$('#planIdBox').load(planLink);
|
||||
}
|
||||
var userList = "<?php echo join(',', array_keys($users));?>".split(',');
|
||||
$(function() {
|
||||
$("#reviewedBy").autocomplete(userList,{multiple: true,mustMatch: true});
|
||||
$("#mailto").autocomplete(userList, { multiple: true, mustMatch: true});
|
||||
})
|
||||
</script>
|
||||
73
trunk/module/story/view/review.html.php
Normal file
73
trunk/module/story/view/review.html.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* The confirm view file of story module of ZenTaoMS.
|
||||
*
|
||||
* ZenTaoMS is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* ZenTaoMS is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with ZenTaoMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @copyright Copyright: 2009 Chunsheng Wang
|
||||
* @author Chunsheng Wang <wwccss@263.net>
|
||||
* @package story
|
||||
* @version $Id$
|
||||
* @link http://www.zentao.cn
|
||||
*/
|
||||
?>
|
||||
<?php include './header.html.php';?>
|
||||
<script language='Javascript'>
|
||||
function setClosedReason(result)
|
||||
{
|
||||
if(result == 'reject')
|
||||
{
|
||||
$('#closedReasonBox').show();
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#closedReasonBox').hide();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<div class='yui-d0'>
|
||||
<form method='post' target='hiddenwin'>
|
||||
<table class='table-1'>
|
||||
<caption><?php echo $story->title;?></caption>
|
||||
<tr>
|
||||
<th class='w-100px rowhead'><?php echo $lang->story->reviewResult;?></th>
|
||||
<td><?php echo html::select('result', $lang->story->reviewResultList, '', 'class=select-3 onchange="setClosedReason(this.value)"');?></td>
|
||||
</tr>
|
||||
<tr id='closedReasonBox' class='hidden'>
|
||||
<th class='rowhead'><?php echo $lang->story->closedReason;?></th>
|
||||
<td><?php echo html::select('closedReason', $lang->story->reasonList, '', 'class=select-3');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->assignedTo;?></th>
|
||||
<td><?php echo html::select('assignedTo', $users, $story->openedBy, 'class=select-3');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->reviewedBy;?></th>
|
||||
<td><?php echo html::input('reviewedBy', $app->user->account . ', ', 'class=text-1');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='rowhead'><?php echo $lang->story->comment;?></th>
|
||||
<td><textarea rows='8' name='comment' class='area-1'></textarea></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan='2' class='a-center'>
|
||||
<?php echo html::submitButton();?>
|
||||
<?php echo html::linkButton($lang->goback, inlink('view', "storyID=$story->id"));?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<?php include '../../common/action.html.php';?>
|
||||
</div>
|
||||
<?php include '../../common/footer.html.php';?>
|
||||
@@ -29,18 +29,18 @@
|
||||
<div id='main'>STORY #<?php echo $story->id . $lang->colon . $story->title;?></div>
|
||||
<div>
|
||||
<?php
|
||||
if(common::hasPriv('story', 'edit')) echo html::a($this->createLink('story', 'edit', "storyID=$story->id"), $lang->story->buttonEdit);
|
||||
if(common::hasPriv('product', 'browse'))
|
||||
{
|
||||
if($app->session->storyList != '') echo html::a($app->session->storyList, $lang->story->buttonToList);
|
||||
else echo html::a($this->createLink('product', 'browse', "productID=$story->product&moduleID=$story->module"), $lang->story->buttonToList);
|
||||
}
|
||||
$browseLink = $app->session->storyList != false ? $app->session->storyList : $this->createLink('product', 'browse', "productID=$story->product&moduleID=$story->module");
|
||||
common::printLink('story', 'change', "storyID=$story->id", $lang->story->change);
|
||||
if($story->status == 'draft' or $story->status == 'changed') common::printLink('story', 'review', "storyID=$story->id", $lang->story->review); else echo $lang->story->review . ' ';
|
||||
common::printLink('story', 'close', "storyID=$story->id", $lang->close);
|
||||
common::printLink('story', 'edit', "storyID=$story->id", $lang->edit);
|
||||
echo html::a($browseLink, $lang->goback);
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='yui-d0 yui-t6'>
|
||||
<div class='yui-d0 yui-t8'>
|
||||
<div class='yui-main'>
|
||||
<div class='yui-b'>
|
||||
<fieldset>
|
||||
@@ -52,34 +52,32 @@
|
||||
<div><?php foreach($story->files as $file) echo html::a($file->fullPath, $file->title, '_blank');?></div>
|
||||
</fieldset>
|
||||
<?php include '../../common/action.html.php';?>
|
||||
<fieldset>
|
||||
<legend><?php echo $lang->story->legendAction;?></legend>
|
||||
<div class='a-center' style='font-size:16px; font-weight:bold'>
|
||||
<?php
|
||||
if(common::hasPriv('story', 'edit')) echo html::a($this->createLink('story', 'edit', "storyID=$story->id"), $lang->story->buttonEdit);
|
||||
if(common::hasPriv('product', 'browse'))
|
||||
{
|
||||
if($app->session->storyList != '') echo html::a($app->session->storyList, $lang->story->buttonToList);
|
||||
else echo html::a($this->createLink('product', 'browse', "productID=$story->product&moduleID=$story->module"), $lang->story->buttonToList);
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class='a-center' style='font-size:16px; font-weight:bold'>
|
||||
<?php
|
||||
common::printLink('story', 'edit', "storyID=$story->id", $lang->edit);
|
||||
common::printLink('story', 'review', "storyID=$story->id", $lang->story->review);
|
||||
common::printLink('story', 'close', "storyID=$story->id", $lang->story->close);
|
||||
echo html::a($browseLink, $lang->goback);
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='yui-b'>
|
||||
<fieldset>
|
||||
<legend><?php echo $lang->story->legendBasicInfo;?></legend>
|
||||
<table class='table-1 a-left' cellpadding='0' cellspacing='0'>
|
||||
<table class='table-1'>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->labProductAndModule;?></td>
|
||||
<td>
|
||||
<td class='rowhead w-p20'><?php echo $lang->story->product;?></td>
|
||||
<td><?php common::printLink('product', 'view', "productID=$story->product", $product->name);?>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->module;?></td>
|
||||
<td>
|
||||
<?php
|
||||
echo $product->name;
|
||||
if(!empty($modulePath)) echo $lang->arrow;
|
||||
foreach($modulePath as $key => $module)
|
||||
{
|
||||
echo $module->name;
|
||||
if(!common::printLink('product', 'browse', "productID=$story->product&browseType=byModule¶m=$module->id", $module->name)) echo $module->name;
|
||||
if(isset($modulePath[$key + 1])) echo $lang->arrow;
|
||||
}
|
||||
?>
|
||||
@@ -87,95 +85,105 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->plan;?></td>
|
||||
<td><?php echo $plan;?></td>
|
||||
<td><?php if(isset($story->planTitle)) if(!common::printLink('productplan', 'view', "planID=$story->plan", $story->planTitle)) echo $story->planTitle;?>
|
||||
</tr>
|
||||
<!--
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->type;?></td>
|
||||
<td><?php //echo $lang->story->typeList->{$story->type};?></td>
|
||||
</tr>
|
||||
-->
|
||||
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->status;?></td>
|
||||
<td><?php $lang->show($lang->story->statusList, $story->status);?></td>
|
||||
<td><?php echo $lang->story->statusList[$story->status];?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->assignedTo;?></td>
|
||||
<td><?php echo $users[$story->assignedTo];?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width='40%' class='rowhead'><?php echo $lang->story->assignedDate;?></td>
|
||||
<td><?php echo $story->assignedDate;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->lastEditedBy;?></td>
|
||||
<td><?php echo $users[$story->lastEditedBy];?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->lastEditedDate;?></td>
|
||||
<td><?php echo $story->lastEditedDate;?></td>
|
||||
<td class='rowhead'><?php echo $lang->story->stage;?></td>
|
||||
<td><?php echo $lang->story->stageList[$story->stage];?></td>
|
||||
</tr>
|
||||
</table>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend><?php echo $lang->story->legendMailto;?></legend>
|
||||
<div></div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend><?php echo $lang->story->legendOpenInfo;?></legend>
|
||||
<table class='table-1 a-left'>
|
||||
<legend><?php echo $lang->story->legendLifeTime;?></legend>
|
||||
<table class='table-1'>
|
||||
<tr>
|
||||
<td width='40%' class='rowhead'><?php echo $lang->story->openedBy;?></td>
|
||||
<td><?php echo $users[$story->openedBy];?></td>
|
||||
<td class='rowhead w-p20'><?php echo $lang->story->openedBy;?></td>
|
||||
<td><?php echo $users[$story->openedBy] . $lang->at . $story->openedDate;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->openedDate;?></td>
|
||||
<td><?php echo $story->openedDate;?></td>
|
||||
<td class='rowhead'><?php echo $lang->story->assignedTo;?></td>
|
||||
<td><?php if($story->assignedTo) echo $users[$story->assignedTo] . $lang->at . $story->assignedDate;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->reviewedBy;?></td>
|
||||
<td><?php $reviewedBy = explode(',', $story->reviewedBy); foreach($reviewedBy as $account) echo ' ' . $users[trim($account)]; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->closedBy;?></td>
|
||||
<td><?php if($story->closedBy) echo $users[$story->closedBy] . $lang->at . $story->closedDate;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->closedReason;?></td>
|
||||
<td>
|
||||
<?php
|
||||
if($story->closedReason) echo $lang->story->reasonList[$story->closedReason];
|
||||
if($story->duplicateStory)
|
||||
{
|
||||
echo html::a(inlink('view', "storyID=$story->duplicateStory", '#' . $story->duplicateStory . ' ' . $story->extraStories[$story->duplicateStory]));
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->lastEditedBy;?></td>
|
||||
<td><?php if($story->lastEditedBy) echo $users[$story->lastEditedBy] . $lang->at . $story->lastEditedDate;?></td>
|
||||
</tr>
|
||||
</table>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend><?php echo $lang->story->legendProjectAndTask;?></legend>
|
||||
<table class='table-1 a-left'>
|
||||
<table class='table-1 fixed'>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->project;?></td>
|
||||
<td><?php //echo $story->project;?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->tasks;?></td>
|
||||
<td><?php //echo $story->tasks;?></td>
|
||||
<td>
|
||||
<?php
|
||||
foreach($story->tasks as $task)
|
||||
{
|
||||
$projectName = $story->projects[$task->project];
|
||||
echo html::a($this->createLink('project', 'browse', "projectID=$task->project"), $projectName);
|
||||
echo html::a($this->createLink('task', 'view', "taskID=$task->id"), "#$task->id $task->name") . '<br />';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</fieldset>
|
||||
|
||||
<!--
|
||||
<fieldset>
|
||||
<legend><?php echo $lang->story->legendCloseInfo;?></legend>
|
||||
<table class='table-1 a-left'>
|
||||
<tr>
|
||||
<td width='40%' class='rowhead'><?php echo $lang->story->closedBy;?></td>
|
||||
<td><?php echo $users[$story->closedBy];?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class='rowhead'><?php echo $lang->story->closedDate;?></td>
|
||||
<td><?php echo $story->closedDate;?></td>
|
||||
</tr>
|
||||
</table>
|
||||
<legend><?php echo $lang->story->legendLinkStories;?></legend>
|
||||
<div>
|
||||
<?php
|
||||
$linkStories = explode(',', $story->linkStories) ;
|
||||
foreach($linkStories as $linkStoryID)
|
||||
{
|
||||
if(isset($story->extraStories[$linkStoryID])) echo html::a(inlink('view', "storyID=$linkStoryID"), "#$linkStoryID " . $story->extraStories[$linkStoryID]) . '<br />';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</fieldset>
|
||||
-->
|
||||
|
||||
<fieldset>
|
||||
<legend><?php echo $lang->story->legendLinkBugs;?></legend>
|
||||
<div> </div>
|
||||
<legend><?php echo $lang->story->legendChildStories;?></legend>
|
||||
<div>
|
||||
<?php
|
||||
$childStories = explode(',', $story->childStories) ;
|
||||
foreach($childStories as $childStoryID)
|
||||
{
|
||||
if(isset($story->extraStories[$childStoryID])) echo html::a(inlink('view', "storyID=$childStoryID"), "#$childStoryID " . $story->extraStories[$childStoryID]) . '<br />';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend><?php echo $lang->story->legendCases;?></legend>
|
||||
<div> </div>
|
||||
<legend><?php echo $lang->story->legendMailto;?></legend>
|
||||
<div><?php $mailto = explode(',', $story->mailto); foreach($mailto as $account) echo ' ' . $users[trim($account)]; ?></div>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend><?php echo $lang->story->legendVersion;?></legend>
|
||||
<div><?php for($i = $story->version; $i >= 1; $i --) echo html::a(inlink('view', "storyID=$story->id&version=$i"), "#$i");?></div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user