Merge branch '15.0.beta3' of http://gitlab.zcorp.cc/easycorp/zentaopms into 15.0.beta3

This commit is contained in:
zhujinyong
2021-04-01 13:29:38 +08:00
24 changed files with 246 additions and 107 deletions
+3 -4
View File
@@ -344,15 +344,14 @@ REPLACE INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `system`) V
REPLACE INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'common', '', 'CRProduct', '1');
REPLACE INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'common', '', 'CRExecution', '1');
update zt_block set source='execution' where block='statistic' and source='project';
update zt_block set source='project' where block='statistic' and source='program';
update zt_config set `value`='project-browse' where `key`='projectLink';
update zt_config set `value`='program-browse' where `key`='programLink';
update zt_block set source='project', block='projectteam' where block='programteam' and source='program';
update zt_block set source='project', block='project' where block='program' and source='program';
update zt_team set type='execution' where type='project';
update zt_action set objectType='execution' where objectType='project';
update zt_file set objectType='execution' where objectType='project';
ALTER TABLE `zt_todo` ADD `deleted` ENUM( "0", "1" ) NOT NULL DEFAULT '0';
TRUNCATE `zt_block`;
DELETE FROM `zt_config` WHERE `key` = 'blockInited';
+6 -4
View File
@@ -1258,12 +1258,14 @@ class block extends control
$projectID = $this->session->project;
$members = $this->loadModel('project')->getTeamMemberPairs($projectID);
$budget = $this->loadModel('workestimation')->getBudget($projectID);
$workhour = $this->project->getWorkhour($projectID);
if(empty($budget)) $budget = new stdclass();
$this->view->people = $this->dao->select('sum(people) as people')->from(TABLE_DURATIONESTIMATION)->where('project')->eq($this->session->project)->fetch('people');
$this->view->members = count($members) ? count($members) - 1 : 0;
$this->view->consumed = $this->dao->select('sum(cast(consumed as decimal(10,2))) as consumed')->from(TABLE_TASK)->where('project')->eq($projectID)->andWhere('deleted')->eq(0)->andWhere('parent')->lt(1)->fetch('consumed');
$this->view->budget = $budget;
$this->view->people = $this->dao->select('sum(people) as people')->from(TABLE_DURATIONESTIMATION)->where('project')->eq($this->session->project)->fetch('people');
$this->view->members = count($members) ? count($members) - 1 : 0;
$this->view->consumed = $this->dao->select('sum(cast(consumed as decimal(10,2))) as consumed')->from(TABLE_TASK)->where('project')->eq($projectID)->andWhere('deleted')->eq(0)->andWhere('parent')->lt(1)->fetch('consumed');
$this->view->budget = $budget;
$this->view->totalLeft = (float)$workhour->totalLeft;
}
/**
+17 -9
View File
@@ -9,6 +9,7 @@
* @version $Id$
* @link http://www.zentao.net
*/
global $config;
$lang->block = new stdclass();
$lang->block->common = 'InfoBlock';
$lang->block->name = 'Name';
@@ -68,6 +69,7 @@ $lang->block->time = 'No';
$lang->block->week = 'Week';
$lang->block->selectProduct = 'Product selection';
$lang->block->of = ' von ';
$lang->block->leftHour = 'Left';
$lang->block->params = new stdclass();
$lang->block->params->name = 'Name';
@@ -279,11 +281,14 @@ $lang->block->default['full']['my']['3']['grid'] = 4;
$lang->block->default['full']['my']['3']['source'] = 'todo';
$lang->block->default['full']['my']['3']['params']['count'] = '20';
$lang->block->default['full']['my']['4']['title'] = 'Project Statistic';
$lang->block->default['full']['my']['4']['block'] = 'statistic';
$lang->block->default['full']['my']['4']['source'] = 'project';
$lang->block->default['full']['my']['4']['grid'] = 8;
$lang->block->default['full']['my']['4']['params']['count'] = '20';
if($config->systemMode == 'new')
{
$lang->block->default['full']['my']['4']['title'] = 'Project Statistic';
$lang->block->default['full']['my']['4']['block'] = 'statistic';
$lang->block->default['full']['my']['4']['source'] = 'project';
$lang->block->default['full']['my']['4']['grid'] = 8;
$lang->block->default['full']['my']['4']['params']['count'] = '20';
}
$lang->block->default['full']['my']['5']['title'] = 'Personal Contribution';
$lang->block->default['full']['my']['5']['block'] = 'contribute';
@@ -307,10 +312,13 @@ $lang->block->default['full']['my']['7']['params']['riskNum'] = '20';
$lang->block->default['full']['my']['7']['params']['issueNum'] = '20';
$lang->block->default['full']['my']['7']['params']['storyNum'] = '20';
$lang->block->default['full']['my']['8']['title'] = 'Human Input';
$lang->block->default['full']['my']['8']['block'] = 'projectteam';
$lang->block->default['full']['my']['8']['source'] = 'project';
$lang->block->default['full']['my']['8']['grid'] = 8;
if($config->systemMode == 'new')
{
$lang->block->default['full']['my']['8']['title'] = 'Human Input';
$lang->block->default['full']['my']['8']['block'] = 'projectteam';
$lang->block->default['full']['my']['8']['source'] = 'project';
$lang->block->default['full']['my']['8']['grid'] = 8;
}
$lang->block->default['full']['my']['9']['title'] = 'Project List';
$lang->block->default['full']['my']['9']['block'] = 'project';
+17 -9
View File
@@ -9,6 +9,7 @@
* @version $Id$
* @link http://www.zentao.net
*/
global $config;
$lang->block = new stdclass();
$lang->block->common = 'Block';
$lang->block->name = 'Name';
@@ -68,6 +69,7 @@ $lang->block->time = 'No';
$lang->block->week = 'Week';
$lang->block->selectProduct = 'Product selection';
$lang->block->of = ' of ';
$lang->block->leftHour = 'Left';
$lang->block->params = new stdclass();
$lang->block->params->name = 'Name';
@@ -279,11 +281,14 @@ $lang->block->default['full']['my']['3']['grid'] = 4;
$lang->block->default['full']['my']['3']['source'] = 'todo';
$lang->block->default['full']['my']['3']['params']['count'] = '20';
$lang->block->default['full']['my']['4']['title'] = 'Project Statistic';
$lang->block->default['full']['my']['4']['block'] = 'statistic';
$lang->block->default['full']['my']['4']['source'] = 'project';
$lang->block->default['full']['my']['4']['grid'] = 8;
$lang->block->default['full']['my']['4']['params']['count'] = '20';
if($config->systemMode == 'new')
{
$lang->block->default['full']['my']['4']['title'] = 'Project Statistic';
$lang->block->default['full']['my']['4']['block'] = 'statistic';
$lang->block->default['full']['my']['4']['source'] = 'project';
$lang->block->default['full']['my']['4']['grid'] = 8;
$lang->block->default['full']['my']['4']['params']['count'] = '20';
}
$lang->block->default['full']['my']['5']['title'] = 'Personal Contribution';
$lang->block->default['full']['my']['5']['block'] = 'contribute';
@@ -307,10 +312,13 @@ $lang->block->default['full']['my']['7']['params']['riskNum'] = '20';
$lang->block->default['full']['my']['7']['params']['issueNum'] = '20';
$lang->block->default['full']['my']['7']['params']['storyNum'] = '20';
$lang->block->default['full']['my']['8']['title'] = 'Human Input';
$lang->block->default['full']['my']['8']['block'] = 'projectteam';
$lang->block->default['full']['my']['8']['source'] = 'project';
$lang->block->default['full']['my']['8']['grid'] = 8;
if($config->systemMode == 'new')
{
$lang->block->default['full']['my']['8']['title'] = 'Human Input';
$lang->block->default['full']['my']['8']['block'] = 'projectteam';
$lang->block->default['full']['my']['8']['source'] = 'project';
$lang->block->default['full']['my']['8']['grid'] = 8;
}
$lang->block->default['full']['my']['9']['title'] = 'Project List';
$lang->block->default['full']['my']['9']['block'] = 'project';
+17 -9
View File
@@ -9,6 +9,7 @@
* @version $Id$
* @link http://www.zentao.net
*/
global $config;
$lang->block = new stdclass();
$lang->block->common = 'Bloc';
$lang->block->name = 'Nom';
@@ -68,6 +69,7 @@ $lang->block->time = 'No';
$lang->block->week = 'Week';
$lang->block->selectProduct = 'Product selection';
$lang->block->of = ' di ';
$lang->block->leftHour = 'Left';
$lang->block->params = new stdclass();
$lang->block->params->name = 'Nom';
@@ -279,11 +281,14 @@ $lang->block->default['full']['my']['3']['grid'] = 4;
$lang->block->default['full']['my']['3']['source'] = 'todo';
$lang->block->default['full']['my']['3']['params']['count'] = '20';
$lang->block->default['full']['my']['4']['title'] = 'Project Statistic';
$lang->block->default['full']['my']['4']['block'] = 'statistic';
$lang->block->default['full']['my']['4']['source'] = 'project';
$lang->block->default['full']['my']['4']['grid'] = 8;
$lang->block->default['full']['my']['4']['params']['count'] = '20';
if($config->systemMode == 'new')
{
$lang->block->default['full']['my']['4']['title'] = 'Project Statistic';
$lang->block->default['full']['my']['4']['block'] = 'statistic';
$lang->block->default['full']['my']['4']['source'] = 'project';
$lang->block->default['full']['my']['4']['grid'] = 8;
$lang->block->default['full']['my']['4']['params']['count'] = '20';
}
$lang->block->default['full']['my']['5']['title'] = 'Personal Contribution';
$lang->block->default['full']['my']['5']['block'] = 'contribute';
@@ -307,10 +312,13 @@ $lang->block->default['full']['my']['7']['params']['riskNum'] = '20';
$lang->block->default['full']['my']['7']['params']['issueNum'] = '20';
$lang->block->default['full']['my']['7']['params']['storyNum'] = '20';
$lang->block->default['full']['my']['8']['title'] = 'Human Input';
$lang->block->default['full']['my']['8']['block'] = 'projectteam';
$lang->block->default['full']['my']['8']['source'] = 'project';
$lang->block->default['full']['my']['8']['grid'] = 8;
if($config->systemMode == 'new')
{
$lang->block->default['full']['my']['8']['title'] = 'Human Input';
$lang->block->default['full']['my']['8']['block'] = 'projectteam';
$lang->block->default['full']['my']['8']['source'] = 'project';
$lang->block->default['full']['my']['8']['grid'] = 8;
}
$lang->block->default['full']['my']['9']['title'] = 'Project List';
$lang->block->default['full']['my']['9']['block'] = 'project';
+17 -9
View File
@@ -9,6 +9,7 @@
* @version $Id$
* @link http://www.zentao.net
*/
global $config;
$lang->block = new stdclass();
$lang->block->common = 'Block';
$lang->block->name = 'Tên';
@@ -68,6 +69,7 @@ $lang->block->time = 'No';
$lang->block->week = 'Week';
$lang->block->selectProduct = 'Product selection';
$lang->block->of = ' thực ';
$lang->block->leftHour = 'Left';
$lang->block->params = new stdclass();
$lang->block->params->name = 'Tên';
@@ -279,11 +281,14 @@ $lang->block->default['full']['my']['3']['grid'] = 4;
$lang->block->default['full']['my']['3']['source'] = 'todo';
$lang->block->default['full']['my']['3']['params']['count'] = '20';
$lang->block->default['full']['my']['4']['title'] = 'Project Statistic';
$lang->block->default['full']['my']['4']['block'] = 'statistic';
$lang->block->default['full']['my']['4']['source'] = 'project';
$lang->block->default['full']['my']['4']['grid'] = 8;
$lang->block->default['full']['my']['4']['params']['count'] = '20';
if($config->systemMode == 'new')
{
$lang->block->default['full']['my']['4']['title'] = 'Project Statistic';
$lang->block->default['full']['my']['4']['block'] = 'statistic';
$lang->block->default['full']['my']['4']['source'] = 'project';
$lang->block->default['full']['my']['4']['grid'] = 8;
$lang->block->default['full']['my']['4']['params']['count'] = '20';
}
$lang->block->default['full']['my']['5']['title'] = 'Personal Contribution';
$lang->block->default['full']['my']['5']['block'] = 'contribute';
@@ -307,10 +312,13 @@ $lang->block->default['full']['my']['7']['params']['riskNum'] = '20';
$lang->block->default['full']['my']['7']['params']['issueNum'] = '20';
$lang->block->default['full']['my']['7']['params']['storyNum'] = '20';
$lang->block->default['full']['my']['8']['title'] = 'Human Input';
$lang->block->default['full']['my']['8']['block'] = 'projectteam';
$lang->block->default['full']['my']['8']['source'] = 'project';
$lang->block->default['full']['my']['8']['grid'] = 8;
if($config->systemMode == 'new')
{
$lang->block->default['full']['my']['8']['title'] = 'Human Input';
$lang->block->default['full']['my']['8']['block'] = 'projectteam';
$lang->block->default['full']['my']['8']['source'] = 'project';
$lang->block->default['full']['my']['8']['grid'] = 8;
}
$lang->block->default['full']['my']['9']['title'] = 'Project List';
$lang->block->default['full']['my']['9']['block'] = 'project';
+4
View File
@@ -69,6 +69,7 @@ $lang->block->time = '第';
$lang->block->week = '周';
$lang->block->selectProduct = '选择产品';
$lang->block->of = '的';
$lang->block->leftHour = '剩余工时';
$lang->block->params = new stdclass();
$lang->block->params->name = '参数名称';
@@ -280,11 +281,14 @@ $lang->block->default['full']['my']['3']['grid'] = 4;
$lang->block->default['full']['my']['3']['source'] = 'todo';
$lang->block->default['full']['my']['3']['params']['count'] = '20';
if($config->systemMode == 'new')
{
$lang->block->default['full']['my']['4']['title'] = '项目统计';
$lang->block->default['full']['my']['4']['block'] = 'statistic';
$lang->block->default['full']['my']['4']['source'] = 'project';
$lang->block->default['full']['my']['4']['grid'] = 8;
$lang->block->default['full']['my']['4']['params']['count'] = '20';
}
$lang->block->default['full']['my']['5']['title'] = '我的贡献';
$lang->block->default['full']['my']['5']['block'] = 'contribute';
+1
View File
@@ -68,6 +68,7 @@ $lang->block->time = '第';
$lang->block->week = '周';
$lang->block->selectProduct = '選擇產品';
$lang->block->of = '的';
$lang->block->leftHour = '剩餘工時';
$lang->block->params = new stdclass();
$lang->block->params->name = '參數名稱';
+5 -8
View File
@@ -8,7 +8,6 @@ $maxConsumed = 0;
<div class='panel-body'>
<div class='table-row'>
<div class='table-col chart-titles'>
<div class='chart-col-title strong'><span><?php echo $lang->project->name;?></span></div>
<?php foreach($projects as $project):?>
<?php
$maxTeamCount = max($maxTeamCount, $project->teamCount);
@@ -48,24 +47,22 @@ $maxConsumed = 0;
</div>
<style>
.block-projectteam .panel-body {margin-top: -10px}
.chart-titles {width: 110px; padding-right: 10px; position: relative; z-index: 1}
.chart-titles {top: 30px; width: 110px; padding-right: 10px; position: relative; z-index: 1}
.chart-rows {position: relative; z-index: 0}
.chart-title {width: 100px; line-height: 20px; padding: 5px 0; height: 30px}
.chart-title > span {background: #fff}
.chart-col-title {line-height: 20px; margin-bottom: 10px; padding: 0 10px}
.project-team, .project-consumed {padding: 0}
.project-team {border-right: 1px solid #e5e8ec}
.project-team > .chart-col-title {text-align: right}
.project-team, .project-consumed {padding: 0; border-left: 1px solid #e5e8ec}
.chart-col-item {height: 30px; padding: 5px 0}
.chart-col-text {width: 50px; position: absolute; top: 5px; line-height: 20px; left: 0}
.project-team .chart-col-item {padding-left: 50px}
.project-team .chart-col-item {padding-right: 50px}
.project-team .chart-col-item:before {content: ' '; z-index: 0; left: -100px; top: 14px; right: 0; border-top: 1px dotted #e5e8ec}
.project-consumed .chart-col-item {padding-right: 50px}
.chart-col-item .progress {background: none; border-radius: 0; overflow: visible; margin: 6px 0 0 0; position: relative; z-index: 1}
.chart-col-item .progress > .progress-bar {border-radius: 0; position: relative; min-width: 1px}
.project-team .chart-col-item .progress > .progress-bar {float: right; background-color: #39cfff}
.project-team .chart-col-item .progress > .progress-bar {background-color: #39cfff}
.chart-col-item .progress .progress-text {position: absolute; top: -6px; color: #333; width: 50px; line-height: 20px; white-space: nowrap; overflow: visible}
.project-team .progress .progress-text {text-align: right; left: -50px; padding-right: 5px}
.project-team .progress .progress-text {text-align: left; right: -55px; padding-right: 5px}
.project-consumed .progress .progress-text {text-align: left; right: -50px; padding-left: 5px}
</style>
</div>
@@ -41,7 +41,6 @@
<div class='col'>
<div class='panel-content'>
<div class='panel-heading not-move-handler'>
<strong class='project-name' title='<?php echo $project->name;?>'> <?php echo html::a($viewLink, $project->name);?> </strong>
<?php if($config->systemMode == 'new'):?>
<?php if($project->model === 'waterfall'): ?>
<span class='project-type-label label label-warning label-outline'><?php echo $lang->project->waterfall; ?></span>
@@ -49,6 +48,7 @@
<span class='project-type-label label label-info label-outline'><?php echo $lang->project->scrum; ?></span>
<?php endif; ?>
<?php endif; ?>
<strong class='project-name' title='<?php echo $project->name;?>'> <?php echo html::a($viewLink, $project->name);?> </strong>
<nav class='panel-actions nav nav-default'>
<li class='dropdown'>
<ul class='dropdown-menu pull-right cards-menu'>
@@ -3,17 +3,19 @@
<tr>
<th class='w-100px'><?php echo $lang->durationestimation->people;?></th>
<td><?php echo $people ? $people : 0;?></td>
<th class='w-80px'><?php echo $lang->durationestimation->members;?></th>
<td><?php echo $members;?></td>
<th class='w-100px'><?php echo $lang->workestimation->duration;?></th>
<td><?php echo zget($budget, 'duration', 0);?></td>
</tr>
<tr>
<th><?php echo $lang->workestimation->duration;?></th>
<td><?php echo zget($budget, 'duration', 0);?></td>
<th><?php echo $lang->workestimation->consumed;?></th>
<th class='w-100px'><?php echo $lang->durationestimation->members;?></th>
<td><?php echo $members;?></td>
<th class='w-100px'><?php echo $lang->workestimation->consumed;?></th>
<td><?php echo $consumed ? $consumed : 0;?></td>
</tr>
<tr>
<th><?php echo $lang->workestimation->totalLaborCost;?></th>
<th class='w-100px'><?php echo $lang->workestimation->totalLaborCost;?></th>
<td><?php echo '¥' . zget($budget, 'totalLaborCost', 0);?></td>
<th class='w-100px'><?php echo $lang->block->leftHour;?></th>
<td><?php echo $totalLeft ? $totalLeft : 0;?></td>
</tr>
</table>
+2
View File
@@ -208,6 +208,8 @@ $lang->my->work = 'Work';
$lang->project->list = 'Project List';
$lang->execution->list = "{$lang->executionCommon} List";
$lang->doc->recent = 'Recent';
$lang->doc->my = 'My';
$lang->doc->favorite = 'Favorite';
+3 -3
View File
@@ -173,7 +173,7 @@ $lang->project->homeMenu->browse = array('link' => ($config->systemMode == 'new'
/* Scrum menu. */
$lang->scrum->menu = new stdclass();
$lang->scrum->menu->index = array('link' => "{$lang->dashboard}|project|index|project=%s");
$lang->scrum->menu->execution = array('link' => "$lang->executionCommon|project|execution|projectID=%s");
$lang->scrum->menu->execution = array('link' => "$lang->executionCommon|project|execution|status=all&projectID=%s");
$lang->scrum->menu->story = array('link' => "$lang->SRCommon|projectstory|story|projectID=%s", 'subModule' => 'projectstory', 'alias' => 'story,track');
$lang->scrum->menu->doc = array('link' => "{$lang->doc->common}|doc|objectLibs|type=project&objectID=%s", 'subModule' => 'doc');
$lang->scrum->menu->qa = array('link' => "{$lang->qa->common}|project|bug|projectID=%s", 'subModule' => 'testcase,testtask,bug,testreport', 'alias' => 'bug,testtask,testcase,testreport');
@@ -214,8 +214,8 @@ $lang->scrum->menu->settings['subMenu']->group = array('link' => "{$lang->
/* Execution menu. */
$lang->execution->homeMenu = new stdclass();
$lang->execution->homeMenu->index = "$lang->dashboard|execution|index|";
$lang->execution->homeMenu->list = array('link' => "{$lang->execution->common}|execution|all|", 'alias' => 'create,batchedit');
if($config->systemMode == 'new') $lang->execution->homeMenu->index = "$lang->dashboard|execution|index|";
$lang->execution->homeMenu->list = array('link' => "{$lang->executionCommon}|execution|all|", 'alias' => 'create,batchedit');
$lang->execution->menu = new stdclass();
$lang->execution->menu->task = array('link' => "{$lang->task->common}|execution|task|executionID=%s", 'subModule' => 'task,tree', 'alias' => 'importtask,importbug');
+2
View File
@@ -208,6 +208,8 @@ $lang->my->work = '待处理';
$lang->project->list = '项目列表';
$lang->execution->list = "{$lang->executionCommon}列表";
$lang->doc->recent = '最近文档';
$lang->doc->my = '我的文档';
$lang->doc->favorite = '我的收藏';
+3 -1
View File
@@ -519,6 +519,7 @@ class commonModel extends model
public static function printHomeButton($openApp)
{
global $lang;
global $config;
if(!$openApp) return;
$icon = zget($lang->navIcons, $openApp, '');
@@ -527,6 +528,7 @@ class commonModel extends model
{
$nav = $lang->mainNav->$openApp;
list($title, $currentModule, $currentMethod, $vars) = explode('|', $nav);
if($openApp == 'execution') $currentMethod = 'all';
}
else
{
@@ -535,7 +537,7 @@ class commonModel extends model
if($openApp == 'product') $currentMethod = 'all';
}
$link = $openApp != 'execution' ? helper::createLink($currentModule, $currentMethod) : '';
$link = ($openApp != 'execution' or ($config->systemMode == 'classic')) ? helper::createLink($currentModule, $currentMethod) : '';
$html = $link ? html::a($link, "$icon {$lang->$openApp->common}", '', "class='btn'") : "$icon {$lang->$openApp->common}";
echo "<div class='btn-group header-btn'>" . $html . '</div>';
+19 -31
View File
@@ -2280,11 +2280,12 @@ class executionModel extends model
$data = (array)fixer::input('post')->get();
extract($data);
$executionType = strpos('sprint|stage', $execution->type) !== false ? 'execution' : $execution->type;
$executionID = (int)$executionID;
$executionType = 'execution';
$accounts = array_unique($accounts);
$limited = array_values($limited);
$oldJoin = $this->dao->select('`account`, `join`')->from(TABLE_TEAM)->where('root')->eq((int)$executionID)->andWhere('type')->eq($executionType)->fetchPairs();
$this->dao->delete()->from(TABLE_TEAM)->where('root')->eq((int)$executionID)->andWhere('type')->eq($executionType)->exec();
$oldJoin = $this->dao->select('`account`, `join`')->from(TABLE_TEAM)->where('root')->eq($executionID)->andWhere('type')->eq($executionType)->fetchPairs();
$this->dao->delete()->from(TABLE_TEAM)->where('root')->eq($executionID)->andWhere('type')->eq($executionType)->exec();
$executionMember = array();
foreach($accounts as $key => $account)
@@ -2297,13 +2298,13 @@ class executionModel extends model
$member->hours = $hours[$key];
$member->limited = $limited[$key];
$member->root = (int)$executionID;
$member->root = $executionID;
$member->account = $account;
$member->join = isset($oldJoin[$account]) ? $oldJoin[$account] : helper::today();
$member->type = $executionType;
$executionMember[$account] = $member;
$this->dao->replace(TABLE_TEAM)->data($member)->exec();
$this->dao->insert(TABLE_TEAM)->data($member)->exec();
}
/* Only changed account update userview. */
@@ -2312,36 +2313,23 @@ class executionModel extends model
$changedAccounts = array_merge($changedAccounts, array_diff($oldAccounts, $accounts));
$changedAccounts = array_unique($changedAccounts);
if($executionType == 'execution')
{
$childSprints = $this->dao->select('id')->from(TABLE_EXECUTION)->where('project')->eq($execution->id)->andWhere('type')->in('stage,sprint')->andWhere('deleted')->eq('0')->fetchPairs();
$linkedProducts = $this->loadModel('product')->getProductPairsByProject($execution->id);
$this->loadModel('user')->updateUserView(array($executionID), 'execution', $changedAccounts);
if(!empty($childSprints)) $this->user->updateUserView($childSprints, 'sprint', $changedAccounts);
if(!empty($linkedProducts)) $this->user->updateUserView(array_keys($linkedProducts), 'product', $changedAccounts);
}
/* Add iteration or phase team members to the execution team. */
if($executionType == 'stage' || $executionType == 'sprint')
{
$this->addExecutionMembers($execution->project, $executionMember);
if($execution->acl != 'open') $this->updateUserView($executionID, 'sprint', $changedAccounts);
}
/* Add the execution team members to the project. */
$this->addProjectMembers($execution->project, $executionMember);
if($execution->acl != 'open') $this->updateUserView($executionID, 'sprint', $changedAccounts);
}
/**
* Add iteration or phase team members to the execution team.
* Add the execution team members to the project.
*
* @param int $executionID
* @param int $projectID
* @param array $members
* @access public
* @return void
*/
public function addExecutionMembers($executionID = 0, $members = array())
public function addProjectMembers($projectID = 0, $members = array())
{
$executionType = 'execution';
$oldJoin = $this->dao->select('`account`, `join`')->from(TABLE_TEAM)->where('root')->eq($executionID)->andWhere('type')->eq($executionType)->fetchPairs();
$projectType = 'project';
$oldJoin = $this->dao->select('`account`, `join`')->from(TABLE_TEAM)->where('root')->eq($projectID)->andWhere('type')->eq($projectType)->fetchPairs();
$accounts = array();
foreach($members as $account => $member)
@@ -2349,9 +2337,9 @@ class executionModel extends model
if(isset($oldJoin[$member->account])) continue;
$accounts[] = $member->account;
$member->root = $executionID;
$member->type = $executionType;
$this->dao->replace(TABLE_TEAM)->data($member)->exec();
$member->root = $projectID;
$member->type = $projectType;
$this->dao->insert(TABLE_TEAM)->data($member)->exec();
}
/* Only changed account update userview. */
@@ -2360,8 +2348,8 @@ class executionModel extends model
$changedAccounts = array_merge($changedAccounts, array_diff($oldAccounts, $accounts));
$changedAccounts = array_unique($changedAccounts);
$this->loadModel('user')->updateUserView($executionID, $executionType, $changedAccounts);
$linkedProducts = $this->loadModel('product')->getProductPairsByProject($executionID);
$this->loadModel('user')->updateUserView($projectID, $projectType, $changedAccounts);
$linkedProducts = $this->loadModel('product')->getProductPairsByProject($projectID);
if(!empty($linkedProducts)) $this->user->updateUserView(array_keys($linkedProducts), 'product', $changedAccounts);
}
+3 -3
View File
@@ -31,13 +31,13 @@
<div id="sidebarHeader">
<div class="title">
<?php echo empty($projectID) ? $lang->project->common : zget($projects, $projectID);?>
<?php if($projectID) echo html::a(inLink('all'), "<i class='icon icon-sm icon-close'></i>", '', 'class="text-muted"');?>
<?php if($projectID) echo html::a($this->createLink($this->app->rawModule, $this->app->rawMethod), "<i class='icon icon-sm icon-close'></i>", '', 'class="text-muted"');?>
</div>
</div>
<?php endif;?>
<div class='btn-toolbar pull-left'>
<?php foreach($lang->execution->featureBar['all'] as $key => $label):?>
<?php echo html::a(inlink("all", "status=$key&projectID=$projectID&orderBy=$orderBy&productID=$productID"), "<span class='text'>{$label}</span>", '', "class='btn btn-link' id='{$key}Tab' data-app='$from'");?>
<?php echo html::a($this->createLink($this->app->rawModule, $this->app->rawMethod, "status=$key&projectID=$projectID&orderBy=$orderBy&productID=$productID"), "<span class='text'>{$label}</span>", '', "class='btn btn-link' id='{$key}Tab' data-app='$from'");?>
<?php endforeach;?>
</div>
<div class='btn-toolbar pull-right'>
@@ -55,7 +55,7 @@
<?php $canBatchEdit = common::hasPriv('execution', 'batchEdit'); ?>
<form class='main-table' id='executionsForm' method='post' action='<?php echo inLink('batchEdit');?>' data-ride='table'>
<table class='table has-sort-head table-fixed' id='executionList'>
<?php $vars = "status=$status&projectID=$projectID&from=$from&orderBy=%s&productID=$productID&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?>
<?php $vars = "status=$status&projectID=$projectID&orderBy=%s&productID=$productID&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?>
<thead>
<tr>
<th class='c-id'>
+3 -3
View File
@@ -74,11 +74,11 @@ class personnelModel extends model
->orderBy('id_desc')
->fetchAll('id');
if(empty($projects)) return $personnelList;
$accountPairs = $this->getInvolvedProjects($projects);
if(empty($accountPairs)) return $personnelList;
$executionPairs = $this->getInvolvedExecutions($projects);
$executionPairs = $this->getInvolvedExecutions($projects);
$taskInvest = $this->getProjectTaskInvest($projects, $accountPairs);
$bugAndStoryInvest = $this->getBugAndStoryInvest($accountPairs, $programID);
if(isset($this->config->maxVersion))
@@ -267,7 +267,7 @@ class personnelModel extends model
return $this->dao->select('account, count(root) as executions')->from(TABLE_TEAM)
->where('root')->in(array_keys($executions))
->andWhere('type')->in('stage,sprint')
->andWhere('type')->in('execution')
->groupBy('account')
->fetchPairs('account');
}
+1 -1
View File
@@ -12,7 +12,7 @@ $lang->program->progress = '项目进度';
$lang->program->children = '子项目集';
$lang->program->parent = '父项目集';
$lang->program->allInput = '项目集总投入';
$lang->program->teamCount = '项目集成员';
$lang->program->teamCount = '总人数';
$lang->program->longTime = '长期';
$lang->program->view = '项目集详情';
+9 -3
View File
@@ -651,16 +651,22 @@ class project extends control
/**
* Execution list.
*
* @param string $status
* @param int $projectID
* @param string $orderBy
* @param int $productID
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
* @access public
* @return void
*/
public function execution($projectID = 0)
public function execution($status = 'all', $projectID = 0, $orderBy = 'id_desc', $productID = 0, $recTotal = 0, $recPerPage = 10, $pageID = 1)
{
$uri = $this->app->getURI(true);
$this->app->session->set('executionList', $uri, 'project');
echo $this->fetch('execution', 'all', "status=all&projectID=$projectID");
echo $this->fetch('execution', 'all', "status=$status&projectID=$projectID&orderBy=$orderBy&productID=$productID&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID");
}
/**
@@ -1030,7 +1036,7 @@ class project extends control
if(!empty($_POST))
{
$this->execution->manageMembers($projectID);
$this->project->manageMembers($projectID);
$link = $this->createLink('project', 'manageMembers', "projectID=$projectID");
$this->send(array('message' => $this->lang->saveSuccess, 'result' => 'success', 'locate' => $link));
}
+54
View File
@@ -1227,6 +1227,60 @@ class projectModel extends model
}
}
/**
* Manage team members.
*
* @param int $projectID
* @access public
* @return void
*/
public function manageMembers($projectID)
{
$project = $this->getByID($projectID);
$data = (array)fixer::input('post')->get();
extract($data);
$projectID = (int)$projectID;
$projectType = 'project';
$accounts = array_unique($accounts);
$limited = array_values($limited);
$oldJoin = $this->dao->select('`account`, `join`')->from(TABLE_TEAM)->where('root')->eq($projectID)->andWhere('type')->eq($projectType)->fetchPairs();
$this->dao->delete()->from(TABLE_TEAM)->where('root')->eq($projectID)->andWhere('type')->eq($projectType)->exec();
$projectMember = array();
foreach($accounts as $key => $account)
{
if(empty($account)) continue;
$member = new stdclass();
$member->role = $roles[$key];
$member->days = $days[$key];
$member->hours = $hours[$key];
$member->limited = $limited[$key];
$member->root = $projectID;
$member->account = $account;
$member->join = isset($oldJoin[$account]) ? $oldJoin[$account] : helper::today();
$member->type = $projectType;
$projectMember[$account] = $member;
$this->dao->insert(TABLE_TEAM)->data($member)->exec();
}
/* Only changed account update userview. */
$oldAccounts = array_keys($oldJoin);
$changedAccounts = array_diff($accounts, $oldAccounts);
$changedAccounts = array_merge($changedAccounts, array_diff($oldAccounts, $accounts));
$changedAccounts = array_unique($changedAccounts);
$childSprints = $this->dao->select('id')->from(TABLE_PROJECT)->where('project')->eq($projectID)->andWhere('type')->in('stage,sprint')->andWhere('deleted')->eq('0')->fetchPairs();
$linkedProducts = $this->loadModel('product')->getProductPairsByProject($projectID);
$this->loadModel('user')->updateUserView(array($projectID), 'project', $changedAccounts);
if(!empty($childSprints)) $this->user->updateUserView($childSprints, 'sprint', $changedAccounts);
if(!empty($linkedProducts)) $this->user->updateUserView(array_keys($linkedProducts), 'product', $changedAccounts);
}
/**
* Print datatable cell.
*
+30
View File
@@ -35,6 +35,13 @@ function loadExecutionMembers(executionID)
$(this).find('#team').replaceWith(data);
$(this).find('#assignedTo').attr('id', 'team').attr('name', 'team[]').chosen();
});
$('#testStoryBox table tbody tr').each(function(i)
{
$td = $(this).find('#testAssignedTo').closest('td');
$td.html(data);
$td.find('#assignedTo').val('').attr('id', 'testAssignedTo').attr('name', 'testAssignedTo[]').chosen();
});
});
}
@@ -53,6 +60,29 @@ function loadExecutionStories(executionID)
$('#story').next('.picker').remove();
$('#story').replaceWith(data);
$('#story').addClass('filled').chosen();
if($('#testStoryBox table tbody tr').length == 0)
{
var trHtml = $('#testStoryTemplate tr').prop("outerHTML");
$('#testStoryBox table tbody').append(trHtml);
$td = $('#testStoryBox table tbody tr:first').find('#testStory').closest('td');
$td.html(data);
$td.find('#story').val($td.find('#story option').eq(i).val()).attr('id', 'testStory').attr('name', 'testStory[]').addClass('filled').chosen();
$td = $('#testStoryBox table tbody tr:first').find('#testPri_chosen').closest('td');
$td.find('#testPri_chosen').remove();
$td.find('#testPri').chosen();
}
else
{
$('#testStoryBox table tbody tr').each(function(i)
{
$td = $(this).find('#testStory').closest('td');
$td.html(data);
$td.find('#story').val($td.find('#story option').eq(i).val()).attr('id', 'testStory').attr('name', 'testStory[]').addClass('filled').chosen();
});
}
});
}
+21
View File
@@ -293,6 +293,27 @@
</form>
</div>
</div>
<table class='hidden' id='testStoryTemplate'>
<tr>
<td><?php echo html::select("testStory[]", array(0 => ''), 0, "class='form-control chosen'");?></td>
<td><?php echo html::select("testPri[]", $lang->task->priList, '', "class='form-control chosen'");?></td>
<td>
<div class='input-group'>
<?php echo html::input("testEstStarted[]", '', "class='form-control form-date' placeholder='{$lang->task->estStarted}'");?>
<span class='input-group-addon fix-border'>~</span>
<?php echo html::input("testDeadline[]", '', "class='form-control form-date' placeholder='{$lang->task->deadline}'");?>
</div>
</td>
<td><?php echo html::select("testAssignedTo[]", array('' => ''), '', "class='form-control chosen'");?></td>
<td><?php echo html::input("testEstimate[]", '', "class='form-control'");?></td>
<td class='text-center'>
<div class="btn-group">
<button type="button" class="btn btn-sm" tabindex="-1" onclick='addItem(this)'><i class="icon icon-plus"></i></button>
<button type="button" class="btn btn-sm" tabindex="-1" onclick='removeItem(this)'><i class="icon icon-close"></i></button>
</div>
</td>
</tr>
</table>
<?php js::set('stories', $stories);?>
<?php js::set('storyPinYin', (empty($config->isINT) and class_exists('common')) ? common::convert2Pinyin($stories) : array());?>
<?php js::set('testStoryIdList', $testStoryIdList);?>
@@ -11,9 +11,6 @@
*/
include "../../../common/view/header.html.php";
?>
<div id="mainMenu" class="clearfix">
<div class="btn-toolbar pull-left"><?php common::printAdminSubMenu('xuanxuan');?></div>
</div>
<div id='dashboardWrapper'>
<div class='panels-container dashboard' id='dashboard'>
<div class='row'>