* code for task#803.

* add batchEdit for story.
This commit is contained in:
chencongzhi520@gmail.com
2012-06-02 08:25:17 +00:00
parent a3327c0ab8
commit a321746fbb
13 changed files with 510 additions and 132 deletions
+10
View File
@@ -1553,6 +1553,16 @@ INSERT INTO `zt_groupPriv` (`company`, `group`, `module`, `method`) VALUES
(1, 3, 'todo', 'batchEdit'),
(1, 4, 'todo', 'batchEdit'),
(1, 5, 'todo', 'batchEdit'),
(1, 1, 'story', 'batchEdit'),
(1, 2, 'story', 'batchEdit'),
(1, 3, 'story', 'batchEdit'),
(1, 4, 'story', 'batchEdit'),
(1, 5, 'story', 'batchEdit'),
(1, 1, 'story', 'batchClose'),
(1, 2, 'story', 'batchClose'),
(1, 3, 'story', 'batchClose'),
(1, 4, 'story', 'batchClose'),
(1, 5, 'story', 'batchClose'),
(1, 1, 'task', 'batchEdit'),
(1, 2, 'task', 'batchEdit'),
(1, 3, 'task', 'batchEdit'),
+1 -1
View File
@@ -157,7 +157,7 @@ $lang->release->menu = $lang->product->menu;
/* 项目视图菜单设置。*/
$lang->project->menu->list = '%s';
$lang->project->menu->task = array('link' => '任务|project|task|projectID=%s', 'subModule' => 'task', 'alias' => 'grouptask,importtask');
$lang->project->menu->story = array('link' => '需求|project|story|projectID=%s');
$lang->project->menu->story = array('link' => '需求|project|story|projectID=%s', 'subModule' => 'story', 'alias' => 'batchedit');
$lang->project->menu->bug = 'Bug|project|bug|projectID=%s';
$lang->project->menu->dynamic = '动态|project|dynamic|projectID=%s';
$lang->project->menu->build = array('link' => '版本|project|build|projectID=%s', 'subModule' => 'build');
+4
View File
@@ -57,12 +57,14 @@ $lang->resource->product->ajaxGetPlans = 'ajaxGetPlans';
$lang->resource->story->create = 'create';
$lang->resource->story->batchCreate = 'batchCreate';
$lang->resource->story->edit = 'edit';
$lang->resource->story->batchEdit = 'batchEdit';
$lang->resource->story->export = 'export';
$lang->resource->story->delete = 'delete';
$lang->resource->story->view = 'view';
$lang->resource->story->change = 'lblChange';
$lang->resource->story->review = 'lblReview';
$lang->resource->story->close = 'lblClose';
$lang->resource->story->batchClose = 'batchClose';
$lang->resource->story->activate = 'lblActivate';
$lang->resource->story->tasks = 'tasks';
$lang->resource->story->report = 'reportChart';
@@ -374,6 +376,8 @@ $lang->changelog['3.1'][] = 'todo-batchCreate';
$lang->changelog['3.2'][] = 'my-changePassword';
$lang->changelog['3.2'][] = 'todo-batchEdit';
$lang->changelog['3.2'][] = 'story-batchEdit';
$lang->changelog['3.2'][] = 'story-batchClose';
$lang->changelog['3.2'][] = 'task-batchEdit';
$lang->changelog['3.2'][] = 'bug-batchEdit';
$lang->changelog['3.2'][] = 'testcase-batchEdit';
+17
View File
@@ -7,3 +7,20 @@ function browseByModule()
$('#featurebar .active').removeClass('active');
$('#bymoduleTab').addClass('active');
}
/**
* Change form action.
*
* @param formName $formName
* @param actionName $actionName
* @param actionLink $actionLink
* @access public
* @return void
*/
function changeAction(formName, actionName, actionLink)
{
if(actionName == 'batchEdit') $('#' + formName).attr('target', '');
if(actionName == 'batchClose') $('#' + formName).attr('target', 'hiddenwin');
$('#' + formName).attr('action', actionLink).submit();
}
+98 -74
View File
@@ -38,81 +38,105 @@ var browseType = '<?php echo $browseType;?>';
</div>
</div>
<div id='querybox' class='<?php if($browseType !='bysearch') echo 'hidden';?>'><?php echo $searchForm;?></div>
<table class='cont-lt1'>
<tr valign='top'>
<td class='side <?php echo $treeClass;?>' id='treebox'>
<div class='box-title'><?php echo $productName;?></div>
<div class='box-content'>
<?php echo $moduleTree;?>
<div class='a-right'>
<?php if(common::hasPriv('product', 'edit')) echo html::a($this->createLink('product', 'edit', "productID=$productID"), $lang->edit);?>
<?php if(common::hasPriv('product', 'delete')) echo html::a($this->createLink('product', 'delete', "productID=$productID&confirm=no"), $lang->delete, 'hiddenwin');?>
<?php if(common::hasPriv('tree', 'browse')) echo html::a($this->createLink('tree', 'browse', "rootID=$productID&view=story"), $lang->tree->manage);?>
<form method='post' id='productStoryForm'>
<table class='cont-lt1'>
<tr valign='top'>
<td class='side <?php echo $treeClass;?>' id='treebox'>
<div class='box-title'><?php echo $productName;?></div>
<div class='box-content'>
<?php echo $moduleTree;?>
<div class='a-right'>
<?php if(common::hasPriv('product', 'edit')) echo html::a($this->createLink('product', 'edit', "productID=$productID"), $lang->edit);?>
<?php if(common::hasPriv('product', 'delete')) echo html::a($this->createLink('product', 'delete', "productID=$productID&confirm=no"), $lang->delete, 'hiddenwin');?>
<?php if(common::hasPriv('tree', 'browse')) echo html::a($this->createLink('tree', 'browse', "rootID=$productID&view=story"), $lang->tree->manage);?>
</div>
</div>
</div>
</td>
<td class='divider <?php echo $treeClass;?>'></td>
<td>
<table class='table-1 fixed colored tablesorter datatable'>
<thead>
<tr class='colhead'>
<?php $vars = "productID=$productID&browseType=$browseType&param=$moduleID&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";?>
<th class='w-id'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<th class='w-pri'><?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='w-p30'><?php common::printOrderLink('title', $orderBy, $vars, $lang->story->title);?></th>
<th><?php common::printOrderLink('plan', $orderBy, $vars, $lang->story->planAB);?></th>
<th><?php common::printOrderLink('source', $orderBy, $vars, $lang->story->source);?></th>
<th><?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
<th><?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->assignedToAB);?></th>
<th class='w-hour'><?php common::printOrderLink('estimate', $orderBy, $vars, $lang->story->estimateAB);?></th>
<th><?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th><?php common::printOrderLink('stage', $orderBy, $vars, $lang->story->stageAB);?></th>
<th class='w-150px {sorter:false}'><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
<?php $totalEstimate = 0.0;?>
<?php foreach($stories as $key => $story):?>
<?php
$viewLink = $this->createLink('story', 'view', "storyID=$story->id");
$totalEstimate += $story->estimate;
$canView = common::hasPriv('story', 'view');
?>
<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 $lang->story->priList[$story->pri];?></td>
<td class='a-left nobr'><nobr><?php echo html::a($viewLink, $story->title);?></nobr></td>
<td class='nobr'><?php echo $story->planTitle;?></td>
<td><?php echo $lang->story->sourceList[$story->source];?></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 echo $lang->story->statusList[$story->status];?></td>
<td><?php echo $lang->story->stageList[$story->stage];?></td>
<td>
<?php
$vars = "story={$story->id}";
if(!common::printLink('testcase', 'create', "productID=$story->product&module=0&from=&param=0&$vars", $lang->story->createCase)) echo $lang->story->createCase . ' ';
if(!($story->status != 'closed' and common::printLink('story', 'change', $vars, $lang->story->change))) echo $lang->story->change . ' ';
if(!(($story->status == 'draft' or $story->status == 'changed') and common::printLink('story', 'review', $vars, $lang->story->review))) echo $lang->story->review . ' ';
if(!common::printLink('story', 'edit', $vars, $lang->edit)) echo $lang->edit;
?>
</td>
</tr>
<?php endforeach;?>
</tbody>
<tfoot>
<tr>
<td colspan='11' class='a-right'>
<div class='f-left'><?php printf($lang->product->storySummary, count($stories), $totalEstimate);?></div>
<?php $pager->show();?>
</td>
</tr>
</tfoot>
</table>
</td>
</tr>
</table>
</td>
<td class='divider <?php echo $treeClass;?>'></td>
<td>
<table class='table-1 fixed colored tablesorter datatable'>
<thead>
<tr class='colhead'>
<?php $vars = "productID=$productID&browseType=$browseType&param=$moduleID&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";?>
<th class='w-id'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<th class='w-pri'><?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='w-p30'><?php common::printOrderLink('title', $orderBy, $vars, $lang->story->title);?></th>
<th><?php common::printOrderLink('plan', $orderBy, $vars, $lang->story->planAB);?></th>
<th><?php common::printOrderLink('source', $orderBy, $vars, $lang->story->source);?></th>
<th><?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
<th><?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->assignedToAB);?></th>
<th class='w-hour'><?php common::printOrderLink('estimate', $orderBy, $vars, $lang->story->estimateAB);?></th>
<th><?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th><?php common::printOrderLink('stage', $orderBy, $vars, $lang->story->stageAB);?></th>
<th class='w-150px {sorter:false}'><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
<?php $totalEstimate = 0.0;?>
<?php foreach($stories as $key => $story):?>
<?php
$viewLink = $this->createLink('story', 'view', "storyID=$story->id");
$totalEstimate += $story->estimate;
$canView = common::hasPriv('story', 'view');
?>
<tr class='a-center'>
<td>
<input type='checkbox' name='storyIDList[<?php echo $story->id;?>]' value='<?php echo $story->id;?>' />
<?php if($canView) echo html::a($viewLink, sprintf('%03d', $story->id)); else printf('%03d', $story->id);?>
</td>
<td><?php echo $lang->story->priList[$story->pri];?></td>
<td class='a-left nobr'><nobr><?php echo html::a($viewLink, $story->title);?></nobr></td>
<td class='nobr'><?php echo $story->planTitle;?></td>
<td><?php echo $lang->story->sourceList[$story->source];?></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 echo $lang->story->statusList[$story->status];?></td>
<td><?php echo $lang->story->stageList[$story->stage];?></td>
<td>
<?php
$vars = "story={$story->id}";
if(!common::printLink('testcase', 'create', "productID=$story->product&module=0&from=&param=0&$vars", $lang->story->createCase)) echo $lang->story->createCase . ' ';
if(!($story->status != 'closed' and common::printLink('story', 'change', $vars, $lang->story->change))) echo $lang->story->change . ' ';
if(!(($story->status == 'draft' or $story->status == 'changed') and common::printLink('story', 'review', $vars, $lang->story->review))) echo $lang->story->review . ' ';
if(!common::printLink('story', 'edit', $vars, $lang->edit)) echo $lang->edit;
?>
</td>
</tr>
<?php endforeach;?>
</tbody>
<tfoot>
<tr>
<td colspan='11' class='a-right'>
<div class='f-left'>
<?php
if(count($stories))
{
echo html::selectAll() . html::selectReverse();
if(common::hasPriv('story', 'batchEdit'))
{
$actionLink = $this->createLink('story', 'batchEdit', "from=productBrowse&productID=$productID&projectID=0&orderBy=$orderBy");
echo html::commonButton($lang->story->batchEdit, "onclick=\"changeAction('productStoryForm', 'batchEdit', '$actionLink')\"");
}
if(common::hasPriv('story', 'batchClose') and strtolower($browseType) != 'closedbyme' and strtolower($browseType) != 'closedstory')
{
$actionLink = $this->createLink('story', 'batchClose');
echo html::commonButton($lang->story->batchClose, "onclick=\"changeAction('productStoryForm', 'batchClose', '$actionLink')\"");
}
}
printf($lang->product->storySummary, count($stories), $totalEstimate);
?>
</div>
<?php $pager->show();?>
</td>
</tr>
</tfoot>
</table>
</td>
</tr>
</table>
</form>
<script language='javascript'>
$('#module<?php echo $moduleID;?>').addClass('active')
$('#<?php echo $browseType;?>Tab').addClass('active')
+16
View File
@@ -2,3 +2,19 @@ $(document).ready(function()
{
$("a.iframe").colorbox({width:640, height:480, iframe:true, transition:'none'});
});
/**
* Change form action.
*
* @param formName $formName
* @param actionName $actionName
* @param actionLink $actionLink
* @access public
* @return void
*/
function changeAction(formName, actionName, actionLink)
{
if(actionName == 'batchEdit') $('#' + formName).attr('target', '');
if(actionName == 'batchClose') $('#' + formName).attr('target', 'hiddenwin');
$('#' + formName).attr('action', actionLink).submit();
}
+87 -57
View File
@@ -12,63 +12,93 @@
?>
<?php include '../../common/view/header.html.php';?>
<?php include '../../common/view/tablesorter.html.php';?>
<table class='table-1 fixed colored tablesorter datatable'>
<caption class='caption-tl'>
<div class='f-left'><?php echo $lang->project->story;?></div>
<div class='f-right'>
<?php
if($productID) common::printLink('story', 'create', "productID=$productID&moduleID=0&story=0&project=$project->id", $lang->story->create);
if(common::hasPriv('project', 'linkstory')) echo html::a($this->createLink('project', 'linkstory', "project=$project->id"), $lang->project->linkStory);
?>
</div>
</caption>
<thead>
<tr class='colhead'>
<?php $vars = "projectID={$project->id}&orderBy=%s"; ?>
<th class='w-id {sorter:false}'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<th class='w-pri {sorter:false}'> <?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='{sorter:false}'> <?php common::printOrderLink('title', $orderBy, $vars, $lang->story->title);?></th>
<th class='w-user {sorter:false}'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
<th class='w-hour {sorter:false}'> <?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->assignedToAB);?></th>
<th class='w-hour {sorter:false}'> <?php common::printOrderLink('estimate', $orderBy, $vars, $lang->story->estimateAB);?></th>
<th class='w-hour {sorter:false}'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='w-status {sorter:false}'> <?php common::printOrderLink('stage', $orderBy, $vars, $lang->story->stageAB);?></th>
<th class='w-50px'> <?php echo $lang->story->taskCount;?></th>
<th class='w-100px {sorter:false}'> <?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
<?php $totalEstimate = 0;?>
<?php foreach($stories as $key => $story):?>
<?php
$storyLink = $this->createLink('story', 'view', "storyID=$story->id");
$totalEstimate += $story->estimate;
?>
<tr class='a-center'>
<td><?php echo html::a($storyLink, sprintf('%03d', $story->id));?></td>
<td><?php echo $lang->story->priList[$story->pri];?></td>
<td class='a-left nobr'><?php echo html::a($storyLink,$story->title);?></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 echo $lang->story->statusList[$story->status];?></td>
<td><?php echo $lang->story->stageList[$story->stage];?></td>
<td class='linkbox'>
<?php
$tasksLink = $this->createLink('story', 'tasks', "storyID=$story->id&projectID=$project->id");
$storyTasks[$story->id] > 0 ? print(html::a($tasksLink, $storyTasks[$story->id], '', 'class="iframe"')) : print(0);
?>
</td>
<td>
<form method='post' id='projectStoryForm'>
<table class='table-1 fixed colored tablesorter datatable'>
<caption class='caption-tl'>
<div class='f-left'><?php echo $lang->project->story;?></div>
<div class='f-right'>
<?php
$param = "projectID={$project->id}&story={$story->id}";
common::printLink('task', 'create', $param, $lang->project->wbs);
common::printLink('project', 'unlinkStory', $param, $lang->unlink, 'hiddenwin');
if($productID) common::printLink('story', 'create', "productID=$productID&moduleID=0&story=0&project=$project->id", $lang->story->create);
if(common::hasPriv('project', 'linkstory')) echo html::a($this->createLink('project', 'linkstory', "project=$project->id"), $lang->project->linkStory);
?>
</td>
</tr>
<?php endforeach;?>
</tbody>
<tfoot><tr><td colspan='10'><?php printf($lang->product->storySummary, count($stories), $totalEstimate);?></td></tr></tfoot>
</table>
</div>
</caption>
<thead>
<tr class='colhead'>
<?php $vars = "projectID={$project->id}&orderBy=%s"; ?>
<th class='w-id {sorter:false}'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<th class='w-pri {sorter:false}'> <?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='{sorter:false}'> <?php common::printOrderLink('title', $orderBy, $vars, $lang->story->title);?></th>
<th class='w-user {sorter:false}'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
<th class='w-hour {sorter:false}'> <?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->assignedToAB);?></th>
<th class='w-hour {sorter:false}'> <?php common::printOrderLink('estimate', $orderBy, $vars, $lang->story->estimateAB);?></th>
<th class='w-hour {sorter:false}'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='w-status {sorter:false}'> <?php common::printOrderLink('stage', $orderBy, $vars, $lang->story->stageAB);?></th>
<th class='w-50px'> <?php echo $lang->story->taskCount;?></th>
<th class='w-100px {sorter:false}'> <?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
<?php $totalEstimate = 0;?>
<?php foreach($stories as $key => $story):?>
<?php
$storyLink = $this->createLink('story', 'view', "storyID=$story->id");
$totalEstimate += $story->estimate;
?>
<tr class='a-center'>
<td>
<input type='checkbox' name='storyIDList[<?php echo $story->id;?>]' value='<?php echo $story->id;?>' />
<?php echo html::a($storyLink, sprintf('%03d', $story->id));?>
</td>
<td><?php echo $lang->story->priList[$story->pri];?></td>
<td class='a-left nobr'><?php echo html::a($storyLink,$story->title);?></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 echo $lang->story->statusList[$story->status];?></td>
<td><?php echo $lang->story->stageList[$story->stage];?></td>
<td class='linkbox'>
<?php
$tasksLink = $this->createLink('story', 'tasks', "storyID=$story->id&projectID=$project->id");
$storyTasks[$story->id] > 0 ? print(html::a($tasksLink, $storyTasks[$story->id], '', 'class="iframe"')) : print(0);
?>
</td>
<td>
<?php
$param = "projectID={$project->id}&story={$story->id}";
common::printLink('task', 'create', $param, $lang->project->wbs);
common::printLink('project', 'unlinkStory', $param, $lang->unlink, 'hiddenwin');
?>
</td>
</tr>
<?php endforeach;?>
</tbody>
<tfoot>
<tr>
<td colspan='10'>
<div class='f-left'>
<?php
if(count($stories))
{
echo html::selectAll() . html::selectReverse();
if(common::hasPriv('story', 'batchEdit'))
{
$actionLink = $this->createLink('story', 'batchEdit', "from=projectStory&productID=0&projectID=$project->id&orderBy=$orderBy");
echo html::commonButton($lang->story->batchEdit, "onclick=\"changeAction('projectStoryForm', 'batchEdit', '$actionLink')\"");
}
if(common::hasPriv('story', 'batchClose'))
{
$actionLink = $this->createLink('story', 'batchClose', "from=projectStory&productID=0");
echo html::commonButton($lang->story->batchClose, "onclick=\"changeAction('projectStoryForm', 'batchClose', '$actionLink')\"");
}
}
printf($lang->product->storySummary, count($stories), $totalEstimate);
?>
</div>
</td>
</tr>
</tfoot>
</table>
</form>
<?php include '../../common/view/footer.html.php';?>
+91
View File
@@ -21,6 +21,7 @@ class story extends control
{
parent::__construct();
$this->loadModel('product');
$this->loadModel('project');
$this->loadModel('tree');
$this->loadModel('user');
}
@@ -267,6 +268,96 @@ class story extends control
$this->display();
}
/**
* Batch edit story.
*
* @param string $from productBrowse|projectStory|storyBatchEdit.
* @param int $productID
* @param int $projectID
* @param string $orderBy
* @access public
* @return void
*/
public function batchEdit($from = '', $productID = 0, $projectID = 0, $orderBy = '')
{
/* Get post data for product-Browse or project-Story. */
if($from == 'productBrowse' or $from == 'projectStory')
{
/* Init vars. */
$editedStories = array();
$storyIDList = $this->post->storyIDList ? $this->post->storyIDList : array();
$columns = 9;
$showSuhosinInfo = false;
/* Get all stories. */
if(!$projectID)
{
/* Set menu. */
$this->product->setMenu($this->product->getPairs('nodeleted'), $productID);
$allStories = $this->dao->select('*')->from(TABLE_STORY)->where($this->session->storyReport)->orderBy($orderBy)->fetchAll('id');
}
else
{
$this->lang->story->menu = $this->lang->project->menu;
$this->project->setMenu($this->project->getPairs('nodeleted'), $projectID);
$this->lang->set('menugroup.story', 'project');
$allStories = $this->story->getProjectStories($projectID, $orderBy);
}
if(!$allStories) $allStories = array();
/* Initialize the stories whose need to edited. */
foreach($allStories as $story) if(in_array($story->id, $storyIDList)) $editedStories[$story->id] = $story;
/* Judge whether the editedStories is too large. */
$showSuhosinInfo = $this->loadModel('common')->judgeSuhosinSetting(count($editedStories), $columns);
/* Set the sessions. */
$this->app->session->set('showSuhosinInfo', $showSuhosinInfo);
/* Assign. */
if(!$projectID)
{
$product = $this->product->getByID($productID);
$this->view->header['title'] = $product->name . $this->lang->colon . $this->lang->story->batchEdit;
}
else
{
$project = $this->project->getByID($projectID);
$this->view->header['title'] = $project->name . $this->lang->colon . $this->lang->story->batchEdit;
}
if($showSuhosinInfo) $this->view->suhosinInfo = $this->lang->suhosinInfo;
$this->view->position[] = $this->lang->story->common;
$this->view->position[] = $this->lang->story->batchEdit;
$this->view->users = $this->loadModel('user')->getPairs('nodeleted');
$this->view->moduleOptionMenu = $this->tree->getOptionMenu($productID, $viewType = 'story');
$this->view->plans = $this->loadModel('productplan')->getPairs($productID);
$this->view->productID = $productID;
$this->view->editedStories = $editedStories;
$this->display();
}
/* Get post data for story-batchEdit. */
elseif($from == 'storyBatchEdit')
{
if(!empty($_POST))
{
$allChanges = $this->story->batchUpdate();
if($allChanges)
{
foreach($allChanges as $storyID => $changes)
{
$actionID = $this->loadModel('action')->create('story', $storyID, 'Edited');
$this->action->logHistory($actionID, $changes);
$this->sendMail($storyID, $actionID);
}
}
}
die(js::locate($this->session->storyList, 'parent'));
}
}
/**
* Change a story.
*
+26
View File
@@ -0,0 +1,26 @@
/**
* Set duplicate field.
*
* @param string $resolution
* @param int $storyID
* @access public
* @return void
*/
function setDuplicateAndChild(resolution, storyID)
{
if(resolution == 'duplicate')
{
$('#childStoryBox' + storyID).hide();
$('#duplicateStoryBox' + storyID).show();
}
else if(resolution == 'subdivided')
{
$('#duplicateStoryBox' + storyID).hide();
$('#childStoryBox' + storyID).show();
}
else
{
$('#duplicateStoryBox' + storyID).hide();
$('#childStoryBox' + storyID).hide();
}
}
+3
View File
@@ -17,7 +17,9 @@ $lang->story->change = "Change";
$lang->story->changed = 'Changed';
$lang->story->review = 'Review';
$lang->story->edit = "Edit";
$lang->story->batchEdit = "Batch edit";
$lang->story->close = 'Close';
$lang->story->batchClose = 'Batch close';
$lang->story->activate = 'Activate';
$lang->story->delete = "Delete";
$lang->story->view = "Info";
@@ -165,6 +167,7 @@ $lang->story->needNotReview = "needn't review";
$lang->story->afterSubmit = "After created";
$lang->story->successSaved = "Successfully saved";
$lang->story->confirmDelete = "Are you sure to delete this story?";
$lang->story->confirmBatchClose = "Are you sure to close those stories?";
$lang->story->errorFormat = 'Error format';
$lang->story->errorEmptyTitle = "Title can't be empty";
$lang->story->mustChooseResult = 'Must choose s result';
+3
View File
@@ -17,7 +17,9 @@ $lang->story->change = "变更";
$lang->story->changed = '需求变更';
$lang->story->review = '评审';
$lang->story->edit = "编辑需求";
$lang->story->batchEdit = "批量编辑";
$lang->story->close = '关闭';
$lang->story->batchClose = '批量关闭';
$lang->story->activate = '激活';
$lang->story->delete = "删除需求";
$lang->story->view = "需求详情";
@@ -165,6 +167,7 @@ $lang->story->needNotReview = '不需要评审';
$lang->story->afterSubmit = "添加之后";
$lang->story->successSaved = "需求成功添加,";
$lang->story->confirmDelete = "您确认删除该需求吗?";
$lang->story->confirmBatchClose = "您确认关闭这些需求吗?";
$lang->story->errorFormat = '需求数据有误';
$lang->story->errorEmptyTitle = '标题不能为空';
$lang->story->mustChooseResult = '必须选择评审结果';
+78
View File
@@ -345,6 +345,84 @@ class storyModel extends model
if(!dao::isError()) return common::createChanges($oldStory, $story);
}
/**
* Batch update story.
*
* @access public
* @return void
*/
public function batchUpdate()
{
/* Init vars. */
$stories = array();
$allChanges = array();
$now = helper::now();
$storyIDList = $this->post->storyIDList ? $this->post->storyIDList : array();
/* Adjust whether the post data is complete, if not, remove the last element of $taskIDList. */
if($this->session->showSuhosinInfo) array_pop($storyIDList);
/* Init $stories. */
if(!empty($storyIDList))
{
foreach($storyIDList as $storyID)
{
$oldStory = $this->getById($storyID);
$story->lastEditedBy = $this->app->user->account;
$story->lastEditedDate = $now;
$story->status = $oldStory->status;
$story->title = htmlspecialchars($this->post->titles[$storyID]);
$story->estimate = $this->post->estimates[$storyID];
$story->pri = $this->post->pris[$storyID];
$story->module = $this->post->modules[$storyID];
$story->plan = $this->post->plans[$storyID];
$story->source = $this->post->sources[$storyID];
$story->stage = isset($this->post->stages[$storyID]) ? $this->post->stages[$storyID] : $oldStory->stage;
$story->closedBy = isset($this->post->closedBys[$storyID]) ? $this->post->closedBys[$storyID] : $oldStory->closedBy;
$story->closedReason = isset($this->post->closedReasons[$storyID]) ? $this->post->closedReasons[$storyID] : $oldStory->closedReason;
$story->duplicateStory = isset($this->post->duplicateStories[$storyID]) ? $this->post->duplicateStories[$storyID] : $oldStory->duplicateStory;
$story->childStories = isset($this->post->childStoriesIDList[$storyID]) ? $this->post->childStoriesIDList[$storyID] : $oldStory->childStories;
if($story->title != $oldStory->title) $story->status = 'changed';
if($story->plan !== false and $story->plan == '') $story->plan = 0;
if($story->closedBy != false and $oldStory->closedDate == '') $story->closedDate = $now;
if($story->closedReason != false and $oldStory->closedDate == '') $story->closedDate = $now;
if($story->closedBy != false or $story->closedReason != false) $story->status = 'closed';
if($story->closedReason != false and $story->closedBy == false) $story->closedBy = $this->app->user->account;
$stories[$storyID] = $story;
unset($story);
}
foreach($stories as $storyID => $story)
{
$oldStory = $this->getById($storyID);
$this->dao->update(TABLE_STORY)->data($story)
->autoCheck()
->batchCheck($this->config->story->edit->requiredFields, 'notempty')
->checkIF($story->closedBy, 'closedReason', 'notempty')
->checkIF($story->closedReason == 'done', 'stage', 'notempty')
->checkIF($story->closedReason == 'duplicate', 'duplicateStory', 'notempty')
->checkIF($story->closedReason == 'subdivided', 'childStories', 'notempty')
->where('id')->eq((int)$storyID)
->exec();
if(!dao::isError())
{
$allChanges[$storyID] = common::createChanges($oldStory, $story);
}
else
{
die(js::error('story#' . $storyID . dao::getError(true)));
}
}
}
return $allChanges;
}
/**
* Review a story.
*
+76
View File
@@ -0,0 +1,76 @@
<?php
/**
* The batch edit view of story module of ZenTaoPMS.
*
* @copyright Copyright 2009-2012 青岛易软天创网络科技有限公司 (QingDao Nature Easy Soft Network Technology Co,LTD www.cnezsoft.com)
* @license LGPL (http://www.gnu.org/licenses/lgpl.html)
* @author Congzhi Chen <congzhi@cnezsoft.com>
* @package story
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<form method='post' target='hiddenwin' action="<?php echo $this->inLink('batchEdit', "from=storyBatchEdit&productID=$productID")?>">
<table class='table-1 fixed'>
<caption><?php echo $lang->story->common . $lang->colon . $lang->story->batchEdit;?></caption>
<tr>
<th class='w-30px'> <?php echo $lang->idAB;?></th>
<th> <?php echo $lang->story->title;?></th>
<th class='w-30px'> <?php echo $lang->story->estimateAB;?></th>
<th class='w-50px'> <?php echo $lang->priAB;?></th>
<th class='w-100px'><?php echo $lang->story->module;?></th>
<th class='w-100px'><?php echo $lang->story->planAB;?></th>
<th class='w-80px'> <?php echo $lang->story->source;?></th>
<th class='w-60px'> <?php echo $lang->story->status;?></th>
<th class='w-80px'> <?php echo $lang->story->stageAB;?></th>
<th class='w-100px'><?php echo $lang->story->closedBy;?></th>
<th class='w-120px'><?php echo $lang->story->closedReason;?></th>
</tr>
<?php foreach($editedStories as $story):?>
<tr class='a-center'>
<td><?php echo $story->id . html::hidden("storyIDList[$story->id]", $story->id);?></td>
<td><?php echo html::input("titles[$story->id]", $story->title, 'class=text-1'); echo "<span class='star'>*</span>";?></td>
<td><?php echo html::input("estimates[$story->id]", $story->estimate, 'class=text-1'); echo "<span class='star'>*</span>";?></td>
<td><?php echo html::select("pris[$story->id]", (array)$lang->story->priList, $story->pri, 'class=select-1');?></td>
<td><?php echo html::select("modules[$story->id]", $moduleOptionMenu, $story->module, 'class=select-1');?></td>
<td><?php echo html::select("plans[$story->id]", $plans, $story->plan, 'class=select-1');?></td>
<td><?php echo html::select("sources[$story->id]", $lang->story->sourceList, $story->source, 'class=select-1');?></td>
<td><?php echo $lang->story->statusList[$story->status];?></td>
<?php if($story->status != 'draft'):?>
<td><?php echo html::select("stages[$story->id]", $lang->story->stageList, $story->stage, 'class=select-1');?></td>
<?php else:?>
<td><?php echo html::select("stages[$story->id]", $lang->story->stageList, $story->stage, 'class="select-1" disabled="disabled"');?></td>
<?php endif;?>
<?php if($story->status == 'closed'):?>
<td><?php echo html::select("closedBys[$story->id]", $users, $story->closedBy, 'class="select-1"');?></td>
<?php else:?>
<td><?php echo html::select("closedBys[$story->id]", $users, $story->closedBy, 'class="select-1" disabled="disabled"');?></td>
<?php endif;?>
<?php if($story->status == 'closed'):?>
<td>
<div class='f-left'><?php echo html::select("closedReasons[$story->id]", $lang->story->reasonList, $story->closedReason, "class=w-60px onchange=setDuplicateAndChild(this.value,$story->id)");?></div>
<div class='f-left' id='<?php echo 'duplicateStoryBox' . $story->id;?>' <?php if($story->closedReason != 'duplicate') echo "style='display:none'";?>>
<?php echo html::input("duplicateStoryIDList[$story->id]", '', "class=w-30px placeholder='{$lang->idAB}'");?>
</div>
<div class='f-left' id='<?php echo 'childStoryBox' . $story->id;?>' <?php if($story->closedReason != 'subdivided') echo "style='display:none'";?>>
<?php echo html::input("childStoriesIDList[$story->id]", '', "class=w-30px placeholder='{$lang->idAB}'");?>
</div>
</td>
<?php else:?>
<td class='f-left'><?php echo html::select("closedReasons[$story->id]", $lang->story->reasonList, $story->closedReason, 'class="w-60px" disabled="disabled"');?></td>
<?php endif;?>
</tr>
<?php endforeach;?>
<?php if(isset($suhosinInfo)):?>
<tr><td colspan='11'><div class='f-left blue'><?php echo $suhosinInfo;?></div></td></tr>
<?php endif;?>
<tr><td colspan='11' class='a-center'><?php echo html::submitButton();?></td></tr>
</table>
</form>
<?php include '../../common/view/footer.html.php';?>