Merge branch '20.x' of https://github.com/easysoft/zentaopms into 20.x
This commit is contained in:
@@ -758,6 +758,7 @@ class block extends control
|
||||
if(!empty($this->params->type) and preg_match('/[^a-zA-Z0-9_]/', $this->params->type)) die();
|
||||
|
||||
$this->loadModel('project');
|
||||
$this->loadModel('weekly');
|
||||
$this->app->loadLang('task');
|
||||
$this->app->loadLang('story');
|
||||
|
||||
@@ -772,26 +773,39 @@ class block extends control
|
||||
return false;
|
||||
}
|
||||
|
||||
$today = date('Y-m-d', strtotime(helper::today()));
|
||||
$date = date('Ymd', strtotime($this->loadModel('weekly')->getThisMonday($today)));
|
||||
$tasks = $this->dao->select("program, sum(consumed) as totalConsumed, sum(if(status != 'cancel' and status != 'closed', `left`, 0)) as totalLeft")->from(TABLE_TASK)
|
||||
->where('program')->in(array_keys($programs))
|
||||
->andWhere('deleted')->eq(0)
|
||||
->andWhere('parent')->lt(1)
|
||||
->groupBy('program')
|
||||
->fetchAll('program');
|
||||
|
||||
foreach($programs as $programID => $program)
|
||||
{
|
||||
$program->allStories = $program->doneStories = $program->leftStories = 0;
|
||||
|
||||
$stories = $this->dao->select('id, status')->from(TABLE_STORY)
|
||||
->where('deleted')->eq(0)
|
||||
->andWhere('type')->eq('story')
|
||||
->andWhere('status')->ne('draft')
|
||||
->andWhere('program')->eq($programID)
|
||||
->fetchPairs();
|
||||
foreach($stories as $id => $status)
|
||||
if($program->template == 'scrum')
|
||||
{
|
||||
$program->allStories ++;
|
||||
if($status == 'closed') $program->doneStories ++;
|
||||
if($status != 'closed') $program->leftStories ++;
|
||||
$program->progress = $program->allStories == 0 ? 0 : round($program->doneStories / $program->allStories, 3) * 100;
|
||||
$program->projects = $this->project->getProjectStats('all', 0, 0, 1, 'id_desc', null, $programID);
|
||||
}
|
||||
else
|
||||
{
|
||||
$begin = $program->begin;
|
||||
$weeks = $this->weekly->getWeekPairs($begin);
|
||||
$current = zget($weeks, $date, '');
|
||||
|
||||
$program->progress = $program->allStories == 0 ? 0 : ceil($program->doneStories / $program->allStories) * 100;
|
||||
$program->pv = $this->weekly->getPV($programID, $today);
|
||||
$program->ev = $this->weekly->getEV($programID, $today);
|
||||
$program->ac = $this->weekly->getAC($programID, $today);
|
||||
$program->sv = $this->weekly->getSV($program->ev, $program->pv);
|
||||
$program->cv = $this->weekly->getCV($program->ev, $program->ac);
|
||||
|
||||
//$program->projects = $this->dao->select('*')
|
||||
$progress = isset($tasks[$programID]) ? (($tasks[$programID]->totalConsumed + $tasks[$programID]->totalLeft)) ? round($tasks[$programID]->totalConsumed / ($tasks[$programID]->totalConsumed + $tasks[$programID]->totalLeft), 3) * 100 : 0 : 0;
|
||||
|
||||
$program->current = $current;
|
||||
$program->progress = $progress;
|
||||
}
|
||||
}
|
||||
|
||||
$this->view->programs = $programs;
|
||||
@@ -1030,7 +1044,7 @@ class block extends control
|
||||
$projects[$project->id]->releasedStories = 0;
|
||||
}
|
||||
|
||||
$projects[$project->id]->progress = ($project->totalConsumed || $project->totalLeft) ? round($project->totalConsumed / ($project->totalConsumed + $project->totalLeft), 2) * 100 : 0;
|
||||
$projects[$project->id]->progress = ($project->totalConsumed || $project->totalLeft) ? round($project->totalConsumed / ($project->totalConsumed + $project->totalLeft), 3) * 100 : 0;
|
||||
$projects[$project->id]->taskProgress = $project->totalTasks ? round(($project->totalTasks - $project->undoneTasks) / $project->totalTasks, 2) * 100 : 0;
|
||||
$projects[$project->id]->storyProgress = $project->totalStories ? round(($project->totalStories - $project->unclosedStories) / $project->totalStories, 2) * 100 : 0;
|
||||
$projects[$project->id]->bugProgress = $project->totalBugs ? round(($project->totalBugs - $project->activeBugs) / $project->totalBugs, 2) * 100 : 0;
|
||||
@@ -1065,7 +1079,7 @@ class block extends control
|
||||
$this->view->cv = $this->weekly->getCV($this->view->ev, $this->view->ac);
|
||||
|
||||
$this->view->current = $current;
|
||||
$this->view->progress = ($task->totalConsumed + $task->totalLeft) ? round($task->totalConsumed / ($task->totalConsumed + $task->totalLeft), 2) * 100 : 0;
|
||||
$this->view->progress = ($task->totalConsumed + $task->totalLeft) ? round($task->totalConsumed / ($task->totalConsumed + $task->totalLeft), 3) * 100 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -55,6 +55,10 @@ html[lang="en"] .product-info .type-info {color: #A6AAB8; text-align: center; po
|
||||
.block-statistic.block-sm .nav-secondary > li.active > a.btn-view {width: auto; left: 0; right: 0;}
|
||||
.block-statistic.block-sm .nav-secondary > li.active > a.btn-view > i {display: none;}
|
||||
.block-statistic.block-sm .nav-secondary > li.active > a.btn-view:hover {cursor: pointer; background: rgba(0,0,0,.1)}
|
||||
.block-statistic .program-info .info span+span{margin-left: 15px}
|
||||
.block-statistic .project-info{margin-top: 25px}
|
||||
.block-statistic .project-info .col-xs-5, .block-statistic .project-info .col-xs-7{margin-top: 8px}
|
||||
.block-statistic .project-info .col-xs-5{padding-left: 0px;}
|
||||
|
||||
.status-count{margin:auto}
|
||||
.status-count tr:first-child td:last-child{color:#000;font-weight:bold}
|
||||
@@ -133,14 +137,28 @@ $(function()
|
||||
</div>
|
||||
<div class="col-7">
|
||||
<div class="program-info">
|
||||
<div class='title'><?php echo $lang->program->allInput;?></div>
|
||||
<h4><?php echo $lang->program->allInput;?></h4>
|
||||
<div class='info'>
|
||||
<span><i class='icon icon-group'></i> <?php echo $program->countMembers;?></span>
|
||||
<span><i class='icon icon-clock'></i> <?php echo $program->consumed;?></span>
|
||||
<span><i class='icon icon-cost'></i> <?php echo $program->budget;?></span>
|
||||
<span><i class='icon icon-group'></i> <?php echo $program->teamCount;?></span>
|
||||
<span><i class='icon icon-clock'></i> <?php echo $program->estimate;?></span>
|
||||
<span><i class='icon icon-cost'></i> <?php echo $program->budget . ' ' . zget($lang->program->unitList, $program->budgetUnit);?></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="project-info">
|
||||
<?php $i = 0;?>
|
||||
<h4><?php echo $lang->program->lastIteration;?></h4>
|
||||
<?php foreach($program->projects as $project):?>
|
||||
<?php $i ++;?>
|
||||
<?php if($i > 3) break;?>
|
||||
<div class='col-xs-5'><?php echo $project->name;?></div>
|
||||
<div class='col-xs-7'>
|
||||
<div class='progress progress-text-left'>
|
||||
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="<?php echo $project->hours->progress;?>" aria-valuemin="0" aria-valuemax="100" style="width: <?php echo $project->hours->progress;?>%">
|
||||
<span class='progress-text'><?php echo $project->hours->progress . '%';?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach;?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
.block-welcome .progress-group{margin-top: 20px;}
|
||||
.block-welcome .progress{margin-top: 10px; width: 85%}
|
||||
</style>
|
||||
<?php $progress = $tasks == 0 ? 0 : ceil($doneTasks / $tasks) * 100;?>
|
||||
<?php $progress = $tasks == 0 ? 0 : ($doneTasks / $tasks) * 100;?>
|
||||
<div class='panel-move-handler'></div>
|
||||
<div class="panel-body conatiner-fluid">
|
||||
<div class="table-row">
|
||||
|
||||
@@ -133,7 +133,6 @@ class design extends control
|
||||
$this->view->position[] = $this->lang->design->batchCreate;
|
||||
|
||||
$typeList = (array)$this->lang->design->typeList;
|
||||
$typeList[''] = '';
|
||||
|
||||
$this->view->typeList = $typeList;
|
||||
$this->view->stories = $this->loadModel('story')->getProductStoryPairs($productID);
|
||||
|
||||
@@ -37,6 +37,7 @@ $lang->design->createdDate = '创建时间';
|
||||
$lang->design->basicInfo = '基本信息';
|
||||
|
||||
$lang->design->typeList = array();
|
||||
$lang->design->typeList[''] = '';
|
||||
$lang->design->typeList['HLDS'] = '概要设计';
|
||||
$lang->design->typeList['DDS'] = '详细设计';
|
||||
$lang->design->typeList['DBDS'] = '数据库设计';
|
||||
|
||||
@@ -264,16 +264,21 @@ class designModel extends model
|
||||
*/
|
||||
public function getList($productID, $type = 'all', $param = 0, $orderBy = 'id_desc', $pager = null)
|
||||
{
|
||||
if($type == 'bySearch') return $this->getBySearch($param, $orderBy, $pager);
|
||||
|
||||
$designs = $this->dao->select('*')->from(TABLE_DESIGN)
|
||||
->where('deleted')->eq(0)
|
||||
->beginIF($this->session->program)->andWhere('program')->eq($this->session->program)->fi()
|
||||
->beginIF($type != 'all')->andWhere('type')->in($type)->fi()
|
||||
->andWhere('product')->eq($productID)
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll('id');
|
||||
if($type == 'bySearch')
|
||||
{
|
||||
$designs = $this->getBySearch($param, $orderBy, $pager);
|
||||
}
|
||||
else
|
||||
{
|
||||
$designs = $this->dao->select('*')->from(TABLE_DESIGN)
|
||||
->where('deleted')->eq(0)
|
||||
->beginIF($this->session->program)->andWhere('program')->eq($this->session->program)->fi()
|
||||
->beginIF($type != 'all')->andWhere('type')->in($type)->fi()
|
||||
->andWhere('product')->eq($productID)
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll('id');
|
||||
}
|
||||
|
||||
foreach($designs as $id => $design)
|
||||
{
|
||||
@@ -324,13 +329,6 @@ class designModel extends model
|
||||
->page($pager)
|
||||
->fetchAll('id');
|
||||
|
||||
foreach($designs as $id => $design)
|
||||
{
|
||||
$design->commit = '';
|
||||
$relations = $this->loadModel('common')->getRelations('design', $id, 'commit');
|
||||
foreach($relations as $relation) $design->commit .= html::a(helper::createLink('design', 'revision', "repoID=$relation->BID", '', true), "#$relation->BID", '_blank');
|
||||
}
|
||||
|
||||
return $designs;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,3 +11,8 @@ $config->program->editor->suspend = array('id' => 'comment', 'tools' => 'simple
|
||||
|
||||
$config->program->list = new stdclass();
|
||||
$config->program->list->exportFields = 'id,name,code,template,category,status,begin,end,budget,PM,end,desc';
|
||||
|
||||
$config->program->create = new stdclass();
|
||||
$config->program->edit = new stdclass();
|
||||
$config->program->create->requiredFields = 'name,code,begin,end';
|
||||
$config->program->edit->requiredFields = 'name,code,begin,end';
|
||||
|
||||
@@ -44,6 +44,8 @@ class program extends control
|
||||
{
|
||||
if(common::hasPriv('program', 'createGuide')) $this->lang->pageActions = html::a($this->createLink('program', 'createGuide'), "<i class='icon icon-sm icon-plus'></i> " . $this->lang->program->create, '', "class='btn btn-primary' data-toggle=modal");
|
||||
|
||||
$this->app->session->set('programList', $this->app->getURI(true));
|
||||
|
||||
$programType = $this->cookie->programType ? $this->cookie->programType : 'bylist';
|
||||
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
@@ -151,30 +153,33 @@ class program extends control
|
||||
/**
|
||||
* Edit a program.
|
||||
*
|
||||
* @param int $projectID
|
||||
* @param int $programID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function edit($projectID = 0)
|
||||
public function edit($programID = 0)
|
||||
{
|
||||
$project = $this->project->getByID($projectID);
|
||||
$program = $this->project->getByID($programID);
|
||||
|
||||
if($_POST)
|
||||
{
|
||||
$changes = $this->project->update($projectID);
|
||||
$changes = $this->program->update($programID);
|
||||
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => $this->processErrors(dao::getError())));
|
||||
if($changes)
|
||||
{
|
||||
$actionID = $this->loadModel('action')->create('project', $projectID, 'edited');
|
||||
$actionID = $this->loadModel('action')->create('program', $programID, 'edited');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse')));
|
||||
|
||||
$url = $this->session->programList ? $this->session->programList : inlink('browse');
|
||||
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $url));
|
||||
}
|
||||
|
||||
$this->view->pmUsers = $this->loadModel('user')->getPairs('noclosed|nodeleted|pmfirst', $project->PM);
|
||||
$this->view->title = $this->lang->project->edit;
|
||||
$this->view->position[] = $this->lang->project->edit;
|
||||
$this->view->project = $project;
|
||||
$this->view->pmUsers = $this->loadModel('user')->getPairs('noclosed|nodeleted|pmfirst', $program->PM);
|
||||
$this->view->title = $this->lang->program->edit;
|
||||
$this->view->position[] = $this->lang->program->edit;
|
||||
$this->view->program = $program;
|
||||
$this->view->parents = $this->program->getParentPairs();
|
||||
$this->view->groups = $this->loadModel('group')->getPairs();
|
||||
$this->display();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
<?php
|
||||
class programModel extends model
|
||||
{
|
||||
/**
|
||||
* Get program list.
|
||||
*
|
||||
* @param varchar $status
|
||||
* @param varchar $orderBy
|
||||
* @param object $pager
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getList($status = 'all', $orderBy = 'id_desc', $pager = NULL)
|
||||
{
|
||||
return $this->dao->select('*')->from(TABLE_PROJECT)
|
||||
@@ -20,6 +29,12 @@ class programModel extends model
|
||||
->fetchAll('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get program pairs.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getPairs()
|
||||
{
|
||||
return $this->dao->select('id, name')->from(TABLE_PROJECT)
|
||||
@@ -30,6 +45,13 @@ class programModel extends model
|
||||
->fetchPairs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get program pairs by template.
|
||||
*
|
||||
* @param varchar $template
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getPairsByTemplate($template)
|
||||
{
|
||||
return $this->dao->select('id, name')->from(TABLE_PROJECT)
|
||||
@@ -41,6 +63,15 @@ class programModel extends model
|
||||
->fetchPairs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user programs for block.
|
||||
*
|
||||
* @param varchar $status
|
||||
* @param varchar $orderBy
|
||||
* @param int $limit
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getUserPrograms($status = 'all', $orderBy = 'id_desc', $limit = 15)
|
||||
{
|
||||
$programs = $this->dao->select('*')->from(TABLE_PROJECT)
|
||||
@@ -57,7 +88,7 @@ class programModel extends model
|
||||
if(empty($programs)) return array();
|
||||
$programIdList = array_keys($programs);
|
||||
|
||||
$consumes = $this->dao->select('program, sum(consumed) as consumed')->from(TABLE_TASK)
|
||||
$hours = $this->dao->select('program, sum(consumed) as consumed, sum(estimate) as estimate')->from(TABLE_TASK)
|
||||
->where('program')->in($programIdList)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->andWhere('parent')->lt(1)
|
||||
@@ -76,6 +107,21 @@ class programModel extends model
|
||||
->groupBy('program')
|
||||
->fetchAll('program');
|
||||
|
||||
$allStories = $this->dao->select('program, count(*) as allStories')->from(TABLE_STORY)
|
||||
->where('program')->in($programIdList)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->andWhere('status')->ne('draft')
|
||||
->groupBy('program')
|
||||
->fetchAll('program');
|
||||
|
||||
$doneStories = $this->dao->select('program, count(*) as doneStories')->from(TABLE_STORY)
|
||||
->where('program')->in($programIdList)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->andWhere('status')->eq('closed')
|
||||
->andWhere('closedReason')->eq('done')
|
||||
->groupBy('program')
|
||||
->fetchAll('program');
|
||||
|
||||
$leftStories = $this->dao->select('program, count(*) as leftStories')->from(TABLE_STORY)
|
||||
->where('program')->in($programIdList)
|
||||
->andWhere('deleted')->eq(0)
|
||||
@@ -93,10 +139,13 @@ class programModel extends model
|
||||
foreach($programs as $programID => $program)
|
||||
{
|
||||
$program->teamCount = isset($teams[$programID]) ? $teams[$programID]->count : 0;
|
||||
$program->consumed = isset($consumes[$programID]) ? $consumes[$programID] : 0;
|
||||
$program->leftTasks = isset($leftTasks[$programID]) ? $leftTasks[$programID] : 0;
|
||||
$program->leftStories = isset($leftStories[$programID]) ? $leftStories[$programID] : 0;
|
||||
$program->leftBugs = isset($leftBugs[$programID]) ? $leftBugs[$programID] : 0;
|
||||
$program->consumed = isset($hours[$programID]) ? $hours[$programID]->consumed : 0;
|
||||
$program->estimate = isset($hours[$programID]) ? $hours[$programID]->estimate : 0;
|
||||
$program->leftTasks = isset($leftTasks[$programID]) ? $leftTasks[$programID]->leftTasks : 0;
|
||||
$program->allStories = isset($allStories[$programID]) ? $allStories[$programID]->allStories : 0;
|
||||
$program->doneStories = isset($doneStories[$programID]) ? $doneStories[$programID]->doneStories : 0;
|
||||
$program->leftStories = isset($leftStories[$programID]) ? $leftStories[$programID]->leftStories : 0;
|
||||
$program->leftBugs = isset($leftBugs[$programID]) ? $leftBugs[$programID]->leftBugs : 0;
|
||||
}
|
||||
|
||||
return $programs;
|
||||
@@ -166,9 +215,14 @@ class programModel extends model
|
||||
die(js::locate('back'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a program.
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->lang->project->team = $this->lang->project->teamname;
|
||||
$project = fixer::input('post')
|
||||
->setDefault('status', 'wait')
|
||||
->add('type', 'program')
|
||||
@@ -178,14 +232,14 @@ class programModel extends model
|
||||
->setDefault('team', substr($this->post->name,0, 30))
|
||||
->join('whitelist', ',')
|
||||
->cleanInt('budget')
|
||||
->stripTags($this->config->project->editor->create['id'], $this->config->allowedTags)
|
||||
->stripTags($this->config->program->editor->create['id'], $this->config->allowedTags)
|
||||
->remove('products, workDays, delta, branch, uid, plans')
|
||||
->get();
|
||||
|
||||
$project = $this->loadModel('file')->processImgURL($project, $this->config->project->editor->create['id'], $this->post->uid);
|
||||
$project = $this->loadModel('file')->processImgURL($project, $this->config->program->editor->create['id'], $this->post->uid);
|
||||
$this->dao->insert(TABLE_PROJECT)->data($project)
|
||||
->autoCheck()
|
||||
->batchcheck($this->config->project->create->requiredFields, 'notempty')
|
||||
->batchcheck($this->config->program->create->requiredFields, 'notempty')
|
||||
->check('name', 'unique', "deleted='0'")
|
||||
->check('code', 'unique', "deleted='0'")
|
||||
->exec();
|
||||
@@ -249,6 +303,67 @@ class programModel extends model
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update program.
|
||||
*
|
||||
* @param int $programID
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function update($programID)
|
||||
{
|
||||
$programID = (int)$programID;
|
||||
$oldProgram = $this->dao->findById($programID)->from(TABLE_PROJECT)->fetch();
|
||||
|
||||
$program = fixer::input('post')
|
||||
->setIF($this->post->begin == '0000-00-00', 'begin', '')
|
||||
->setIF($this->post->end == '0000-00-00', 'end', '')
|
||||
->setIF($this->post->acl != 'custom', 'whitelist', '')
|
||||
->setIF($this->post->acl == 'custom' and !isset($_POST['whitelist']), 'whitelist', '')
|
||||
->setDefault('team', $this->post->name)
|
||||
->join('whitelist', ',')
|
||||
->stripTags($this->config->program->editor->edit['id'], $this->config->allowedTags)
|
||||
->remove('products, branch, uid, plans')
|
||||
->get();
|
||||
$program = $this->loadModel('file')->processImgURL($program, $this->config->program->editor->edit['id'], $this->post->uid);
|
||||
|
||||
$this->dao->update(TABLE_PROJECT)->data($program)
|
||||
->autoCheck($skipFields = 'begin,end')
|
||||
->batchcheck($this->config->program->edit->requiredFields, 'notempty')
|
||||
->checkIF($program->begin != '', 'begin', 'date')
|
||||
->checkIF($program->end != '', 'end', 'date')
|
||||
->checkIF($program->end != '', 'end', 'gt', $program->begin)
|
||||
->check('name', 'unique', "id!=$programID and deleted='0'")
|
||||
->check('code', 'unique', "id!=$programID and deleted='0'")
|
||||
->where('id')->eq($programID)
|
||||
->limit(1)
|
||||
->exec();
|
||||
|
||||
if(!dao::isError())
|
||||
{
|
||||
$this->file->updateObjectID($this->post->uid, $programID, 'project');
|
||||
if($program->acl != 'open' and ($program->acl != $oldProject->acl or $program->whitelist != $oldProgram->whitelist))
|
||||
{
|
||||
$this->loadModel('user')->updateUserView($programID, 'program');
|
||||
}
|
||||
|
||||
if($oldProgram->parent != $program->parent) $this->moveNode($programID, $program->parent, $oldProgram->path, $oldProgram->grade);
|
||||
|
||||
return common::createChanges($oldProgram, $program);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get program swapper.
|
||||
*
|
||||
* @param object $programs
|
||||
* @param int $programID
|
||||
* @param varchar $currentModule
|
||||
* @param varchar $currentMethod
|
||||
* @param varchar $extra
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
public function getSwapper($programs, $programID, $currentModule, $currentMethod, $extra = '')
|
||||
{
|
||||
$this->loadModel('project');
|
||||
@@ -270,24 +385,34 @@ class programModel extends model
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Judge an action is clickable or not.
|
||||
*
|
||||
* @param object $project
|
||||
* @param string $action
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public static function isClickable($project, $action)
|
||||
{
|
||||
$action = strtolower($action);
|
||||
|
||||
if($action == 'start') return $project->status == 'wait' or $project->status == 'suspended';
|
||||
if($action == 'finish') return $project->status == 'wait' or $project->status == 'doing';
|
||||
if($action == 'close') return $project->status != 'closed';
|
||||
if($action == 'suspend') return $project->status == 'wait' or $project->status == 'doing';
|
||||
if($action == 'activate') return $project->status == 'done';
|
||||
if($action == 'start') return $program->status == 'wait' or $program->status == 'suspended';
|
||||
if($action == 'finish') return $program->status == 'wait' or $program->status == 'doing';
|
||||
if($action == 'close') return $program->status != 'closed';
|
||||
if($action == 'suspend') return $program->status == 'wait' or $program->status == 'doing';
|
||||
if($action == 'activate') return $program->status == 'done';
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getProducts($program)
|
||||
{
|
||||
return $this->dao->select('*')->from(TABLE_PRODUCT)->where('project')->eq($program)->fetchAll('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check has content for program
|
||||
*
|
||||
* @param int $programID
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function checkHasContent($programID)
|
||||
{
|
||||
$count = 0;
|
||||
@@ -312,6 +437,13 @@ class programModel extends model
|
||||
return $count > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set program tree path.
|
||||
*
|
||||
* @param int $programID
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function setTreePath($programID)
|
||||
{
|
||||
$program = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($programID)->fetch();
|
||||
@@ -327,5 +459,69 @@ class programModel extends model
|
||||
$path['grade'] = $parent->grade + 1;
|
||||
}
|
||||
$this->dao->update(TABLE_PROJECT)->set('path')->eq($path['path'])->set('grade')->eq($path['grade'])->where('id')->eq($program->id)->exec();
|
||||
return !dao::isError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get program parent pairs
|
||||
*
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getParentPairs()
|
||||
{
|
||||
$stmt = $this->dao->select('id,name,parent,path,grade')->from(TABLE_PROJECT)->where('isCat')->eq(1)->andWhere('deleted')->eq(0)->orderBy('grade, `order`')->query();
|
||||
|
||||
$pairs = array();
|
||||
$pairs[0] = '/';
|
||||
while($program = $stmt->fetch())
|
||||
{
|
||||
if($program->grade == 1)
|
||||
{
|
||||
$pairs[$program->id] = '/' . $program->name;
|
||||
continue;
|
||||
}
|
||||
|
||||
$programName = '/' . $program->name;
|
||||
$pairs[$program->id] = isset($pairs[$program->parent]) ? $pairs[$program->parent] . $programName : $programName;
|
||||
}
|
||||
|
||||
return $pairs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move project node.
|
||||
*
|
||||
* @param int $programID
|
||||
* @param int $parentID
|
||||
* @param string $oldPath
|
||||
* @param int $oldGrade
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function moveNode($programID, $parentID, $oldPath, $oldGrade)
|
||||
{
|
||||
$parent = $this->dao->select('id,parent,path,grade')->from(TABLE_PROJECT)->where('id')->eq($parentID)->fetch();
|
||||
|
||||
$childNodes = $this->dao->select('id,parent,path,grade')->from(TABLE_PROJECT)
|
||||
->where('path')->like("{$oldPath}%")
|
||||
->andWhere('deleted')->eq(0)
|
||||
->andWhere('template')->ne('')
|
||||
->orderBy('grade')
|
||||
->fetchAll();
|
||||
/* Process child node path and grade field. */
|
||||
foreach($childNodes as $childNode)
|
||||
{
|
||||
$path = substr($childNode->path, strpos($childNode->path, ",{$programID},"));
|
||||
$grade = $oldGrade - $childNode->grade + 1;
|
||||
if($parent)
|
||||
{
|
||||
$path = rtrim($parent->path, ',') . $path;
|
||||
$grade = $parent->grade + $grade;
|
||||
}
|
||||
$this->dao->update(TABLE_PROJECT)->set('path')->eq($path)->set('grade')->eq($grade)->where('id')->eq($childNode->id)->exec();
|
||||
}
|
||||
|
||||
return !dao::isError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* The create view of project module of ZenTaoPMS.
|
||||
* The edit view of program module of ZenTaoPMS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv12.html)
|
||||
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
|
||||
* @package project
|
||||
* @package program
|
||||
* @version $Id: create.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
@@ -20,47 +20,52 @@
|
||||
</div>
|
||||
<form class='form-indicator main-form form-ajax' method='post' target='hiddenwin' id='dataform'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th class='w-120px'><?php echo $lang->program->parent;?></th>
|
||||
<td class="col-main"><?php echo html::select('parent', $parents, $program->parent, "class='form-control chosen'");?></td>
|
||||
<td></td><td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class='w-120px'><?php echo $lang->program->name;?></th>
|
||||
<td class="col-main"><?php echo html::input('name', $project->name, "class='form-control' required");?></td>
|
||||
<td class="col-main"><?php echo html::input('name', $program->name, "class='form-control' required");?></td>
|
||||
<td></td><td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->program->code;?></th>
|
||||
<td><?php echo html::input('code', $project->code, "class='form-control' required");?></td><td></td><td></td>
|
||||
<td><?php echo html::input('code', $program->code, "class='form-control' required");?></td><td></td><td></td>
|
||||
</tr>
|
||||
<?php if($project->template == 'cmmi'):?>
|
||||
<?php if($program->template == 'cmmi'):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->program->category;?></th>
|
||||
<td><?php echo html::select('category', $lang->program->categoryList, $project->category, "class='form-control'");?></td><td></td><td></td>
|
||||
<td><?php echo html::select('category', $lang->program->categoryList, $program->category, "class='form-control'");?></td><td></td><td></td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<tr>
|
||||
<th><?php echo $lang->program->PM;?></th>
|
||||
<td><?php echo html::select('PM', $pmUsers, $project->PM, "class='form-control chosen'");?></td>
|
||||
<td><?php echo html::select('PM', $pmUsers, $program->PM, "class='form-control chosen'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->program->budget;?></th>
|
||||
<td><?php echo html::input('budget', $project->budget, "class='form-control'");?></td>
|
||||
<td style='float:left'><?php echo html::select('budgetUnit', $lang->program->unitList, $project->budgetUnit, "class='form-control'");?></td><td></td>
|
||||
<td><?php echo html::input('budget', $program->budget, "class='form-control'");?></td>
|
||||
<td style='float:left'><?php echo html::select('budgetUnit', $lang->program->unitList, $program->budgetUnit, "class='form-control'");?></td><td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->program->dateRange;?></th>
|
||||
<td>
|
||||
<div class='input-group'>
|
||||
<?php echo html::input('begin', $project->begin, "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->program->begin . "' required");?>
|
||||
<?php echo html::input('begin', $program->begin, "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->program->begin . "' required");?>
|
||||
<span class='input-group-addon'><?php echo $lang->program->to;?></span>
|
||||
<?php echo html::input('end', $project->end, "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->program->end . "' required");?>
|
||||
<?php echo html::input('end', $program->end, "class='form-control form-date' onchange='computeWorkDays();' placeholder='" . $lang->program->end . "' required");?>
|
||||
</div>
|
||||
</td>
|
||||
<td colspan='2'></td>
|
||||
</tr>
|
||||
<?php if($project->template == 'scrum'):?>
|
||||
<?php if($program->template == 'scrum'):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->project->days;?></th>
|
||||
<td>
|
||||
<div class='input-group'>
|
||||
<?php echo html::input('days', $project->days, "class='form-control'");?>
|
||||
<?php echo html::input('days', $program->days, "class='form-control'");?>
|
||||
<span class='input-group-addon'><?php echo $lang->project->day;?></span>
|
||||
</div>
|
||||
</td><td></td><td></td>
|
||||
@@ -68,30 +73,30 @@
|
||||
<?php endif;?>
|
||||
<tr>
|
||||
<th><?php echo $lang->program->realStarted;?></th>
|
||||
<td><?php echo html::input('realStarted', $project->realStarted, "class='form-control form-date'");?></td><td></td><td></td>
|
||||
<td><?php echo html::input('realStarted', $program->realStarted, "class='form-control form-date'");?></td><td></td><td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->project->teamname;?></th>
|
||||
<td><?php echo html::input('team', $project->team, "class='form-control'");?></td><td></td><td></td>
|
||||
<td><?php echo html::input('team', $program->team, "class='form-control'");?></td><td></td><td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->program->desc;?></th>
|
||||
<td colspan='3'>
|
||||
<?php echo $this->fetch('user', 'ajaxPrintTemplates', 'type=project&link=desc');?>
|
||||
<?php echo html::textarea('desc', $project->desc, "rows='6' class='form-control kindeditor' hidefocus='true'");?>
|
||||
<?php echo $this->fetch('user', 'ajaxPrintTemplates', 'type=program&link=desc');?>
|
||||
<?php echo html::textarea('desc', $program->desc, "rows='6' class='form-control kindeditor' hidefocus='true'");?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->program->privway;?></th>
|
||||
<td colspan='3'><?php echo html::radio('privway', $lang->program->privwayList, $project->privway, '', 'block');?></td>
|
||||
<td colspan='3'><?php echo html::radio('privway', $lang->program->privwayList, $program->privway, '', 'block');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->project->acl;?></th>
|
||||
<td colspan='3'><?php echo nl2br(html::radio('acl', $lang->program->aclList, $project->acl, "onclick='setWhite(this.value);'", 'block'));?></td>
|
||||
<td colspan='3'><?php echo nl2br(html::radio('acl', $lang->program->aclList, $program->acl, "onclick='setWhite(this.value);'", 'block'));?></td>
|
||||
</tr>
|
||||
<tr id='whitelistBox' <?php if($project->acl != 'custom') echo "class='hidden'";?>>
|
||||
<tr id='whitelistBox' <?php if($program->acl != 'custom') echo "class='hidden'";?>>
|
||||
<th><?php echo $lang->project->whitelist;?></th>
|
||||
<td colspan='3'><?php echo html::checkbox('whitelist', $groups, $project->whitelist, '', '', 'inline');?></td>
|
||||
<td colspan='3'><?php echo html::checkbox('whitelist', $groups, $program->whitelist, '', '', 'inline');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan='4' class='text-center form-actions'>
|
||||
|
||||
@@ -3804,6 +3804,7 @@ class upgradeModel extends model
|
||||
if(dao::isError()) return false;
|
||||
|
||||
$programID = $this->dao->lastInsertId();
|
||||
$this->dao->update(TABLE_PROJECT)->set('grade')->eq(1)->set('path')->eq(",{$programID},")->where('id')->eq($programID)->exec();
|
||||
|
||||
if($pgmAdmins)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user