Merge branch 'master' into 'importExport'
# Conflicts: # module/port/model.php
This commit is contained in:
@@ -263,12 +263,11 @@ class dao extends baseDAO
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!isset($this->sqlobj->data->{$field->field})) $this->sqlobj->data->{$field->field} = false;
|
||||
|
||||
/* Check rules of fields. */
|
||||
foreach($field->ruleData as $rule)
|
||||
{
|
||||
if(empty($rule)) continue;
|
||||
if(!isset($this->sqlobj->data->{$field->field})) continue;
|
||||
|
||||
if($rule->type == 'system')
|
||||
{
|
||||
|
||||
@@ -50,7 +50,7 @@ class actionModel extends model
|
||||
$action->extra = $extra;
|
||||
if(!defined('IN_UPGRADE')) $action->vision = $this->config->vision;
|
||||
|
||||
if($objectType == 'story' and strpos(',reviewpassed,reviewrejected,reviewclarified,', ",$actionType,") !== false) $action->actor = $this->lang->action->system;
|
||||
if($objectType == 'story' and strpos(',reviewpassed,reviewrejected,reviewclarified,reviewreverted,', ",$actionType,") !== false) $action->actor = $this->lang->action->system;
|
||||
|
||||
/* Use purifier to process comment. Fix bug #2683. */
|
||||
$action->comment = fixer::stripDataTags($comment);
|
||||
|
||||
@@ -1208,14 +1208,14 @@ class block extends control
|
||||
|
||||
$this->weekly->save($this->session->project, $date);
|
||||
|
||||
$this->view->pv = $this->weekly->getPV($this->session->project, $today);
|
||||
$this->view->ev = $this->weekly->getEV($this->session->project, $today);
|
||||
$this->view->ac = $this->weekly->getAC($this->session->project, $today);
|
||||
$this->view->pv = (float)$this->weekly->getPV($this->session->project, $today);
|
||||
$this->view->ev = (float)$this->weekly->getEV($this->session->project, $today);
|
||||
$this->view->ac = (float)$this->weekly->getAC($this->session->project, $today);
|
||||
$this->view->sv = $this->weekly->getSV($this->view->ev, $this->view->pv);
|
||||
$this->view->cv = $this->weekly->getCV($this->view->ev, $this->view->ac);
|
||||
|
||||
$this->view->current = $current;
|
||||
$this->view->progress = ($task->totalConsumed + $task->totalLeft) ? floor($task->totalConsumed / ($task->totalConsumed + $task->totalLeft) * 1000) / 1000 * 100 : 0;
|
||||
$this->view->progress = !empty($this->view->pv) ? floor($this->view->ac / $this->view->pv * 1000) / 1000 * 100 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,6 +37,7 @@ if(!$selfCall) die(include('./todolist.html.php'));
|
||||
.block-todoes .todo-flexbetween {display: flex; justify-content: space-between;}
|
||||
.block-todoes #todoList {display: flex; overflow: hidden;}
|
||||
.block-todoes .label-todo {width: 50px; min-width: 50px!important; border: none; color: #43A047;}
|
||||
.block-todoes .todo-title.text-ellipsis {text-overflow: unset;}
|
||||
[lang^='en'] .block-todoes .todo-pri {width: 60px; min-width: 60px;}
|
||||
</style>
|
||||
<div class='block-todoes'>
|
||||
@@ -93,29 +94,31 @@ if(!$selfCall) die(include('./todolist.html.php'));
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<ul class="todoes">
|
||||
<?php foreach($todos as $id => $todo):?>
|
||||
<?php
|
||||
$appid = isset($_GET['entry']) ? "class='app-btn' data-id='{$this->get->entry}'" : '';
|
||||
$viewLink = $this->createLink('todo', 'view', "todoID={$todo->id}&from=my", 'html', true);
|
||||
?>
|
||||
<li data-id='<?php echo $todo->id?>' class='titleBox'>
|
||||
<span class="todo-check icon icon-check-circle"></span>
|
||||
<a href="<?php echo empty($sso) ? $viewLink : $sso . $sign . 'referer=' . base64_encode($viewLink);?>" class='iframe todo-flexbetween' data-width='1000px' data-toggle='modal' <?php echo $appid?>>
|
||||
<div id='todoList'>
|
||||
<?php if ($todo->date == '2030-01-01') :?>
|
||||
<div class="todo-time"><?php echo $lang->todo->periods['future'] ?></div>
|
||||
<?php else:?>
|
||||
<div class="todo-time"><?php echo date(DT_DATE4, strtotime($todo->date)) . ' ' . $todo->begin;?></div>
|
||||
<?php endif;?>
|
||||
<div class="todo-pri label-pri label-pri-<?php echo $todo->pri?>" title="<?php echo zget($lang->todo->priList, $todo->pri);?>"><?php echo zget($lang->todo->priList, $todo->pri);?></div>
|
||||
<div class="todo-title text-ellipsis" title='<?php echo $todo->name;?>'><?php echo $todo->name;?></div>
|
||||
</div>
|
||||
<span class="label label-id label-todo hidden"><?php echo $lang->block->done;?></span>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach;?>
|
||||
</ul>
|
||||
<div class='table-row'>
|
||||
<ul class="todoes">
|
||||
<?php foreach($todos as $id => $todo):?>
|
||||
<?php
|
||||
$appid = isset($_GET['entry']) ? "class='app-btn' data-id='{$this->get->entry}'" : '';
|
||||
$viewLink = $this->createLink('todo', 'view', "todoID={$todo->id}&from=my", 'html', true);
|
||||
?>
|
||||
<li data-id='<?php echo $todo->id?>' class='titleBox'>
|
||||
<span class="todo-check icon icon-check-circle"></span>
|
||||
<a href="<?php echo empty($sso) ? $viewLink : $sso . $sign . 'referer=' . base64_encode($viewLink);?>" class='iframe todo-flexbetween' data-width='1000px' data-toggle='modal' <?php echo $appid?>>
|
||||
<div id='todoList'>
|
||||
<?php if ($todo->date == '2030-01-01') :?>
|
||||
<div class="todo-time"><?php echo $lang->todo->periods['future'] ?></div>
|
||||
<?php else:?>
|
||||
<div class="todo-time"><?php echo date(DT_DATE4, strtotime($todo->date)) . ' ' . $todo->begin;?></div>
|
||||
<?php endif;?>
|
||||
<div class="todo-pri label-pri label-pri-<?php echo $todo->pri?>" title="<?php echo zget($lang->todo->priList, $todo->pri);?>"><?php echo zget($lang->todo->priList, $todo->pri);?></div>
|
||||
<div class="todo-title text-ellipsis" title='<?php echo $todo->name;?>'><?php echo $todo->name;?></div>
|
||||
</div>
|
||||
<span class="label label-id label-todo hidden"><?php echo $lang->block->done;?></span>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach;?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(function()
|
||||
@@ -150,6 +153,7 @@ if(!$selfCall) die(include('./todolist.html.php'));
|
||||
$block.on('click', '.todo-form-trigger', function()
|
||||
{
|
||||
toggleForm($(this).data('trigger'));
|
||||
$('.block-todoes .commitButton').removeClass('disabled');
|
||||
});
|
||||
$form.timeSpanControl(
|
||||
{
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<div class="panel-body conatiner-fluid">
|
||||
<div class='table-row'>
|
||||
<div class="col col-left hide-in-sm">
|
||||
<h4><?php echo $lang->project->progress;?></h4>
|
||||
<h4><?php echo $lang->project->weekProgress;?></h4>
|
||||
<span class='progress-num'><?php echo $progress . '%';?></span>
|
||||
<div class="progress">
|
||||
<div class="progress-bar" role="progressbar" aria-valuenow="<?php echo $progress;?>" aria-valuemin="0" aria-valuemax="100" style="width: <?php echo $progress;?>%">
|
||||
|
||||
@@ -56,7 +56,7 @@ $config->bug->custom->createFields = $config->bug->list->customCreateFields
|
||||
$config->bug->custom->batchCreateFields = 'project,execution,deadline,steps,type,severity,os,browser,%s';
|
||||
$config->bug->custom->batchEditFields = 'type,severity,pri,assignedTo,deadline,status,resolvedBy,resolution';
|
||||
|
||||
$config->bug->excludeCheckFileds = ',severities,oses,browsers,';
|
||||
$config->bug->excludeCheckFileds = ',severities,oses,browsers,lanes,regions,executions,projects,';
|
||||
|
||||
$config->bug->editor = new stdclass();
|
||||
$config->bug->editor->create = array('id' => 'steps', 'tools' => 'bugTools');
|
||||
|
||||
@@ -364,7 +364,7 @@ class bug extends control
|
||||
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$response['result'] = 'success';
|
||||
$response['result'] = 'success';
|
||||
|
||||
/* Set from param if there is a object to transfer bug. */
|
||||
setcookie('lastBugModule', (int)$this->post->module, $this->config->cookieLife, $this->config->webRoot, '', $this->config->cookieSecure, false);
|
||||
|
||||
@@ -2458,11 +2458,11 @@ EOD;
|
||||
{
|
||||
if($this->app->getViewType() != 'html' or helper::isAjaxRequest() or isset($_GET['_single'])) return;
|
||||
|
||||
if(isset($_SERVER['HTTP_SEC_FETCH_DEST']))
|
||||
if(isset($_SERVER['HTTP_SEC_FETCH_DEST']) and $_SERVER['HTTP_SEC_FETCH_DEST'] == 'iframe')
|
||||
{
|
||||
if($_SERVER['HTTP_SEC_FETCH_DEST'] == 'iframe') return;
|
||||
return;
|
||||
}
|
||||
else if((isset($_SERVER['HTTP_REFERER']) and !empty($_SERVER['HTTP_REFERER'])) or strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'safari') !== false)
|
||||
elseif((isset($_SERVER['HTTP_REFERER']) and !empty($_SERVER['HTTP_REFERER'])) or strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'safari') !== false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -107,8 +107,8 @@ class company extends control
|
||||
return print(js::reload('parent.parent'));
|
||||
}
|
||||
|
||||
$this->view->title = $this->lang->company->common . $this->lang->colon . $this->lang->company->create;
|
||||
$this->view->position = $this->lang->company->create;
|
||||
$this->view->title = $this->lang->company->common . $this->lang->colon . $this->lang->company->create;
|
||||
$this->view->position = $this->lang->company->create;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
@@ -136,9 +136,9 @@ class company extends control
|
||||
$this->company->setMenu();
|
||||
$title = $this->lang->company->common . $this->lang->colon . $this->lang->company->edit;
|
||||
$position[] = $this->lang->company->edit;
|
||||
$this->view->title = $title;
|
||||
$this->view->position = $position;
|
||||
$this->view->company = $this->company->getById($this->app->company->id);
|
||||
$this->view->title = $title;
|
||||
$this->view->position = $position;
|
||||
$this->view->company = $this->company->getById($this->app->company->id);
|
||||
|
||||
$this->display();
|
||||
}
|
||||
@@ -253,8 +253,8 @@ class company extends control
|
||||
/* Get actions. */
|
||||
if($browseType != 'bysearch')
|
||||
{
|
||||
if(!$productID) $productID = 'all';
|
||||
if(!$projectID) $projectID = 'all';
|
||||
if(!$productID) $productID = 'all';
|
||||
if(!$projectID) $projectID = 'all';
|
||||
if(!$executionID) $executionID = 'all';
|
||||
$actions = $this->action->getDynamic($account, $browseType, $orderBy, $pager, $productID, $projectID, $executionID, $date, $direction);
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ class companyModel extends model
|
||||
/**
|
||||
* Get users.
|
||||
*
|
||||
* @param string $browseType
|
||||
* @param string $type
|
||||
* @param int $queryID
|
||||
* @param int $deptID
|
||||
|
||||
@@ -113,14 +113,8 @@ class deptModel extends model
|
||||
krsort($deptMenu);
|
||||
$topMenu = array_pop($deptMenu);
|
||||
$topMenu = explode("\n", trim((string)$topMenu));
|
||||
if($this->app->tab == 'report')
|
||||
{
|
||||
$lastMenu[] = '/' . $this->lang->dept->noDepartment;
|
||||
}
|
||||
else
|
||||
{
|
||||
$lastMenu[] = '/';
|
||||
}
|
||||
|
||||
$lastMenu[] = '/';
|
||||
foreach($topMenu as $menu)
|
||||
{
|
||||
if(!strpos($menu, '|')) continue;
|
||||
|
||||
+51
-57
@@ -154,85 +154,79 @@ class devModel extends model
|
||||
foreach($methods as $method)
|
||||
{
|
||||
if($method->class == 'baseControl' or $method->class == 'control' or $method->name == '__construct') continue;
|
||||
$api = array('name' => $method->name, 'post' => false, 'default' => array());
|
||||
$api = array('name' => $method->name, 'post' => false, 'param' => array());
|
||||
$methodReflect = new ReflectionMethod($module, $method->name);
|
||||
foreach($methodReflect->getParameters() as $key => $param)
|
||||
{
|
||||
try
|
||||
{
|
||||
$api['default'][$param->getName()] = $param->getDefaultValue();
|
||||
}catch(ReflectionException $e){}
|
||||
$paramName = $param->getName();
|
||||
$api['param'][$paramName] = array('var' => $paramName, 'type' => '', 'desc' => '');
|
||||
}
|
||||
|
||||
$startLine = $methodReflect->getStartLine();
|
||||
$endLine = $methodReflect->getEndLine();
|
||||
$comment = $methodReflect->getDocComment();
|
||||
|
||||
$file = file($fileName);
|
||||
for($i = $startLine - 1; $i <= $endLine; $i++)
|
||||
if($startLine > 0)
|
||||
{
|
||||
if(strpos($file[$i], '$this->post') or strpos($file[$i], 'fixer::input') or strpos($file[$i], '$_POST'))
|
||||
$file = file($fileName);
|
||||
for($i = $startLine - 1; $i <= $endLine; $i++)
|
||||
{
|
||||
$api['post'] = true;
|
||||
if(strpos($file[$i], '$this->post') or strpos($file[$i], 'fixer::input') or strpos($file[$i], '$_POST')) $api['post'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Strip the opening and closing tags of the docblock.
|
||||
$comment = substr($comment, 3, -2);
|
||||
|
||||
// Split into arrays of lines.
|
||||
$comment = preg_split('/\r?\n\r?/', $comment);
|
||||
|
||||
// Trim asterisks and whitespace from the beginning and whitespace from the end of lines.
|
||||
$comment = array_map(array('devModel', "trimSpace"), $comment);
|
||||
|
||||
// Group the lines together by @tags
|
||||
$blocks = array();
|
||||
$b = -1;
|
||||
foreach ($comment as $line)
|
||||
if($comment)
|
||||
{
|
||||
if (isset($line[1]) && $line[0] == '@' && ctype_alpha($line[1]))
|
||||
{
|
||||
$b++;
|
||||
$blocks[] = array();
|
||||
}
|
||||
else if($b == -1)
|
||||
{
|
||||
$b = 0;
|
||||
$blocks[] = array();
|
||||
}
|
||||
$blocks[$b][] = $line;
|
||||
}
|
||||
// Strip the opening and closing tags of the docblock.
|
||||
$comment = substr($comment, 3, -2);
|
||||
|
||||
// Parse the blocks
|
||||
foreach ($blocks as $block => $body)
|
||||
{
|
||||
$body = trim(implode("\n", $body));
|
||||
if($block == 0 && !(isset($body[1]) && $body[0] == '@' && ctype_alpha($body[1])))
|
||||
// Split into arrays of lines.
|
||||
$comment = preg_split('/\r?\n\r?/', $comment);
|
||||
|
||||
// Trim asterisks and whitespace from the beginning and whitespace from the end of lines.
|
||||
$comment = array_map(array('devModel', "trimSpace"), $comment);
|
||||
|
||||
// Group the lines together by @tags
|
||||
$blocks = array();
|
||||
$b = -1;
|
||||
foreach($comment as $line)
|
||||
{
|
||||
// This is the description block
|
||||
$api['desc'] = $body;
|
||||
continue;
|
||||
if(isset($line[1]) && $line[0] == '@' && ctype_alpha($line[1])) $b++;
|
||||
if($b == -1) $b = 0;
|
||||
|
||||
if(!isset($blocks[$b])) $blocks[$b] = array();
|
||||
$blocks[$b][] = $line;
|
||||
}
|
||||
else
|
||||
|
||||
// Parse the blocks
|
||||
foreach($blocks as $block => $body)
|
||||
{
|
||||
$body = trim(implode("\n", $body));
|
||||
if($block == 0 && !(isset($body[1]) && $body[0] == '@' && ctype_alpha($body[1])))
|
||||
{
|
||||
// This is the description block
|
||||
$api['desc'] = $body;
|
||||
continue;
|
||||
}
|
||||
|
||||
// This block is tagged
|
||||
if(preg_match('/^@[a-z0-9_]+/', $body, $matches))
|
||||
{
|
||||
$tag = substr($matches[0], 1);
|
||||
$body = substr($body, strlen($tag)+2);
|
||||
if($tag == 'param')
|
||||
{
|
||||
$parts = preg_split('/\s+/', trim($body), 3);
|
||||
$parts = array_pad($parts, 3, null);
|
||||
$property = array('type', 'var', 'desc');
|
||||
$param = array_combine($property, $parts);
|
||||
$param['var'] = substr($param['var'], 1);
|
||||
$api['param'][] = $param;
|
||||
}
|
||||
else
|
||||
$body = substr($body, strlen($tag) + 2);
|
||||
if($tag != 'param')
|
||||
{
|
||||
$api[$tag][] = $body;
|
||||
continue;
|
||||
}
|
||||
|
||||
$parts = preg_split('/\s+/', trim($body), 3);
|
||||
$parts = array_pad($parts, 3, null);
|
||||
$property = array('type', 'var', 'desc');
|
||||
$param = array_combine($property, $parts);
|
||||
$paramName = substr($param['var'], 1);
|
||||
$param['var'] = $paramName;
|
||||
if(isset($api['param'][$paramName])) $api['param'][$paramName] = $param;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -245,7 +239,7 @@ class devModel extends model
|
||||
* Get all modules.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
* @return array
|
||||
*/
|
||||
public function getModules()
|
||||
{
|
||||
@@ -258,7 +252,7 @@ class devModel extends model
|
||||
$module = basename($module);
|
||||
if($module == 'editor' or $module == 'help' or $module == 'setting' or $module == 'common') continue;
|
||||
$group = zget($this->config->dev->group, $module, 'other');
|
||||
$modules[$group][] = $module;
|
||||
$modules[$group][$module] = $module;
|
||||
}
|
||||
|
||||
$extPaths = $this->getModuleExtPath();
|
||||
@@ -272,7 +266,7 @@ class devModel extends model
|
||||
$module = basename($path);
|
||||
if($module == 'editor' or $module == 'help' or $module == 'setting' or $module == 'common') continue;
|
||||
$group = zget($this->config->dev->group, $module, 'other');
|
||||
$modules[$group][] = $module;
|
||||
$modules[$group][$module] = $module;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
|
||||
#burnWrapper {max-width: 400px; margin: 0 auto; padding: 8px; position: relative;}
|
||||
#burnYUnit {position: absolute; color: #CBD0DB; top: -10px; left: 10px;}
|
||||
#burnLegend {position: absolute; right: 0; width: 80px; height: 40px; top: 0; margin-top: -20px; line-height: 20px; color: #838A9D; font-size: 12px;}
|
||||
#burnLegend > div {position: relative; padding-left: 30px;}
|
||||
#burnLegend {position: absolute; right: 0; width: 150px; top: 0; margin-top: -20px; line-height: 20px; color: #838A9D; font-size: 12px;}
|
||||
#burnLegend > div {position: relative; padding-left: 22px;}
|
||||
#burnLegend > div:before {content: ' '; display: block; position: absolute; width: 20px; left: 0; top: 8px; height: 2px; background: #EEEEEE;}
|
||||
#burnLegend > div.line-real:before {background: #006AF1;}
|
||||
#burnLegend > div.line-delay:before {background: red;}
|
||||
|
||||
.block-dynamic .panel-body {height: 230px; overflow: auto; position: relative;}
|
||||
.block-team div.col-xs-6 {white-space: nowrap; overflow: hidden;}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
#burnLegend {width: 220px;}
|
||||
@@ -0,0 +1 @@
|
||||
#burnLegend {width: 180px;}
|
||||
@@ -70,7 +70,7 @@
|
||||
foreach($modulePath as $key => $module)
|
||||
{
|
||||
$moduleTitle .= $module->name;
|
||||
if(!common::printLink('product', 'browse', "productID=$story->product&branch=$story->branch&browseType=byModule¶m=$module->id", $module->name)) echo $module->name;
|
||||
if(!common::printLink('product', 'browse', "productID=$story->product&branch=$story->branch&browseType=byModule¶m=$module->id", $module->name, '', "data-app='product'")) echo $module->name;
|
||||
if(isset($modulePath[$key + 1]))
|
||||
{
|
||||
$moduleTitle .= '/';
|
||||
|
||||
@@ -24,7 +24,11 @@
|
||||
<div class="col-sm-6">
|
||||
<div class="panel block-burn" style="height: 280px">
|
||||
<div class="panel-heading">
|
||||
<div class="panel-title"><?php echo $execution->name . $lang->execution->burn;?></div>
|
||||
<div class="panel-title"><?php echo $execution->name . $lang->execution->burn;?>
|
||||
<?php if(isset($execution->delay)):?>
|
||||
<span class="label label-danger label-outline"><?php echo $lang->execution->delayed;?></span>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<?php if(common::hasPriv('execution', 'burn')):?>
|
||||
<nav class="panel-actions nav nav-default">
|
||||
<li><?php common::printLink('execution', 'burn', "executionID=$execution->id", '<i class="icon icon-more icon-sm"></i>', '', "title=$lang->more");?></li>
|
||||
@@ -38,9 +42,12 @@
|
||||
<canvas id="burnCanvas"></canvas>
|
||||
</div>
|
||||
<div id="burnYUnit">(<?php echo $lang->execution->workHour;?>)</div>
|
||||
<div id="burnLegend">
|
||||
<div class="line-ref"><?php echo $lang->execution->charts->burn->graph->reference;?></div>
|
||||
<div class="line-real"><?php echo $lang->execution->charts->burn->graph->actuality;?></div>
|
||||
<div id="burnLegend" class='table-row'>
|
||||
<div class="line-ref table-col"><?php echo $lang->execution->charts->burn->graph->reference;?></div>
|
||||
<div class="line-real table-col"><?php echo $lang->execution->charts->burn->graph->actuality;?></div>
|
||||
<?php if(isset($execution->delay)):?>
|
||||
<div class="line-delay table-col"><?php echo $lang->execution->charts->burn->graph->delay;?></div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
|
||||
@@ -1212,9 +1212,8 @@ EOF;
|
||||
$_POST['account'] = $this->app->user->account;
|
||||
$_POST['groups'] = $this->dao->select('`group`')->from(TABLE_USERGROUP)->where('account')->eq($this->post->account)->fetchPairs('group', 'group');
|
||||
$this->user->update($this->app->user->id);
|
||||
if(dao::isError()) helper::end(js::error(dao::getError()));
|
||||
echo js::locate($this->createLink('my', 'profile'), 'parent');
|
||||
return;
|
||||
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('my', 'profile'), 'closeModal' => true));
|
||||
}
|
||||
|
||||
$this->app->loadConfig('user');
|
||||
|
||||
@@ -8,13 +8,17 @@ $(document).ready(function()
|
||||
$('#password1').change(function(){password1Encrypted = false});
|
||||
$('#password2').change(function(){password2Encrypted = false});
|
||||
|
||||
var passwordStrength = 0;
|
||||
$('#submit').click(function()
|
||||
{
|
||||
var password = $('input#originalPassword').val().trim();
|
||||
var password1 = $('input#password1').val().trim();
|
||||
var passwordStrength = computePasswordStrength(password1);
|
||||
var rand = $('input#verifyRand').val();
|
||||
if(!password1Encrypted) $("#passwordLength").val(password1.length);
|
||||
var password = $('input#originalPassword').val().trim();
|
||||
var password1 = $('input#password1').val().trim();
|
||||
var rand = $('input#verifyRand').val();
|
||||
if(!password1Encrypted)
|
||||
{
|
||||
passwordStrength = computePasswordStrength(password1);
|
||||
$("#passwordLength").val(password1.length);
|
||||
}
|
||||
|
||||
if($("form input[name=passwordStrength]").length == 0) $('#submit').after("<input type='hidden' name='passwordStrength' value='0' />");
|
||||
$("form input[name=passwordStrength]").val(passwordStrength);
|
||||
|
||||
@@ -8,12 +8,16 @@ $(document).ready(function()
|
||||
$('#password1').change(function(){password1Encrypted = false});
|
||||
$('#password2').change(function(){password2Encrypted = false});
|
||||
|
||||
var passwordStrength = 0;
|
||||
$('#submit').click(function()
|
||||
{
|
||||
var password = $('input#verifyPassword').val();
|
||||
var password1 = $('input#password1').val();
|
||||
var passwordStrength = computePasswordStrength(password1);
|
||||
if(!password1Encrypted) $("#passwordLength").val(password1.length);
|
||||
var password = $('input#verifyPassword').val();
|
||||
var password1 = $('input#password1').val();
|
||||
if(!password1Encrypted)
|
||||
{
|
||||
passwordStrength = computePasswordStrength(password1);
|
||||
$("#passwordLength").val(password1.length);
|
||||
}
|
||||
|
||||
if($("form input[name=passwordStrength]").length == 0) $('#submit').after("<input type='hidden' name='passwordStrength' value='0' />");
|
||||
$("form input[name=passwordStrength]").val(passwordStrength);
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<th><?php echo $lang->user->newPassword;?></th>
|
||||
<td>
|
||||
<span class='input-group'>
|
||||
<?php echo html::password('password1', '', "class='form-control' onmouseup='checkPassword(this.value)' onkeyup='checkPassword(this.value)' placeholder='" . zget($lang->user->placeholder->passwordStrength, $config->safe->mode, '') . "'");?>
|
||||
<?php echo html::password('password1', '', "class='form-control' onkeyup='checkPassword(this.value)' placeholder='" . zget($lang->user->placeholder->passwordStrength, $config->safe->mode, '') . "'");?>
|
||||
<span class='input-group-addon' id='passwordStrength'></span>
|
||||
</span>
|
||||
</td>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<div class='main-header'>
|
||||
<h2><i class='icon-pencil'></i> <?php echo $lang->my->editProfile;?></h2>
|
||||
</div>
|
||||
<form method='post' target='hiddenwin' id='dataform'>
|
||||
<form method='post' class='form-ajax' id='dataform'>
|
||||
<table class='table table-form'>
|
||||
<caption><?php echo $lang->my->form->lblBasic;?></caption>
|
||||
<tr>
|
||||
@@ -46,7 +46,7 @@
|
||||
<td>
|
||||
<input type='password' style="display:none"> <!-- Disable input password by browser automatically. -->
|
||||
<span class='input-group'>
|
||||
<?php echo html::password('password1', '', "class='form-control disabled-ie-placeholder' onmouseup='checkPassword(this.value)' onkeyup='checkPassword(this.value)' placeholder='" . (!empty($config->safe->mode) ? $lang->user->placeholder->passwordStrength[$config->safe->mode] : '') . "'");?>
|
||||
<?php echo html::password('password1', '', "class='form-control disabled-ie-placeholder' onkeyup='checkPassword(this.value)' placeholder='" . (!empty($config->safe->mode) ? $lang->user->placeholder->passwordStrength[$config->safe->mode] : '') . "'");?>
|
||||
<span class='input-group-addon' id='passwordStrength'></span>
|
||||
</span>
|
||||
</td>
|
||||
|
||||
@@ -219,7 +219,7 @@ class portModel extends model
|
||||
$this->commonActions($model);
|
||||
$datas = fixer::input('post')->get();
|
||||
$objectData = array();
|
||||
foreach ($datas as $field => $data)
|
||||
foreach($datas as $field => $data)
|
||||
{
|
||||
if(is_array($data))
|
||||
{
|
||||
@@ -256,18 +256,18 @@ class portModel extends model
|
||||
|
||||
$fieldList = array();
|
||||
/* build module fieldList. */
|
||||
foreach ($fields as $key => $field)
|
||||
foreach($fields as $key => $field)
|
||||
{
|
||||
$field = trim($field);
|
||||
$modelFieldList = isset($this->modelFieldList[$field]) ? $this->modelFieldList[$field] : array();
|
||||
|
||||
foreach ($portFieldList as $portField => $value)
|
||||
foreach($portFieldList as $portField => $value)
|
||||
{
|
||||
$funcName = 'init' . ucfirst($portField);
|
||||
if((!isset($modelFieldList[$portField])) or $portField == 'title')
|
||||
{
|
||||
$modelFieldList[$portField] = $this->portConfig->fieldList[$portField];
|
||||
if(strpos($this->portConfig->initFunction, $portField) !== false) $modelFieldList[$portField] = $this->$funcName($model, $field);
|
||||
$modelFieldList[$portField] = $this->portConfig->fieldList[$portField];
|
||||
if(strpos($this->portConfig->initFunction, $portField) !== false) $modelFieldList[$portField] = $this->$funcName($model, $field);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,7 +402,7 @@ class portModel extends model
|
||||
if(is_array($values) and $withKey)
|
||||
{
|
||||
unset($values['']);
|
||||
foreach ($values as $key => $value)
|
||||
foreach($values as $key => $value)
|
||||
{
|
||||
$values[$key] = $value . "(#$key)";
|
||||
}
|
||||
@@ -546,7 +546,7 @@ class portModel extends model
|
||||
if(!empty($pairs))
|
||||
{
|
||||
$valuePairs = array();
|
||||
foreach ($values as $key => $value)
|
||||
foreach($values as $key => $value)
|
||||
{
|
||||
if(is_object($value)) $value = get_object_vars($value);
|
||||
|
||||
@@ -583,7 +583,7 @@ class portModel extends model
|
||||
$exportDatas = array();
|
||||
$dataSourceList = array();
|
||||
|
||||
foreach ($fieldList as $key => $field)
|
||||
foreach($fieldList as $key => $field)
|
||||
{
|
||||
$exportDatas['fields'][$key] = $field['title'];
|
||||
if($field['values'])
|
||||
@@ -597,7 +597,7 @@ class portModel extends model
|
||||
|
||||
$exportDatas['user'] = $this->loadModel('user')->getPairs('noclosed|nodeleted|noletter');
|
||||
|
||||
foreach ($rows as $id => $values)
|
||||
foreach($rows as $id => $values)
|
||||
{
|
||||
foreach($values as $field => $value)
|
||||
{
|
||||
|
||||
@@ -930,7 +930,8 @@ class productplanModel extends model
|
||||
->fetchPairs();
|
||||
if(isset($branchPlanPairs[$plan->branch])) $branchPlanPairs[$plan->branch] = $planID;
|
||||
|
||||
$plansOfStory = ',' . implode(',', $branchPlanPairs);
|
||||
$plansOfStory = implode(',', $branchPlanPairs);
|
||||
$plansOfStory = trim($plansOfStory, ',');
|
||||
|
||||
$this->dao->update(TABLE_STORY)->set("plan")->eq($plansOfStory)->where('id')->eq((int)$storyID)->exec();
|
||||
|
||||
|
||||
@@ -101,11 +101,11 @@ $lang->program->noProgram = 'No program.';
|
||||
$lang->program->showClosed = 'Closed programs.';
|
||||
$lang->program->tips = 'If a parent program is selected, the products under the parent program can be associated. If no program is selected for the project, a product with the same name as the project is created and associated with the project by default.';
|
||||
$lang->program->confirmBatchUnlink = "Do you want to batch unlink these stakeholders?";
|
||||
$lang->program->beginLetterParent = 'The start date of the program is < the start date of the parent program:';
|
||||
$lang->program->endGreaterParent = 'The finish date of the program is > the finish date of the parent program:';
|
||||
$lang->program->dateExceedParent = 'The start and finish date of the program was > the start and finish date of the parent program:';
|
||||
$lang->program->beginGreateChild = 'The start date of the program is > the minimum start date of the subprogram or project:';
|
||||
$lang->program->endLetterChild = 'The finish date of the program is < the maximum finish date of the subprogram or project:';
|
||||
$lang->program->beginLetterParent = 'The start date of the program is less than the start date of the parent program:';
|
||||
$lang->program->endGreaterParent = 'The finish date of the program is greater than the finish date of the parent program:';
|
||||
$lang->program->dateExceedParent = 'The start and finish date of the program was greater than the start and finish date of the parent program:';
|
||||
$lang->program->beginGreateChild = 'The start date of the program is greater than the minimum start date of the subprogram or project:';
|
||||
$lang->program->endLetterChild = 'The finish date of the program is less than the maximum finish date of the subprogram or project:';
|
||||
$lang->program->dateExceedChild = 'The start and finish date of the program no longer include the date scope of the subprogram or project:';
|
||||
$lang->program->closeErrorMessage = 'There are subprograms or projects that are not closed';
|
||||
$lang->program->hasChildren = 'It has child programs or projects. You cannot delete it.';
|
||||
|
||||
@@ -101,11 +101,11 @@ $lang->program->noProgram = 'No program.';
|
||||
$lang->program->showClosed = 'Closed';
|
||||
$lang->program->tips = 'If a parent program is selected, the products under the parent program can be associated. If no program is selected for the project, a product with the same name as the project is created and associated with the project by default.';
|
||||
$lang->program->confirmBatchUnlink = "Do you want to batch unlink these stakeholders?";
|
||||
$lang->program->beginLetterParent = 'The start date of the program is < the start date of the parent program:';
|
||||
$lang->program->endGreaterParent = 'The finish date of the program is > the finish date of the parent program:';
|
||||
$lang->program->dateExceedParent = 'The start and finish date of the program was > the start and finish date of the parent program:';
|
||||
$lang->program->beginGreateChild = 'The start date of the program is > the minimum start date of the subprogram or project:';
|
||||
$lang->program->endLetterChild = 'The finish date of the program is < the maximum finish date of the subprogram or project:';
|
||||
$lang->program->beginLetterParent = 'The start date of the program is less than the start date of the parent program:';
|
||||
$lang->program->endGreaterParent = 'The finish date of the program is greater than the finish date of the parent program:';
|
||||
$lang->program->dateExceedParent = 'The start and finish date of the program was greater than the start and finish date of the parent program:';
|
||||
$lang->program->beginGreateChild = 'The start date of the program is greater than the minimum start date of the subprogram or project:';
|
||||
$lang->program->endLetterChild = 'The finish date of the program is less than the maximum finish date of the subprogram or project:';
|
||||
$lang->program->dateExceedChild = 'The start and finish date of the program no longer include the date scope of the subprogram or project:';
|
||||
$lang->program->closeErrorMessage = 'There are subprograms or projects that are not closed';
|
||||
$lang->program->hasChildren = 'The program has a child program or the project exists and can not be deleted.';
|
||||
|
||||
@@ -11,14 +11,17 @@
|
||||
#copyProjectModal a.active {border-color: #00da88; color: #00da88; background-color: #E5FFE6;}
|
||||
#copyProjectModal a.active:after {position: absolute; content: '\e92f'; font-family: ZentaoIcon; font-size: 20px; right: 25px;}
|
||||
#copyProjectModal a.cancel {color: #ff5d5d;}
|
||||
#mainContent td.required:after {right: -4px;}
|
||||
#budget {border-right: 0px;}
|
||||
#budgetUnit {border-left: 0px;}
|
||||
#projectName {display: inline-block; width: 32%;}
|
||||
#productsBox a {border-radius: 2px !important;}
|
||||
#productsBox .col-sm-4 {padding-right: 5px;}
|
||||
#productsBox .addProduct {padding-left: 0px !important;}
|
||||
#productsBox .required:after{right: -6px !important;}
|
||||
#productsBox .required:after {right: -4.5px !important;}
|
||||
#productsBox .addProduct {padding-left: 0px !important; padding-right: 10px;}
|
||||
#productsBox .addProduct.required:after {right: -1px !important;}
|
||||
#productsBox .input-group-addon > div {display: inline-block !important;}
|
||||
#productsBox .required + .text-danger.help-text {position: relative; left: 10px;}
|
||||
#plansBox .row {display: inline-table; width: 102%;}
|
||||
#plansBox .col-sm-4 {float: none; display: inline-block; padding-right: 5px;}
|
||||
#dataform th {vertical-align: top; padding-top: 13px;}
|
||||
|
||||
@@ -6,3 +6,4 @@
|
||||
#endList {vertical-align: top; padding-top: 13px;}
|
||||
#dataform th {vertical-align: top; padding-top: 13px;}
|
||||
#linkPlan {padding-top: 25px !important;}
|
||||
#productsBox .row .col-sm-4.required::after {right: -5px;}
|
||||
|
||||
@@ -149,6 +149,17 @@ function setParentProgram(parentProgram)
|
||||
});
|
||||
|
||||
$('#parent').attr('data-lastSelected', parentProgram);
|
||||
|
||||
if(parentProgram != '0')
|
||||
{
|
||||
$('#productsBox .addProduct .input-group:first').addClass('required');
|
||||
$('#productsBox .row .input-group:first').addClass('required');
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#productsBox .addProduct .input-group').removeClass('required');
|
||||
$('#productsBox .row .input-group').removeClass('required');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -201,6 +212,7 @@ function addNewProduct(obj)
|
||||
|
||||
$('#productTitle').html(manageProducts);
|
||||
}
|
||||
$('#productsBox div + .text-danger.help-text').empty();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -246,7 +258,7 @@ function loadBranches(product)
|
||||
if($('#productsBox .row .input-group:last select:first').val() != 0)
|
||||
{
|
||||
var length = $('#productsBox .row .input-group').size();
|
||||
var $html = $('#productsBox .row .col-sm-4:last').html();
|
||||
var $html = $('#productsBox .row .col-sm-4:last').html().replace('required', '');
|
||||
$('#productsBox .row .col-sm-4:last').find('.input-group-addon').remove();
|
||||
$('#productsBox .row').append('<div class="col-sm-4">' + $html + '</div>');
|
||||
if($('#productsBox .row .input-group:last select').size() >= 2) $('#productsBox .row .input-group:last select:last').remove();
|
||||
|
||||
@@ -120,6 +120,7 @@ $lang->project->estimate = 'Estimates';
|
||||
$lang->project->consume = 'Cost';
|
||||
$lang->project->surplus = 'Left';
|
||||
$lang->project->progress = 'Progress';
|
||||
$lang->project->weekProgress = 'This Week Progress';
|
||||
$lang->project->dateRange = 'Duration';
|
||||
$lang->project->to = ' to ';
|
||||
$lang->project->realBeganAB = 'Actual Begin';
|
||||
|
||||
@@ -120,6 +120,7 @@ $lang->project->estimate = 'Estimates';
|
||||
$lang->project->consume = 'Cost';
|
||||
$lang->project->surplus = 'Left';
|
||||
$lang->project->progress = 'Progress';
|
||||
$lang->project->weekProgress = 'This Week Progress';
|
||||
$lang->project->dateRange = 'Plan Duration';
|
||||
$lang->project->to = ' to ';
|
||||
$lang->project->realBeganAB = 'Actual Begin';
|
||||
|
||||
@@ -120,6 +120,7 @@ $lang->project->estimate = 'Estimates';
|
||||
$lang->project->consume = 'Cost';
|
||||
$lang->project->surplus = 'Left';
|
||||
$lang->project->progress = 'Progress';
|
||||
$lang->project->weekProgress = 'This Week Progress';
|
||||
$lang->project->dateRange = 'Duration';
|
||||
$lang->project->to = ' to ';
|
||||
$lang->project->realBeganAB = 'Actual Begin';
|
||||
|
||||
@@ -120,6 +120,7 @@ $lang->project->estimate = '预计';
|
||||
$lang->project->consume = '消耗';
|
||||
$lang->project->surplus = '剩余';
|
||||
$lang->project->progress = '进度';
|
||||
$lang->project->weekProgress = '本周进度';
|
||||
$lang->project->dateRange = '计划起止日期';
|
||||
$lang->project->to = '至';
|
||||
$lang->project->realBeganAB = '实际开始';
|
||||
|
||||
+15
-18
@@ -289,6 +289,8 @@ class report extends control
|
||||
$this->app->loadLang('task');
|
||||
$this->app->loadLang('bug');
|
||||
$this->app->loadLang('testcase');
|
||||
$this->loadModel('dept');
|
||||
$this->loadModel('user');
|
||||
|
||||
$firstAction = $this->dao->select('*')->from(TABLE_ACTION)->orderBy('id')->limit(1)->fetch();
|
||||
$currentYear = date('Y');
|
||||
@@ -311,38 +313,32 @@ class report extends control
|
||||
}
|
||||
|
||||
/* Get users and depts. */
|
||||
$users = $this->loadModel('user')->getPairs('noletter|useid|noclosed');
|
||||
$users[''] = $this->lang->report->annualData->allUser;
|
||||
|
||||
$depts = $this->loadModel('dept')->getOptionMenu();
|
||||
if($this->app->tab == 'report')
|
||||
{
|
||||
$noDepartment = $depts[0];
|
||||
unset($depts[0]);
|
||||
$depts += array('0' => $noDepartment);
|
||||
}
|
||||
|
||||
$accounts = array();
|
||||
if($userID)
|
||||
{
|
||||
$user = $this->loadModel('user')->getById($userID, 'id');
|
||||
$user = $this->user->getById($userID, 'id');
|
||||
$dept = $user->dept;
|
||||
$users = $this->loadModel('dept')->getDeptUserPairs($dept, 'id');
|
||||
$users = array('' => $this->lang->report->annualData->allUser) + $this->dept->getDeptUserPairs($dept, 'id');
|
||||
$accounts = array($user->account => ($user->realname ? $user->realname : $user->account));
|
||||
}
|
||||
else
|
||||
{
|
||||
$users = $this->loadModel('dept')->getDeptUserPairs($dept, 'id');
|
||||
$users = array('' => $this->lang->report->annualData->allUser) + $users;
|
||||
$accounts = $this->loadModel('dept')->getDeptUserPairs($dept);
|
||||
$users = array('' => $this->lang->report->annualData->allUser) + $this->dept->getDeptUserPairs($dept, 'id');
|
||||
$accounts = $this->dept->getDeptUserPairs($dept);
|
||||
}
|
||||
|
||||
$noDepartment = array('0' => '/' . $this->lang->dept->noDepartment);
|
||||
$depts = $this->dept->getOptionMenu();
|
||||
if(!$this->app->user->admin)
|
||||
{
|
||||
foreach($depts as $id => $name) if($id != $this->app->user->dept) unset($depts[$id]);
|
||||
$depts = ($dept and isset($depts[$dept])) ? array($dept => $depts[$dept]) : $noDepartment;
|
||||
}
|
||||
else
|
||||
{
|
||||
$depts = array('' => $this->lang->report->annualData->allDept) + $depts;
|
||||
|
||||
unset($depts[0]);
|
||||
$depts += $noDepartment;
|
||||
}
|
||||
|
||||
if($accounts) $accounts = array_keys($accounts);
|
||||
@@ -357,6 +353,7 @@ class report extends control
|
||||
{
|
||||
$data['logins'] = $this->report->getUserYearLogins($accounts, $year);
|
||||
}
|
||||
|
||||
$data['actions'] = $this->report->getUserYearActions($accounts, $year);
|
||||
$data['todos'] = $this->report->getUserYearTodos($accounts, $year);
|
||||
$data['contributions'] = $this->report->getUserYearContributions($accounts, $year);
|
||||
@@ -372,7 +369,7 @@ class report extends control
|
||||
|
||||
if(empty($dept) and empty($userID)) $data['statusStat'] = $this->report->getAllTimeStatusStat();
|
||||
|
||||
$this->view->title = sprintf($this->lang->report->annualData->title, ($userID ? zget($users, $userID, '') : ($dept ? substr($depts[$dept], strrpos($depts[$dept], '/') + 1) : $depts[''])), $year);
|
||||
$this->view->title = sprintf($this->lang->report->annualData->title, ($userID ? zget($users, $userID, '') : (($dept !== '') ? substr($depts[$dept], strrpos($depts[$dept], '/') + 1) : $depts[''])), $year);
|
||||
$this->view->data = $data;
|
||||
$this->view->year = $year;
|
||||
$this->view->users = $users;
|
||||
|
||||
+24
-9
@@ -358,18 +358,33 @@ class reportModel extends model
|
||||
$taskGroups[$task->assignedTo][$task->id] = $task;
|
||||
}
|
||||
|
||||
$multiTaskTeams = $this->dao->select('*')->from(TABLE_TASKTEAM)->where('task')->in(array_keys($allTasks))
|
||||
$stmt = $this->dao->select('*')->from(TABLE_TASKTEAM)->where('task')->in(array_keys($allTasks))
|
||||
->beginIF($dept)->andWhere('account')->in(array_keys($deptUsers))->fi()
|
||||
->fetchGroup('account', 'task');
|
||||
foreach($multiTaskTeams as $assignedTo => $multiTasks)
|
||||
->query();
|
||||
$multiTaskTeams = array();
|
||||
while($taskTeam = $stmt->fetch())
|
||||
{
|
||||
foreach($multiTasks as $task)
|
||||
$account = $taskTeam->account;
|
||||
if(!isset($multiTaskTeams[$account][$taskTeam->task]))
|
||||
{
|
||||
$userTask = clone $allTasks[$task->root];
|
||||
$userTask->estimate = $task->estimate;
|
||||
$userTask->consumed = $task->consumed;
|
||||
$userTask->left = $task->left;
|
||||
$taskGroups[$assignedTo][$task->root] = $userTask;
|
||||
$multiTaskTeams[$account][$taskTeam->task] = $taskTeam;
|
||||
}
|
||||
else
|
||||
{
|
||||
$multiTaskTeams[$account][$taskTeam->task]->estimate += $taskTeam->estimate;
|
||||
$multiTaskTeams[$account][$taskTeam->task]->consumed += $taskTeam->consumed;
|
||||
$multiTaskTeams[$account][$taskTeam->task]->left += $taskTeam->left;
|
||||
}
|
||||
}
|
||||
foreach($multiTaskTeams as $assignedTo => $taskTeams)
|
||||
{
|
||||
foreach($taskTeams as $taskTeam)
|
||||
{
|
||||
$userTask = clone $allTasks[$taskTeam->task];
|
||||
$userTask->estimate = $taskTeam->estimate;
|
||||
$userTask->consumed = $taskTeam->consumed;
|
||||
$userTask->left = $taskTeam->left;
|
||||
$taskGroups[$assignedTo][$taskTeam->task] = $userTask;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<div>
|
||||
<ul id='infoList'>
|
||||
<li>
|
||||
<?php echo $userID ? $annualDataLang->logins : ($dept ? $annualDataLang->deptUsers : $annualDataLang->companyUsers);?>
|
||||
<?php echo $userID ? $annualDataLang->logins : ($dept !== '' ? $annualDataLang->deptUsers : $annualDataLang->companyUsers);?>
|
||||
<strong><?php echo $userID ? $data['logins'] : $data['users'];?></strong>
|
||||
</li>
|
||||
<li>
|
||||
@@ -65,7 +65,7 @@
|
||||
}
|
||||
}
|
||||
?>
|
||||
<?php if(!empty($dept) or !empty($userID)):?>
|
||||
<?php if($dept !== '' or !empty($userID)):?>
|
||||
<li>
|
||||
<?php echo $annualDataLang->contributions;?>
|
||||
<strong><?php echo $contributions;?></strong>
|
||||
@@ -75,7 +75,7 @@
|
||||
</div>
|
||||
</section>
|
||||
<section id='actionData'>
|
||||
<header><h2 class='text-holder'><?php echo ((empty($dept) and empty($userID)) ? $annualDataLang->actionData :$annualDataLang->contributionData) . $soFar;?></h2></header>
|
||||
<header><h2 class='text-holder'><?php echo (($dept === '' and empty($userID)) ? $annualDataLang->actionData :$annualDataLang->contributionData) . $soFar;?></h2></header>
|
||||
<div>
|
||||
<ul>
|
||||
<?php foreach($annualDataLang->objectTypeList as $objectType => $objectName):?>
|
||||
@@ -207,7 +207,7 @@
|
||||
</div>
|
||||
<div class='table-header-fixed'>
|
||||
</section>
|
||||
<?php if(empty($dept) and empty($userID)):?>
|
||||
<?php if($dept === '' and empty($userID)):?>
|
||||
<section id='allTimeStatusStat'>
|
||||
<header><h2 class='text-holder'><?php echo $annualDataLang->statusStat;?></h2></header>
|
||||
<div>
|
||||
@@ -287,7 +287,7 @@ $(function()
|
||||
<?php unset($lang->story->statusList['']);?>
|
||||
<?php unset($lang->bug->statusList['']);?>
|
||||
<?php unset($lang->task->statusList['']);?>
|
||||
<?php if(empty($dept) and empty($userID)):?>
|
||||
<?php if($dept === '' and empty($userID)):?>
|
||||
<?php foreach($data['statusStat'] as $objectType => $objectStatusStat):?>
|
||||
<?php
|
||||
$statusStat = array();
|
||||
|
||||
@@ -50,7 +50,7 @@ $config->story->custom->createFields = $config->story->list->customCreateFi
|
||||
$config->story->custom->batchCreateFields = 'module,plan,spec,pri,estimate,review,%s';
|
||||
$config->story->custom->batchEditFields = 'branch,module,plan,estimate,pri,source,stage,closedBy,closedReason';
|
||||
|
||||
$config->story->excludeCheckFileds = ',uploadImage,category,reviewer,reviewDitto,';
|
||||
$config->story->excludeCheckFileds = ',uploadImage,category,reviewer,reviewDitto,lanes,regions,';
|
||||
|
||||
global $lang, $app;
|
||||
$config->story->datatable = new stdclass();
|
||||
|
||||
@@ -753,25 +753,9 @@ class story extends control
|
||||
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$deleteFiles = isset($_POST['deleteFiles']) ? $this->file->getPairs($_POST['deleteFiles'], 'title') : array();
|
||||
$changes = $this->story->update($storyID);
|
||||
$this->story->update($storyID);
|
||||
if(dao::isError()) return print(js::error(dao::getError()));
|
||||
|
||||
$files = $this->file->saveUpload($story->type, $storyID, ",$story->version,");
|
||||
if(empty($files) and $this->post->uid != '' and isset($_SESSION['album']['used'][$this->post->uid])) $files = $this->file->getPairs($_SESSION['album']['used'][$this->post->uid]);
|
||||
|
||||
if($this->post->comment != '' or !empty($changes) or !empty($files) or !empty($deleteFiles))
|
||||
{
|
||||
$action = (!empty($changes) or !empty($files)) ? 'Edited' : 'Commented';
|
||||
$fileAction = empty($files) ? '' : $this->lang->addFiles . join(',', $files) . "\n" ;
|
||||
$fileAction .= empty($deleteFiles) ? '' : $this->lang->deleteFiles . join(',', $deleteFiles) . "\n";
|
||||
$actionID = $this->action->create('story', $storyID, $action, $fileAction . $this->post->comment);
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
|
||||
$editedStory = $this->dao->findById($storyID)->from(TABLE_STORY)->fetch();
|
||||
if(isset($_POST['reviewer']) and $story->status == 'reviewing') $this->story->recordReviewAction($editedStory);
|
||||
}
|
||||
|
||||
$this->executeHooks($storyID);
|
||||
|
||||
if(isonlybody())
|
||||
@@ -1406,16 +1390,9 @@ class story extends control
|
||||
{
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$changes = $this->story->review($storyID);
|
||||
$this->story->review($storyID);
|
||||
if(dao::isError()) return print(js::error(dao::getError()));
|
||||
|
||||
if($changes)
|
||||
{
|
||||
$story = $this->dao->findById($storyID)->from(TABLE_STORY)->fetch();
|
||||
$actionID = $this->story->recordReviewAction($story, $this->post->result, $this->post->closedReason);
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
|
||||
$this->executeHooks($storyID);
|
||||
|
||||
if(isonlybody())
|
||||
@@ -1480,11 +1457,11 @@ class story extends control
|
||||
$reviewers = $this->story->getReviewerPairs($storyID, $story->version);
|
||||
$this->lang->story->resultList = $this->lang->story->reviewResultList;
|
||||
|
||||
if($story->status == 'reviewing' and $story->version == 1) unset($this->lang->story->resultList['revert']);
|
||||
|
||||
if($story->status == 'changing') unset($this->lang->story->resultList['reject']);
|
||||
|
||||
if(count($reviewers) > 1) unset($this->lang->story->resultList['revert']);
|
||||
if($story->status == 'reviewing')
|
||||
{
|
||||
if($story->version == 1) unset($this->lang->story->resultList['revert']);
|
||||
if($story->version > 1) unset($this->lang->story->resultList['reject']);
|
||||
}
|
||||
|
||||
$this->view->title = $this->lang->story->review . "STORY" . $this->lang->colon . $story->title;
|
||||
$this->view->position[] = html::a($this->createLink('product', 'browse', "product=$product->id&branch=$story->branch"), $product->name);
|
||||
|
||||
@@ -39,8 +39,6 @@ function switchShow(result)
|
||||
$('#estimateBox').show();
|
||||
}
|
||||
}
|
||||
|
||||
getStatus('review', "storyID=" + storyID + ",result=" + result);
|
||||
}
|
||||
|
||||
function setStory(reason)
|
||||
|
||||
@@ -321,7 +321,8 @@ $lang->story->action->recalled = array('main' => '$date, recalled b
|
||||
$lang->story->action->closed = array('main' => '$date, geschlossen von <strong>$actor</strong>. Der Grund ist <strong>$extra</strong> $appendLink.', 'extra' => 'reasonList');
|
||||
$lang->story->action->reviewpassed = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>Pass</strong>.');
|
||||
$lang->story->action->reviewrejected = array('main' => '$date, closed by <strong>System</strong>. The reasion is <strong>Rejection</strong>.');
|
||||
$lang->story->action->reviewclarified = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>To Be Clarified</strong>. Please re-initiate the review after changing.');
|
||||
$lang->story->action->reviewclarified = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>To Be Clarified</strong>. Please re-initiate the review after edit.');
|
||||
$lang->story->action->reviewreverted = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>Undo Change</strong>.');
|
||||
$lang->story->action->linked2plan = array('main' => '$date, verknüpft von <strong>$actor</strong> mit Plan <strong>$extra</strong>');
|
||||
$lang->story->action->unlinkedfromplan = array('main' => '$date, Verknüpfung aufgelöst durch <strong>$actor</strong> von Plan <strong>$extra</strong>.');
|
||||
$lang->story->action->linked2execution = array('main' => '$date, verknüpft von <strong>$actor</strong> mit ' . $lang->executionCommon . ' <strong>$extra</strong>.');
|
||||
|
||||
@@ -321,7 +321,8 @@ $lang->story->action->recalled = array('main' => '$date, recalled b
|
||||
$lang->story->action->closed = array('main' => '$date, closed by <strong>$actor</strong>. The reasion is <strong>$extra</strong> $appendLink.', 'extra' => 'reasonList');
|
||||
$lang->story->action->reviewpassed = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>Pass</strong>.');
|
||||
$lang->story->action->reviewrejected = array('main' => '$date, closed by <strong>System</strong>. The reasion is <strong>Rejection</strong>.');
|
||||
$lang->story->action->reviewclarified = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>To Be Clarified</strong>. Please re-initiate the review after changing.');
|
||||
$lang->story->action->reviewclarified = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>To Be Clarified</strong>. Please re-initiate the review after edit.');
|
||||
$lang->story->action->reviewreverted = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>Undo Change</strong>.');
|
||||
$lang->story->action->linked2plan = array('main' => '$date, linked by <strong>$actor</strong> to Plan <strong>$extra</strong>');
|
||||
$lang->story->action->unlinkedfromplan = array('main' => '$date, unlinked by <strong>$actor</strong> from Plan <strong>$extra</strong>.');
|
||||
$lang->story->action->linked2execution = array('main' => '$date, linked by <strong>$actor</strong> to ' . $lang->executionCommon . ' <strong>$extra</strong>.');
|
||||
|
||||
@@ -321,7 +321,8 @@ $lang->story->action->recalled = array('main' => '$date, recalled b
|
||||
$lang->story->action->closed = array('main' => '$date, Fermée par <strong>$actor</strong>. La raison est <strong>$extra</strong> $appendLink.', 'extra' => 'reasonList');
|
||||
$lang->story->action->reviewpassed = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>Pass</strong>.');
|
||||
$lang->story->action->reviewrejected = array('main' => '$date, closed by <strong>System</strong>. The reasion is <strong>Rejection</strong>.');
|
||||
$lang->story->action->reviewclarified = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>To Be Clarified</strong>. Please re-initiate the review after changing.');
|
||||
$lang->story->action->reviewclarified = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>To Be Clarified</strong>. Please re-initiate the review after edit.');
|
||||
$lang->story->action->reviewreverted = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>Undo Change</strong>.');
|
||||
$lang->story->action->linked2plan = array('main' => '$date, planifiée par <strong>$actor</strong> au Plan <strong>$extra</strong>');
|
||||
$lang->story->action->unlinkedfromplan = array('main' => '$date, déplanifiée par <strong>$actor</strong> du Plan <strong>$extra</strong>.');
|
||||
$lang->story->action->linked2execution = array('main' => '$date, associée au ' . $lang->executionCommon . ' <strong>$extra</strong> par <strong>$actor</strong>.');
|
||||
|
||||
@@ -313,7 +313,8 @@ $lang->story->action->recalled = array('main' => '$date, recalled b
|
||||
$lang->story->action->closed = array('main' => '$date, được đóng bởi <strong>$actor</strong>. Lý do là <strong>$extra</strong> $appendLink.', 'extra' => 'reasonList');
|
||||
$lang->story->action->reviewpassed = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>Pass</strong>.');
|
||||
$lang->story->action->reviewrejected = array('main' => '$date, closed by <strong>System</strong>. The reasion is <strong>Rejection</strong>.');
|
||||
$lang->story->action->reviewclarified = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>To Be Clarified</strong>. Please re-initiate the review after changing.');
|
||||
$lang->story->action->reviewclarified = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>To Be Clarified</strong>. Please re-initiate the review after edit.');
|
||||
$lang->story->action->reviewreverted = array('main' => '$date, determined by the <strong>System</strong>. The result is <strong>Undo Change</strong>.');
|
||||
$lang->story->action->linked2plan = array('main' => '$date, liên kết bởi <strong>$actor</strong> tới kế hoạch <strong>$extra</strong>');
|
||||
$lang->story->action->unlinkedfromplan = array('main' => '$date, bị hủy bởi <strong>$actor</strong> từ kế hoạch <strong>$extra</strong>.');
|
||||
$lang->story->action->linked2execution = array('main' => '$date, liên kết bởi <strong>$actor</strong> tới ' . $lang->executionCommon . ' <strong>$extra</strong>.');
|
||||
|
||||
@@ -321,7 +321,8 @@ $lang->story->action->recalled = array('main' => '$date, 由 <stron
|
||||
$lang->story->action->closed = array('main' => '$date, 由 <strong>$actor</strong> 关闭,原因为 <strong>$extra</strong> $appendLink。', 'extra' => 'reasonList');
|
||||
$lang->story->action->reviewpassed = array('main' => '$date, 由 <strong>系统</strong> 判定,结果为 <strong>确认通过</strong>。');
|
||||
$lang->story->action->reviewrejected = array('main' => '$date, 由 <strong>系统</strong> 关闭,原因为 <strong>拒绝</strong>。');
|
||||
$lang->story->action->reviewclarified = array('main' => '$date, 由 <strong>系统</strong> 判定,结果为 <strong>有待明确</strong>,请变更后重新发起评审。');
|
||||
$lang->story->action->reviewclarified = array('main' => '$date, 由 <strong>系统</strong> 判定,结果为 <strong>有待明确</strong>,请编辑后重新发起评审。');
|
||||
$lang->story->action->reviewreverted = array('main' => '$date, 由 <strong>系统</strong> 判定,结果为 <strong>撤销变更</strong>。');
|
||||
$lang->story->action->linked2plan = array('main' => '$date, 由 <strong>$actor</strong> 关联到计划 <strong>$extra</strong>。');
|
||||
$lang->story->action->unlinkedfromplan = array('main' => '$date, 由 <strong>$actor</strong> 从计划 <strong>$extra</strong> 移除。');
|
||||
$lang->story->action->linked2execution = array('main' => '$date, 由 <strong>$actor</strong> 关联到' . $lang->executionCommon . ' <strong>$extra</strong>。');
|
||||
|
||||
@@ -297,7 +297,8 @@ $lang->story->action->recalled = array('main' => '$date, 由 <stron
|
||||
$lang->story->action->closed = array('main' => '$date, 由 <strong>$actor</strong> 關閉,原因為 <strong>$extra</strong> $appendLink。', 'extra' => 'reasonList');
|
||||
$lang->story->action->reviewpassed = array('main' => '$date, 由 <strong>系統</strong> 判定,結果為 <strong>確認通過</strong>。');
|
||||
$lang->story->action->reviewrejected = array('main' => '$date, 由 <strong>系統</strong> 關閉,原因為 <strong>拒絶</strong>。');
|
||||
$lang->story->action->reviewclarified = array('main' => '$date, 由 <strong>系統</strong> 判定,結果為 <strong>有待明確</strong>,請變更後重新發起評審。');
|
||||
$lang->story->action->reviewclarified = array('main' => '$date, 由 <strong>系統</strong> 判定,結果為 <strong>有待明確</strong>,請編輯後重新發起評審。');
|
||||
$lang->story->action->reviewreverted = array('main' => '$date, 由 <strong>系統</strong> 判定,結果為 <strong>撤銷變更</strong>。');
|
||||
$lang->story->action->linked2plan = array('main' => '$date, 由 <strong>$actor</strong> 關聯到計劃 <strong>$extra</strong>。');
|
||||
$lang->story->action->unlinkedfromplan = array('main' => '$date, 由 <strong>$actor</strong> 從計劃 <strong>$extra</strong> 移除。');
|
||||
$lang->story->action->linked2execution = array('main' => '$date, 由 <strong>$actor</strong> 關聯到' . $lang->executionCommon . ' <strong>$extra</strong>。');
|
||||
|
||||
+129
-105
@@ -498,7 +498,7 @@ class storyModel extends model
|
||||
$reviewers = (isset($stories->reviewDitto[$i])) ? $reviewers : $stories->reviewer[$i];
|
||||
$stories->reviewer[$i] = $reviewers;
|
||||
$_POST['reviewer'][$i] = $reviewers;
|
||||
if(empty($stories->reviewer[$i]) and $forceReview)
|
||||
if(empty(array_filter($stories->reviewer[$i])) and $forceReview)
|
||||
{
|
||||
dao::$errors[] = $this->lang->story->errorEmptyReviewedBy;
|
||||
return false;
|
||||
@@ -904,7 +904,7 @@ class storyModel extends model
|
||||
}
|
||||
|
||||
$this->dao->update(TABLE_STORY)
|
||||
->data($story, 'reviewers,spec,verify')
|
||||
->data($story, 'reviewers,spec,verify,finalResult')
|
||||
->autoCheck()
|
||||
->checkIF(isset($story->closedBy), 'closedReason', 'notempty')
|
||||
->checkIF(isset($story->closedReason) and $story->closedReason == 'done', 'stage', 'notempty')
|
||||
@@ -912,6 +912,7 @@ class storyModel extends model
|
||||
->checkIF($story->notifyEmail, 'notifyEmail', 'email')
|
||||
->checkFlow()
|
||||
->where('id')->eq((int)$storyID)->exec();
|
||||
if(dao::isError()) return false;
|
||||
|
||||
if(!dao::isError())
|
||||
{
|
||||
@@ -1039,9 +1040,27 @@ class storyModel extends model
|
||||
}
|
||||
}
|
||||
|
||||
$changes = common::createChanges($oldStory, $story);
|
||||
$deleteFiles = isset($_POST['deleteFiles']) ? $this->file->getPairs($_POST['deleteFiles'], 'title') : array();
|
||||
|
||||
if(isset($_POST['deleteFiles'])) $this->file->deleteStoryFile($storyID, $oldStory->version, $_POST['deleteFiles']);
|
||||
$this->file->updateObjectID($this->post->uid, $storyID, 'story');
|
||||
return common::createChanges($oldStory, $story);
|
||||
|
||||
$files = $this->file->saveUpload($oldStory->type, $storyID, ",$oldStory->version,");
|
||||
if(empty($files) and $this->post->uid != '' and isset($_SESSION['album']['used'][$this->post->uid])) $files = $this->file->getPairs($_SESSION['album']['used'][$this->post->uid]);
|
||||
|
||||
if($this->post->comment != '' or !empty($changes) or !empty($files) or !empty($deleteFiles))
|
||||
{
|
||||
$action = (!empty($changes) or !empty($files)) ? 'Edited' : 'Commented';
|
||||
$fileAction = empty($files) ? '' : $this->lang->addFiles . join(',', $files) . "\n" ;
|
||||
$fileAction .= empty($deleteFiles) ? '' : $this->lang->deleteFiles . join(',', $deleteFiles) . "\n";
|
||||
$actionID = $this->action->create('story', $storyID, $action, $fileAction . $this->post->comment);
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
|
||||
if(isset($story->finalResult)) $this->recordReviewAction($story);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1440,7 +1459,6 @@ class storyModel extends model
|
||||
->setDefault('reviewedDate', $date)
|
||||
->stripTags($this->config->story->editor->review['id'], $this->config->allowedTags)
|
||||
->setIF(!$this->post->assignedTo, 'assignedTo', '')
|
||||
->setIF($this->post->result == 'revert', 'version', $oldStory->version - 1)
|
||||
->removeIF($this->post->result != 'reject', 'closedReason, duplicateStory, childStories')
|
||||
->removeIF($this->post->result == 'reject' and $this->post->closedReason != 'duplicate', 'duplicateStory')
|
||||
->removeIF($this->post->result == 'reject' and $this->post->closedReason != 'subdivided', 'childStories')
|
||||
@@ -1459,12 +1477,12 @@ class storyModel extends model
|
||||
|
||||
$story = $this->updateStoryByReview($storyID, $oldStory, $story);
|
||||
|
||||
$skipFields = '';
|
||||
$skipFields = 'finalResult';
|
||||
$isSuperReviewer = strpos(',' . trim(zget($this->config->story, 'superReviewers', ''), ',') . ',', ',' . $this->app->user->account . ',');
|
||||
if($isSuperReviewer === false)
|
||||
{
|
||||
$reviewers = $this->getReviewerPairs($storyID, $oldStory->version);
|
||||
if(count($reviewers) > 1) $skipFields = 'closedReason';
|
||||
if(count($reviewers) > 1) $skipFields .= ',closedReason';
|
||||
}
|
||||
|
||||
$this->dao->update(TABLE_STORY)->data($story, $skipFields)
|
||||
@@ -1473,27 +1491,21 @@ class storyModel extends model
|
||||
->checkIF($this->post->result == 'reject', 'closedReason', 'notempty')
|
||||
->checkIF($this->post->result == 'reject' and $this->post->closedReason == 'duplicate', 'duplicateStory', 'notempty')
|
||||
->checkFlow()
|
||||
->where('id')->eq($storyID)->exec();
|
||||
if($this->post->result == 'revert')
|
||||
{
|
||||
$preTitle = $this->dao->select('title')->from(TABLE_STORYSPEC)->where('story')->eq($storyID)->andWHere('version')->eq($oldStory->version - 1)->fetch('title');
|
||||
$this->dao->update(TABLE_STORY)->set('title')->eq($preTitle)->where('id')->eq($storyID)->exec();
|
||||
->where('id')->eq($storyID)
|
||||
->exec();
|
||||
if(dao::isError()) return false;
|
||||
|
||||
/* Delete versions that is after this version. */
|
||||
$deleteVersion = array();
|
||||
for($version = $oldStory->version; $version > $story->version; $version --) $deleteVersion[] = $version;
|
||||
if($deleteVersion)
|
||||
{
|
||||
$this->dao->delete()->from(TABLE_STORYSPEC)->where('story')->eq($storyID)->andWHere('version')->in($deleteVersion)->exec();
|
||||
$this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($storyID)->andWhere('version')->in($deleteVersion)->exec();
|
||||
}
|
||||
|
||||
$this->file->deleteStoryFile($storyID, $oldStory->version);
|
||||
}
|
||||
if($this->post->result != 'reject') $this->setStage($storyID);
|
||||
|
||||
if(isset($story->closedReason) and $isSuperReviewer === false) unset($story->closedReason);
|
||||
return common::createChanges($oldStory, $story);
|
||||
$changes = common::createChanges($oldStory, $story);
|
||||
if($changes)
|
||||
{
|
||||
$actionID = $this->recordReviewAction($story, $this->post->result, $this->post->closedReason);
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1524,6 +1536,7 @@ class storyModel extends model
|
||||
if($oldStory->status != 'reviewing') continue;
|
||||
if(!in_array($this->app->user->account, array_keys($reviewerList[$storyID])) and $isSuperReviewer === false) continue;
|
||||
if(isset($hasResult[$storyID]) and $hasResult[$storyID]->version == $oldStories[$storyID]->version) continue;
|
||||
if($oldStory->version > 1 and $result == 'reject') continue;
|
||||
|
||||
$story = new stdClass();
|
||||
$story->reviewedDate = $now;
|
||||
@@ -1546,20 +1559,11 @@ class storyModel extends model
|
||||
foreach($reviewerList[$storyID] as $reviewer => $reviewInfo) $reviewerPairs[$reviewer] = $reviewInfo->result;
|
||||
$reviewerPairs[$this->app->user->account] = $result;
|
||||
|
||||
$status = $this->setStatusByReviewRules($reviewerPairs);
|
||||
$story->status = $status ? $status : $oldStory->status;
|
||||
|
||||
if($story->status == 'closed')
|
||||
{
|
||||
$story->closedBy = $this->app->user->account;
|
||||
$story->closedDate = $now;
|
||||
$story->assignedTo = 'closed';
|
||||
$story->stage = 'closed';
|
||||
if($reason == 'done') $story->stage = 'released';
|
||||
}
|
||||
$reviewResult = $this->getReviewResult($reviewerPairs);
|
||||
$story = $this->setStatusByReviewResult($story, $oldStory, $reviewResult, $reason);
|
||||
}
|
||||
|
||||
$this->dao->update(TABLE_STORY)->data($story)->autoCheck()->where('id')->eq($storyID)->exec();
|
||||
$this->dao->update(TABLE_STORY)->data($story, 'finalResult')->autoCheck()->where('id')->eq($storyID)->exec();
|
||||
$this->setStage($storyID);
|
||||
|
||||
$story->id = $storyID;
|
||||
@@ -1632,6 +1636,7 @@ class storyModel extends model
|
||||
$story = fixer::input('post')
|
||||
->setDefault('status', 'active')
|
||||
->setDefault('reviewer', '')
|
||||
->setDefault('reviewedBy', '')
|
||||
->remove('needNotReview')
|
||||
->join('reviewer', ',')
|
||||
->get();
|
||||
@@ -1653,7 +1658,7 @@ class storyModel extends model
|
||||
$story->status = 'reviewing';
|
||||
}
|
||||
|
||||
$this->dao->update(TABLE_STORY)->set('status')->eq($story->status)->where('id')->eq($storyID)->exec();
|
||||
$this->dao->update(TABLE_STORY)->data($story, 'reviewer')->where('id')->eq($storyID)->exec();
|
||||
if(!dao::isError()) return common::createChanges($oldStory, $story);
|
||||
|
||||
return false;
|
||||
@@ -1958,7 +1963,8 @@ class storyModel extends model
|
||||
{
|
||||
if(!empty($oldStory->plan) and isset($branchPlanPairs[$plan->branch]) and $branchPlanPairs[$plan->branch] != $planID) $unlinkPlans[$branchPlanPairs[$plan->branch]] = empty($unlinkPlans[$branchPlanPairs[$plan->branch]]) ? $storyID : "{$unlinkPlans[$branchPlanPairs[$plan->branch]]},$storyID";
|
||||
if(isset($branchPlanPairs[$plan->branch])) $branchPlanPairs[$plan->branch] = $planID;
|
||||
$story->plan = $oldStory->plan ? ',' . implode(',', $branchPlanPairs) : ",$planID";
|
||||
$story->plan = $oldStory->plan ? implode(',', $branchPlanPairs) : $planID;
|
||||
$story->plan = trim($story->plan, ',');
|
||||
if($story->plan != $oldStory->plan and !empty($planID)) $link2Plans[$planID] = empty($link2Plans[$planID]) ? $storyID : "{$link2Plans[$planID]},$storyID";
|
||||
}
|
||||
}
|
||||
@@ -3065,7 +3071,7 @@ class storyModel extends model
|
||||
}
|
||||
else
|
||||
{
|
||||
$storyQuery .= " AND `status` NOT IN ('draft', 'closed')";
|
||||
$storyQuery .= " AND `status` NOT IN ('draft', 'reviewing', 'changing', 'closed')";
|
||||
}
|
||||
|
||||
if($this->app->rawModule == 'build' and $this->app->rawMethod == 'linkstory') $storyQuery .= " AND `parent` != '-1'";
|
||||
@@ -5548,41 +5554,92 @@ class storyModel extends model
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function setStatusByReviewRules($reviewerList)
|
||||
public function getReviewResult($reviewerList)
|
||||
{
|
||||
$status = '';
|
||||
$results = '';
|
||||
$passCount = 0;
|
||||
$rejectCount = 0;
|
||||
$reviewRule = $this->config->story->reviewRules;
|
||||
foreach($reviewerList as $reviewer => $reviewResult)
|
||||
$results = '';
|
||||
$passCount = 0;
|
||||
$rejectCount = 0;
|
||||
$revertCount = 0;
|
||||
$clarifyCount = 0;
|
||||
$reviewRule = $this->config->story->reviewRules;
|
||||
foreach($reviewerList as $reviewer => $result)
|
||||
{
|
||||
if($reviewResult == 'clarify') return 'draft';
|
||||
$passCount = $result == 'pass' ? $passCount + 1 : $passCount;
|
||||
$rejectCount = $result == 'reject' ? $rejectCount + 1 : $rejectCount;
|
||||
$revertCount = $result == 'revert' ? $revertCount + 1 : $revertCount;
|
||||
$clarifyCount = $result == 'clarify' ? $clarifyCount + 1 : $clarifyCount;
|
||||
|
||||
$passCount = $reviewResult == 'pass' ? $passCount + 1 : $passCount;
|
||||
$rejectCount = $reviewResult == 'reject' ? $rejectCount + 1 : $rejectCount;
|
||||
|
||||
$results .= $reviewResult . ',';
|
||||
$results .= $result . ',';
|
||||
}
|
||||
|
||||
if($reviewRule == 'allpass')
|
||||
{
|
||||
if(strpos($results, 'reject') !== false) return 'closed';
|
||||
$finalResult = '';
|
||||
if($reviewRule == 'allpass' and $passCount == count($reviewerList)) $finalResult = 'pass';
|
||||
if($reviewRule == 'halfpass' and $passCount >= floor(count($reviewerList) / 2) + 1) $finalResult = 'pass';
|
||||
|
||||
if($passCount == count($reviewerList)) $status = 'active';
|
||||
if($rejectCount == count($reviewerList)) $status = 'closed';
|
||||
if(empty($finalResult))
|
||||
{
|
||||
if($clarifyCount >= floor(count($reviewerList) / 2) + 1) return 'clarify';
|
||||
if($revertCount >= floor(count($reviewerList) / 2) + 1) return 'revert';
|
||||
if($rejectCount >= floor(count($reviewerList) / 2) + 1) return 'reject';
|
||||
|
||||
if(strpos($results, 'clarify') !== false) return 'clarify';
|
||||
if(strpos($results, 'revert') !== false) return 'revert';
|
||||
if(strpos($results, 'reject') !== false) return 'reject';
|
||||
}
|
||||
|
||||
if($reviewRule == 'halfpass')
|
||||
{
|
||||
/* When the number of reviewers is even, half of them reject to close. */
|
||||
if(count($reviewerList) > 1 and count($reviewerList) % 2 == 0 and $rejectCount == floor(count($reviewerList) / 2)) return 'closed';
|
||||
return $finalResult;
|
||||
}
|
||||
|
||||
if($passCount >= floor(count($reviewerList) / 2) + 1) $status = 'active';
|
||||
if($rejectCount >= floor(count($reviewerList) / 2) + 1) $status = 'closed';
|
||||
/**
|
||||
* Set story status by reeview result.
|
||||
*
|
||||
* @param int $story
|
||||
* @param int $oldStory
|
||||
* @param int $result
|
||||
* @param string $reason
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function setStatusByReviewResult($story, $oldStory, $result, $reason = 'cancel')
|
||||
{
|
||||
if($result == 'pass') $story->status = 'active';
|
||||
|
||||
if($result == 'clarify')
|
||||
{
|
||||
/* When the review result of the changed story is clarify, the status should be changing. */
|
||||
$isChanged = $oldStory->changedBy ? true : false;
|
||||
$story->status = $isChanged ? 'changing' : 'draft';
|
||||
}
|
||||
|
||||
return $status;
|
||||
if($result == 'revert')
|
||||
{
|
||||
$story->status = 'active';
|
||||
$story->version = $oldStory->version - 1;
|
||||
$story->title = $this->dao->select('title')->from(TABLE_STORYSPEC)->where('story')->eq($story->id)->andWHere('version')->eq($oldStory->version - 1)->fetch('title');
|
||||
|
||||
/* Delete versions that is after this version. */
|
||||
$this->dao->delete()->from(TABLE_STORYSPEC)->where('story')->eq($story->id)->andWHere('version')->in($oldStory->version)->exec();
|
||||
$this->dao->delete()->from(TABLE_STORYREVIEW)->where('story')->eq($story->id)->andWhere('version')->in($oldStory->version)->exec();
|
||||
|
||||
$this->file->deleteStoryFile($story->id, $oldStory->version);
|
||||
}
|
||||
|
||||
if($result == 'reject')
|
||||
{
|
||||
$now = helper::now();
|
||||
$reason = (empty($reason) and isset($story->closedReason)) ? $story->closedReason : $reason;
|
||||
|
||||
$story->status = 'closed';
|
||||
$story->closedBy = $this->app->user->account;
|
||||
$story->closedDate = $now;
|
||||
$story->assignedTo = 'closed';
|
||||
$story->assignedDate = $now;
|
||||
$story->stage = $reason == 'done' ? 'released' : 'closed';
|
||||
$story->closedReason = $reason;
|
||||
}
|
||||
|
||||
$story->finalResult = $result;
|
||||
return $story;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5607,17 +5664,15 @@ class storyModel extends model
|
||||
}
|
||||
|
||||
$reasonParam = $result == 'reject' ? ',' . $reason : '';
|
||||
$reviewers = $this->getReviewerPairs($story->id, $story->version);
|
||||
$reviewedBy = explode(',', trim($story->reviewedBy, ','));
|
||||
$actionID = !empty($result) ? $this->loadModel('action')->create('story', $story->id, 'Reviewed', $comment, ucfirst($result) . $reasonParam) : '';
|
||||
|
||||
$actionID = !empty($result) ? $this->loadModel('action')->create('story', $story->id, 'Reviewed', $comment, ucfirst($result) . $reasonParam) : '';
|
||||
|
||||
if($result != 'revert')
|
||||
if(isset($story->finalResult))
|
||||
{
|
||||
$isChanged = $story->changedBy ? true : false;
|
||||
if($story->status == 'closed') $this->action->create('story', $story->id, 'ReviewRejected', '', $isChanged ? 'changing' : 'draft');
|
||||
if($story->status == 'active') $this->action->create('story', $story->id, 'ReviewPassed');
|
||||
if(!array_diff(array_keys($reviewers), $reviewedBy) and ($story->status == 'draft' or $story->status == 'changing')) $this->action->create('story', $story->id, 'ReviewClarified');
|
||||
if($story->finalResult == 'reject') $this->action->create('story', $story->id, 'ReviewRejected', '', $isChanged ? 'changing' : 'draft');
|
||||
if($story->finalResult == 'pass') $this->action->create('story', $story->id, 'ReviewPassed');
|
||||
if($story->finalResult == 'clarify') $this->action->create('story', $story->id, 'ReviewClarified');
|
||||
if($story->finalResult == 'revert') $this->action->create('story', $story->id, 'ReviewReverted');
|
||||
}
|
||||
|
||||
return $actionID;
|
||||
@@ -5637,27 +5692,12 @@ class storyModel extends model
|
||||
$isSuperReviewer = strpos(',' . trim(zget($this->config->story, 'superReviewers', ''), ',') . ',', ',' . $this->app->user->account . ',');
|
||||
if($isSuperReviewer !== false) return $this->superReview($storyID, $oldStory, $story);
|
||||
|
||||
$now = helper::now();
|
||||
$reviewerList = $this->getReviewerPairs($storyID, $oldStory->version);
|
||||
$reviewedBy = explode(',', trim($story->reviewedBy, ','));
|
||||
if(!array_diff(array_keys($reviewerList), $reviewedBy))
|
||||
{
|
||||
$status = $this->post->result == 'revert' ? 'active' : $this->setStatusByReviewRules($reviewerList);
|
||||
|
||||
/* When the review result of the changed story is clarify, the status should be changing. */
|
||||
$isChanged = $oldStory->changedBy ? true : false;
|
||||
$status = ($isChanged and $status == 'draft') ? 'changing' : $status;
|
||||
|
||||
$story->status = $status ? $status : $oldStory->status;
|
||||
if($story->status == 'closed')
|
||||
{
|
||||
$story->closedBy = $this->app->user->account;
|
||||
$story->closedDate = $now;
|
||||
$story->assignedTo = 'closed';
|
||||
$story->assignedDate = $now;
|
||||
$story->stage = 'closed';
|
||||
if($this->post->closedReason == 'done') $story->stage = 'released';
|
||||
}
|
||||
$reviewResult = $this->getReviewResult($reviewerList);
|
||||
$story = $this->setStatusByReviewResult($story, $oldStory, $reviewResult);
|
||||
}
|
||||
|
||||
return $story;
|
||||
@@ -5679,24 +5719,8 @@ class storyModel extends model
|
||||
$result = isset($_POST['result']) ? $this->post->result : $result;
|
||||
if(empty($result)) return $story;
|
||||
|
||||
$now = helper::now();
|
||||
$status = $oldStory->status;
|
||||
if(strpos('revert,pass', $result) !== false) $status = 'active';
|
||||
if($result == 'reject') $status = 'closed';
|
||||
if($result == 'clarify') $status = 'draft';
|
||||
|
||||
$story->status = $status;
|
||||
|
||||
if($story->status == 'closed')
|
||||
{
|
||||
$story->closedBy = $this->app->user->account;
|
||||
$story->closedDate = $now;
|
||||
$story->assignedTo = 'closed';
|
||||
$story->assignedDate = $now;
|
||||
$story->stage = 'closed';
|
||||
$story->closedReason = isset($_POST['closedReason']) ? $_POST['closedReason'] : $reason;
|
||||
if($_POST['closedReason'] == 'done') $story->stage = 'released';
|
||||
}
|
||||
$reason = isset($_POST['closedReason']) ? $_POST['closedReason'] : $reason;
|
||||
$story = $this->setStatusByReviewResult($story, $oldStory, $result, $reason);
|
||||
|
||||
$this->dao->delete()->from(TABLE_STORYREVIEW)
|
||||
->where('story')->eq($storyID)
|
||||
|
||||
@@ -48,7 +48,7 @@ $config->task->custom->createFields = $config->task->customCreateFields;
|
||||
$config->task->custom->batchCreateFields = 'module,story,assignedTo,estimate,desc,pri';
|
||||
$config->task->custom->batchEditFields = 'module,assignedTo,status,pri,estimate,record,left';
|
||||
|
||||
$config->task->excludeCheckFileds = ',pri,estStartedDitto,deadlineDitto,parent,';
|
||||
$config->task->excludeCheckFileds = ',pri,estStartedDitto,deadlineDitto,parent,regions,lanes,';
|
||||
|
||||
$config->task->datatable = new stdclass();
|
||||
$config->task->datatable->defaultField = array('id', 'pri', 'name', 'status', 'assignedTo', 'finishedBy', 'estimate', 'consumed', 'left', 'progress', 'deadline', 'actions');
|
||||
|
||||
@@ -1228,7 +1228,8 @@ class task extends control
|
||||
public function deleteEstimate($estimateID, $confirm = 'no')
|
||||
{
|
||||
$estimate = $this->task->getEstimateById($estimateID);
|
||||
$task = $this->task->getById($estimate->task);
|
||||
$taskID = $estimate->objectID;
|
||||
$task = $this->task->getById($taskID);
|
||||
if($confirm == 'no' and $task->consumed - $estimate->consumed != 0)
|
||||
{
|
||||
return print(js::confirm($this->lang->task->confirmDeleteEstimate, $this->createLink('task', 'deleteEstimate', "estimateID=$estimateID&confirm=yes")));
|
||||
@@ -1242,12 +1243,12 @@ class task extends control
|
||||
$changes = $this->task->deleteEstimate($estimateID);
|
||||
if(dao::isError()) return print(js::error(dao::getError()));
|
||||
|
||||
$actionID = $this->loadModel('action')->create('task', $estimate->task, 'DeleteEstimate');
|
||||
$actionID = $this->loadModel('action')->create('task', $taskID, 'DeleteEstimate');
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
|
||||
if($task->consumed - $estimate->consumed == 0)
|
||||
{
|
||||
$this->loadModel('action')->create('task', $estimate->task, 'Adjusttasktowait');
|
||||
$this->action->create('task', $taskID, 'Adjusttasktowait');
|
||||
return print(js::reload('parent.parent'));
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
#testStoryBox table tr td input {border: 0px;}
|
||||
#testStoryBox table tr td .input-group .input-group-addon {border-left: 1px solid #dcdcdc; border-right: 1px solid #dcdcdc;}
|
||||
#testStoryBox table button.btn {border: 0px;}
|
||||
#testStoryBox .c-name {width: 300px;}
|
||||
#testStoryBox .c-pri, #testStoryBox .c-estimate, #testStoryBox .c-actions {width: 70px;}
|
||||
#testStoryBox .c-date {width: 140px;}
|
||||
#testStoryBox .c-assignedTo {width: 100px; padding: 7px;}
|
||||
|
||||
.chosen-results > li.has-test,
|
||||
.chosen-results > li.has-new-test {position: relative; color: #388E3C;}
|
||||
|
||||
@@ -9,3 +9,7 @@
|
||||
.table-recorded thead { background: #F5F6F8}
|
||||
.table>thead>tr>th{ border-bottom: 1px solid #EEEEEE}
|
||||
#linearefforts .nav li.active a{color: #0c64eb !important}
|
||||
.input-group-addon {background: #fff}
|
||||
.icon-calendar {color: rgb(22, 168, 248)}
|
||||
#recordForm .table>thead>tr>th{ border: none}
|
||||
.main-header {border-bottom: none !important}
|
||||
|
||||
@@ -166,7 +166,7 @@ $lang->task->recordEstimateAction = 'Record Estimate';
|
||||
|
||||
$lang->task->ditto = 'Dito';
|
||||
$lang->task->dittoNotice = "Diese Aufgabe gehört nicht zum %s wie die Vorherige!";
|
||||
$lang->task->selectTestStory = 'Select Story Tested';
|
||||
$lang->task->selectTestStory = "Select {$lang->SRCommon}";
|
||||
$lang->task->selectAllUser = 'Alle';
|
||||
$lang->task->noStory = 'Keine Story';
|
||||
$lang->task->noAssigned = 'Nicht zugeordnet';
|
||||
|
||||
@@ -166,7 +166,7 @@ $lang->task->recordEstimateAction = 'Record Estimate';
|
||||
|
||||
$lang->task->ditto = 'Ditto';
|
||||
$lang->task->dittoNotice = "This Task is not linked to %s like the last one!";
|
||||
$lang->task->selectTestStory = 'Select Story Tested';
|
||||
$lang->task->selectTestStory = "Select {$lang->SRCommon}";
|
||||
$lang->task->selectAllUser = 'All Users';
|
||||
$lang->task->noStory = 'No Story Linked';
|
||||
$lang->task->noAssigned = 'Unassigned';
|
||||
|
||||
@@ -166,7 +166,7 @@ $lang->task->recordEstimateAction = 'Record Estimate';
|
||||
|
||||
$lang->task->ditto = 'Idem';
|
||||
$lang->task->dittoNotice = "Cette Tâche n'est pas associée au %s comme la précédente peut l'être !";
|
||||
$lang->task->selectTestStory = 'Select Story Testé';
|
||||
$lang->task->selectTestStory = "Select {$lang->SRCommon}";
|
||||
$lang->task->selectAllUser = 'Tous Utilis.';
|
||||
$lang->task->noStory = 'Aucune Story associée';
|
||||
$lang->task->noAssigned = 'Non affectées';
|
||||
|
||||
+17
-6
@@ -35,6 +35,16 @@ class taskModel extends model
|
||||
|
||||
if($this->post->selectTestStory)
|
||||
{
|
||||
foreach($this->post->testStory as $i => $storyID)
|
||||
{
|
||||
if(empty($storyID)) continue;
|
||||
if($this->post->testEstStarted[$i] > $this->post->testDeadline[$i])
|
||||
{
|
||||
dao::$errors[] = "ID: $storyID {$this->lang->task->error->deadlineSmall}";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check required fields when create test task. */
|
||||
foreach($this->post->testStory as $i => $storyID)
|
||||
{
|
||||
@@ -816,7 +826,7 @@ class taskModel extends model
|
||||
{
|
||||
if(!$autoStatus) return $currentTask;
|
||||
|
||||
if($currentTask->consumed == 0)
|
||||
if($currentTask->consumed == 0 and empty($efforts))
|
||||
{
|
||||
if(!isset($task->status)) $currentTask->status = 'wait';
|
||||
$currentTask->finishedBy = '';
|
||||
@@ -2873,7 +2883,7 @@ class taskModel extends model
|
||||
if($estimate->consumed < 0) return dao::$errors[] = sprintf($this->lang->error->ge, $this->lang->task->record, '0');
|
||||
if($estimate->left < 0) return dao::$errors[] = sprintf($this->lang->error->ge, $this->lang->task->left, '0');
|
||||
|
||||
$task = $this->getById($oldEstimate->task);
|
||||
$task = $this->getById($oldEstimate->objectID);
|
||||
$this->dao->update(TABLE_EFFORT)->data($estimate)
|
||||
->autoCheck()
|
||||
->where('id')->eq((int)$estimateID)
|
||||
@@ -2946,7 +2956,7 @@ class taskModel extends model
|
||||
public function deleteEstimate($estimateID)
|
||||
{
|
||||
$estimate = $this->getEstimateById($estimateID);
|
||||
$task = $this->getById($estimate->task);
|
||||
$task = $this->getById($estimate->objectID);
|
||||
$now = helper::now();
|
||||
|
||||
$consumed = $task->consumed - $estimate->consumed;
|
||||
@@ -2954,7 +2964,7 @@ class taskModel extends model
|
||||
if($estimate->isLast)
|
||||
{
|
||||
$lastTwoEstimates = $this->dao->select('*')->from(TABLE_EFFORT)
|
||||
->where('objectID')->eq($estimate->task)
|
||||
->where('objectID')->eq($estimate->objectID)
|
||||
->andWhere('objectType')->eq('task')
|
||||
->orderBy('date desc,id desc')->limit(2)->fetchAll();
|
||||
$lastTwoEstimate = isset($lastTwoEstimates[1]) ? $lastTwoEstimates[1] : '';
|
||||
@@ -2966,7 +2976,7 @@ class taskModel extends model
|
||||
$data->consumed = $consumed;
|
||||
$data->left = $left;
|
||||
$data->status = ($left == 0 && $consumed != 0) ? 'done' : $task->status;
|
||||
if($consumed == 0 and $task->status != 'wait')
|
||||
if($estimate->isLast and $consumed == 0 and $task->status != 'wait')
|
||||
{
|
||||
$data->status = 'wait';
|
||||
$data->left = $task->estimate;
|
||||
@@ -3031,7 +3041,7 @@ class taskModel extends model
|
||||
$this->dao->update(TABLE_EFFORT)->set('deleted')->eq('1')->where('id')->eq($estimateID)->exec();
|
||||
if(!empty($task->team)) $data = $this->computeHours4Multiple($task, $data);
|
||||
|
||||
$this->dao->update(TABLE_TASK)->data($data) ->where('id')->eq($estimate->task)->exec();
|
||||
$this->dao->update(TABLE_TASK)->data($data) ->where('id')->eq($estimate->objectID)->exec();
|
||||
if($task->parent > 0) $this->updateParentStatus($task->id);
|
||||
if($task->story) $this->loadModel('story')->setStage($task->story);
|
||||
|
||||
@@ -3621,6 +3631,7 @@ class taskModel extends model
|
||||
$effort->left = $data->left;
|
||||
$effort->work = isset($data->work) ? $data->work : '';
|
||||
$effort->vision = $this->config->vision;
|
||||
$effort->order = isset($data->order) ? $data->order : 0;
|
||||
$this->dao->insert(TABLE_EFFORT)->data($effort)->autoCheck()->exec();
|
||||
|
||||
return $this->dao->lastInsertID();
|
||||
|
||||
@@ -122,13 +122,13 @@ foreach(explode(',', $config->task->create->requiredFields) as $field)
|
||||
<table class='table table-form mg-0 table-bordered'>
|
||||
<thead>
|
||||
<tr class='text-center'>
|
||||
<th class='w-150px'><?php echo $lang->task->storyAB;?></th>
|
||||
<th class='w-60px'><?php echo $lang->task->pri;?></th>
|
||||
<th class='w-100px'><?php echo $lang->task->estStarted;?></th>
|
||||
<th class='w-100px'><?php echo $lang->task->deadline;?></th>
|
||||
<th class='w-60px'><?php echo $lang->task->assignedTo;?></th>
|
||||
<th class='w-60px'><?php echo $lang->task->estimate;?></th>
|
||||
<th class='w-60px'><?php echo $lang->actions;?></th>
|
||||
<th class='c-name'><?php echo $lang->task->storyAB;?></th>
|
||||
<th class='c-pri'><?php echo $lang->task->pri;?></th>
|
||||
<th class='c-date'><?php echo $lang->task->estStarted;?></th>
|
||||
<th class='c-date'><?php echo $lang->task->deadline;?></th>
|
||||
<th class='c-assignedTo'><?php echo $lang->task->assignedTo;?></th>
|
||||
<th class='c-estimate'><?php echo $lang->task->estimate;?></th>
|
||||
<th class='c-actions'><?php echo $lang->actions;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="resarch">
|
||||
|
||||
@@ -21,92 +21,94 @@ foreach($efforts as $effort)
|
||||
if($app->user->account == $account) $myOrders[$order] = $order;
|
||||
}
|
||||
?>
|
||||
<?php if($myOrders):?>
|
||||
<div class='tabs' id='linearefforts'>
|
||||
<ul class='nav nav-tabs'>
|
||||
<li class='active'><a href='#legendMyEffort' data-toggle='tab'><?php echo $lang->task->myEffort;?></a></li>
|
||||
<li><a href='#legendAllEffort' data-toggle='tab'><?php echo $lang->task->allEffort;?></a></li>
|
||||
</ul>
|
||||
<div class='tab-content'>
|
||||
<div class='tab-pane active' id='legendMyEffort'>
|
||||
<?php foreach($myOrders as $order):?>
|
||||
<div class='caption'>
|
||||
<span class='label label-badge'><?php echo $order + 1;?></span>
|
||||
<span class='account'><?php echo zget($users, $app->user->account);?></span>
|
||||
<div id='linearefforts'>
|
||||
<?php if($myOrders):?>
|
||||
<div class='tabs'>
|
||||
<ul class='nav nav-tabs'>
|
||||
<li class='active'><a href='#legendMyEffort' data-toggle='tab'><?php echo $lang->task->myEffort;?></a></li>
|
||||
<li><a href='#legendAllEffort' data-toggle='tab'><?php echo $lang->task->allEffort;?></a></li>
|
||||
</ul>
|
||||
<div class='tab-content'>
|
||||
<div class='tab-pane active' id='legendMyEffort'>
|
||||
<?php foreach($myOrders as $order):?>
|
||||
<div class='caption'>
|
||||
<span class='label label-badge'><?php echo $order + 1;?></span>
|
||||
<span class='account'><?php echo zget($users, $app->user->account);?></span>
|
||||
</div>
|
||||
<table class='table table-bordered table-fixed table-recorded'>
|
||||
<thead>
|
||||
<tr class='text-center'>
|
||||
<th class="w-120px"><?php echo $lang->task->date;?></th>
|
||||
<th class="w-120px"><?php echo $lang->task->recordedBy;?></th>
|
||||
<th><?php echo $lang->comment;?></th>
|
||||
<th class="thWidth"><?php echo $lang->task->consumed;?></th>
|
||||
<th class="thWidth"><?php echo $lang->task->left;?></th>
|
||||
<th class='c-actions-2'><?php echo $lang->actions;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($allEfforts[$order] as $effort):?>
|
||||
<tr class="text-center">
|
||||
<td><?php echo $effort->date;?></td>
|
||||
<td><?php echo zget($users, $effort->account);?></td>
|
||||
<td class="text-left" title="<?php echo $effort->work;?>"><?php echo $effort->work;?></td>
|
||||
<td title="<?php echo $effort->consumed . ' ' . $lang->execution->workHour;?>"><?php echo $effort->consumed . ' ' . $lang->execution->workHourUnit;?></td>
|
||||
<td title="<?php echo $effort->left . ' ' . $lang->execution->workHour;?>"><?php echo $effort->left . ' ' . $lang->execution->workHourUnit;?></td>
|
||||
<td align='center' class='c-actions'>
|
||||
<?php
|
||||
$canOperateEffort = $this->task->canOperateEffort($task, $effort);
|
||||
common::printIcon($this->config->edition == 'open' ? 'task' : 'effort', $this->config->edition == 'open' ? 'editEstimate' : 'edit', "effortID=$effort->id", '', 'list', 'edit', '', 'showinonlybody', true, $canOperateEffort ? '' : 'disabled');
|
||||
common::printIcon($this->config->edition == 'open' ? 'task' : 'effort', $this->config->edition == 'open' ? 'deleteEstimate' : 'delete', "effortID=$effort->id", '', 'list', 'trash', 'hiddenwin', 'showinonlybody', false, ($canOperateEffort and $effort->left > 0) ? '' : 'disabled');
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endforeach;?>
|
||||
</div>
|
||||
<table class='table table-bordered table-fixed table-recorded'>
|
||||
<thead>
|
||||
<tr class='text-center'>
|
||||
<th class="w-120px"><?php echo $lang->task->date;?></th>
|
||||
<th class="w-120px"><?php echo $lang->task->recordedBy;?></th>
|
||||
<th><?php echo $lang->comment;?></th>
|
||||
<th class="thWidth"><?php echo $lang->task->consumed;?></th>
|
||||
<th class="thWidth"><?php echo $lang->task->left;?></th>
|
||||
<th class='c-actions-2'><?php echo $lang->actions;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($allEfforts[$order] as $effort):?>
|
||||
<tr class="text-center">
|
||||
<td><?php echo $effort->date;?></td>
|
||||
<td><?php echo zget($users, $effort->account);?></td>
|
||||
<td class="text-left" title="<?php echo $effort->work;?>"><?php echo $effort->work;?></td>
|
||||
<td title="<?php echo $effort->consumed . ' ' . $lang->execution->workHour;?>"><?php echo $effort->consumed . ' ' . $lang->execution->workHourUnit;?></td>
|
||||
<td title="<?php echo $effort->left . ' ' . $lang->execution->workHour;?>"><?php echo $effort->left . ' ' . $lang->execution->workHourUnit;?></td>
|
||||
<td align='center' class='c-actions'>
|
||||
<?php
|
||||
$canOperateEffort = $this->task->canOperateEffort($task, $effort);
|
||||
common::printIcon($this->config->edition == 'open' ? 'task' : 'effort', $this->config->edition == 'open' ? 'editEstimate' : 'edit', "effortID=$effort->id", '', 'list', 'edit', '', 'showinonlybody', true, $canOperateEffort ? '' : 'disabled');
|
||||
common::printIcon($this->config->edition == 'open' ? 'task' : 'effort', $this->config->edition == 'open' ? 'deleteEstimate' : 'delete', "effortID=$effort->id", '', 'list', 'trash', 'hiddenwin', 'showinonlybody', false, ($canOperateEffort and $effort->left > 0) ? '' : 'disabled');
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endforeach;?>
|
||||
</div>
|
||||
<div class='tab-pane' id='legendAllEffort'>
|
||||
<?php endif;?>
|
||||
<?php foreach($recorders as $order => $accounts):?>
|
||||
<div class='caption'>
|
||||
<span class='label label-badge'><?php echo $order + 1;?></span>
|
||||
<span class='account'><?php foreach($accounts as $account) echo zget($users, $account) . ' ';?></span>
|
||||
<div class='tab-pane' id='legendAllEffort'>
|
||||
<?php endif;?>
|
||||
<?php foreach($recorders as $order => $accounts):?>
|
||||
<div class='caption'>
|
||||
<span class='label label-badge'><?php echo $order + 1;?></span>
|
||||
<span class='account'><?php foreach($accounts as $account) echo zget($users, $account) . ' ';?></span>
|
||||
</div>
|
||||
<table class='table table-bordered table-fixed table-recorded'>
|
||||
<thead>
|
||||
<tr class='text-center'>
|
||||
<th class="w-120px"><?php echo $lang->task->date;?></th>
|
||||
<th class="w-120px"><?php echo $lang->task->recordedBy;?></th>
|
||||
<th><?php echo $lang->comment;?></th>
|
||||
<th class="thWidth"><?php echo $lang->task->consumed;?></th>
|
||||
<th class="thWidth"><?php echo $lang->task->left;?></th>
|
||||
<th class='c-actions-2'><?php echo $lang->actions;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($allEfforts[$order] as $effort):?>
|
||||
<tr class="text-center">
|
||||
<td><?php echo $effort->date;?></td>
|
||||
<td><?php echo zget($users, $effort->account);?></td>
|
||||
<td class="text-left" title="<?php echo $effort->work;?>"><?php echo $effort->work;?></td>
|
||||
<td title="<?php echo $effort->consumed . ' ' . $lang->execution->workHour;?>"><?php echo $effort->consumed . ' ' . $lang->execution->workHourUnit;?></td>
|
||||
<td title="<?php echo $effort->left . ' ' . $lang->execution->workHour;?>"><?php echo $effort->left . ' ' . $lang->execution->workHourUnit;?></td>
|
||||
<td align='center' class='c-actions'>
|
||||
<?php
|
||||
$canOperateEffort = $this->task->canOperateEffort($task, $effort);
|
||||
common::printIcon($this->config->edition == 'open' ? 'task' : 'effort', $this->config->edition == 'open' ? 'editEstimate' : 'edit', "effortID=$effort->id", '', 'list', 'edit', '', 'showinonlybody', true, $canOperateEffort ? '' : 'disabled');
|
||||
common::printIcon($this->config->edition == 'open' ? 'task' : 'effort', $this->config->edition == 'open' ? 'deleteEstimate' : 'delete', "effortID=$effort->id", '', 'list', 'trash', 'hiddenwin', 'showinonlybody', false, ($canOperateEffort and $effort->left > 0) ? '' : 'disabled');
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endforeach;?>
|
||||
<?php if($myOrders):?>
|
||||
</div>
|
||||
<table class='table table-bordered table-fixed table-recorded'>
|
||||
<thead>
|
||||
<tr class='text-center'>
|
||||
<th class="w-120px"><?php echo $lang->task->date;?></th>
|
||||
<th class="w-120px"><?php echo $lang->task->recordedBy;?></th>
|
||||
<th><?php echo $lang->comment;?></th>
|
||||
<th class="thWidth"><?php echo $lang->task->consumed;?></th>
|
||||
<th class="thWidth"><?php echo $lang->task->left;?></th>
|
||||
<th class='c-actions-2'><?php echo $lang->actions;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($allEfforts[$order] as $effort):?>
|
||||
<tr class="text-center">
|
||||
<td><?php echo $effort->date;?></td>
|
||||
<td><?php echo zget($users, $effort->account);?></td>
|
||||
<td class="text-left" title="<?php echo $effort->work;?>"><?php echo $effort->work;?></td>
|
||||
<td title="<?php echo $effort->consumed . ' ' . $lang->execution->workHour;?>"><?php echo $effort->consumed . ' ' . $lang->execution->workHourUnit;?></td>
|
||||
<td title="<?php echo $effort->left . ' ' . $lang->execution->workHour;?>"><?php echo $effort->left . ' ' . $lang->execution->workHourUnit;?></td>
|
||||
<td align='center' class='c-actions'>
|
||||
<?php
|
||||
$canOperateEffort = $this->task->canOperateEffort($task, $effort);
|
||||
common::printIcon($this->config->edition == 'open' ? 'task' : 'effort', $this->config->edition == 'open' ? 'editEstimate' : 'edit', "effortID=$effort->id", '', 'list', 'edit', '', 'showinonlybody', true, $canOperateEffort ? '' : 'disabled');
|
||||
common::printIcon($this->config->edition == 'open' ? 'task' : 'effort', $this->config->edition == 'open' ? 'deleteEstimate' : 'delete', "effortID=$effort->id", '', 'list', 'trash', 'hiddenwin', 'showinonlybody', false, ($canOperateEffort and $effort->left > 0) ? '' : 'disabled');
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endforeach;?>
|
||||
<?php if($myOrders):?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<?php endif;?>
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
<tr class='text-center'>
|
||||
<th class="w-120px"><?php echo $lang->task->date;?></th>
|
||||
<th class="w-120px"><?php echo $lang->task->recordedBy;?></th>
|
||||
<th><?php echo $lang->comment;?></th>
|
||||
<th><?php echo $lang->task->work;?></th>
|
||||
<th class="thWidth"><?php echo $lang->task->consumed;?></th>
|
||||
<th class="thWidth"><?php echo $lang->task->left;?></th>
|
||||
<th class='c-actions-2'><?php echo $lang->actions;?></th>
|
||||
@@ -97,24 +97,27 @@
|
||||
<table class='table table-form table-fixed table-record'>
|
||||
<thead>
|
||||
<tr class='text-center'>
|
||||
<th class="w-120px"><?php echo $lang->task->date;?></th>
|
||||
<th class="w-150px"><?php echo $lang->task->date;?></th>
|
||||
<?php if($readonly):?>
|
||||
<th class="w-60px"><?php echo $lang->task->teamOrder;?></th>
|
||||
<th class="w-60px <?php if(count($reverseOrders) == 1) echo "hidden"?>"><?php echo $lang->task->teamOrder;?></th>
|
||||
<?php endif;?>
|
||||
<th><?php echo $lang->comment;?></th>
|
||||
<th><?php echo $lang->task->work;?></th>
|
||||
<th class="w-100px"><?php echo $lang->task->consumedAB;?></th>
|
||||
<th class="w-100px"><?php echo $lang->task->leftAB;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php for($i = 1; $i <= 5; $i++):?>
|
||||
<?php for($i = 1; $i <= 3; $i++):?>
|
||||
<tr class="text-center">
|
||||
<td>
|
||||
<?php echo html::input("dates[$i]", helper::today(), "class='form-control text-center form-date'");?>
|
||||
<div class='input-group'>
|
||||
<?php echo html::input("dates[$i]", helper::today(), "class='form-control text-center form-date'");?>
|
||||
<span class='input-group-addon'><i class='icon icon-calendar'></i></span>
|
||||
</div>
|
||||
<?php echo html::hidden("id[$i]", $i);?>
|
||||
</td>
|
||||
<?php if($readonly):?>
|
||||
<td><?php echo html::select("order[$i]", $reverseOrders, '', "class='form-control'")?></td>
|
||||
<td class='<?php if(count($reverseOrders) == 1) echo "hidden"?>'><?php echo html::select("order[$i]", $reverseOrders, '', "class='form-control'")?></td>
|
||||
<?php endif;?>
|
||||
<td class="text-left"><?php echo html::textarea("work[$i]", '', "class='form-control' rows=1");?></td>
|
||||
<td>
|
||||
|
||||
@@ -531,7 +531,7 @@ class testreport extends control
|
||||
|
||||
$tasks = $report->tasks ? $this->testtask->getByList($report->tasks) : array();;
|
||||
$builds = $report->builds ? $this->build->getByList($report->builds) : array();
|
||||
$cases = $this->testreport->getTaskCases($tasks, $report->begin, $report->end);
|
||||
$cases = $this->testreport->getTaskCases($tasks, $report->begin, $report->end, $report->cases);
|
||||
|
||||
list($bugInfo, $bugSummary) = $this->testreport->getBug4Report($tasks, $report->product, $report->begin, $report->end, $builds);
|
||||
|
||||
|
||||
@@ -5,7 +5,4 @@
|
||||
.tab-pane > table {border: 1px solid #ddd;}
|
||||
.tab-pane > table:first-child {border-top: none;}
|
||||
.c-name {max-width: 100px;}
|
||||
|
||||
#cases .pager {margin: 0px;}
|
||||
#cases .pager li .btn.dropdown-toggle {border: 0px; padding-top: 3px;}
|
||||
#profile {vertical-align: unset;}
|
||||
|
||||
@@ -149,7 +149,7 @@ class testreportModel extends model
|
||||
$severityGroups = $statusGroups = $openedByGroups = $resolvedByGroups = $resolutionGroups = $moduleGroups = $typeGroups = $stageGoups = $handleGroups = array();
|
||||
|
||||
/* Init stageGroups. */
|
||||
$isEmptyStage = true;
|
||||
$stageGroups = array();
|
||||
foreach($this->lang->bug->priList as $priKey => $priValue)
|
||||
{
|
||||
$stageGroups[$priKey]['generated'] = 0;
|
||||
@@ -158,7 +158,7 @@ class testreportModel extends model
|
||||
}
|
||||
|
||||
/* Init handleGroups. */
|
||||
$isEmptyHandle = true;
|
||||
$handleGroups = array();
|
||||
$beginTimeStamp = strtotime($begin);
|
||||
$endTimeStamp = strtotime($end);
|
||||
for($i = $beginTimeStamp; $i <= $endTimeStamp; $i += 86400)
|
||||
@@ -220,8 +220,6 @@ class testreportModel extends model
|
||||
$resolvedDate = date('m-d', strtotime($bug->resolvedDate));
|
||||
$stageGroups[$bug->pri]['resolved'] += 1;
|
||||
$handleGroups['resolved'][$resolvedDate] += 1;
|
||||
$isEmptyStage = false;
|
||||
$isEmptyHandle = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,8 +233,6 @@ class testreportModel extends model
|
||||
$foundBugs[$bug->id] = $bug;
|
||||
$stageGroups[$bug->pri]['generated'] += 1;
|
||||
$handleGroups['generated'][$openedDate] += 1;
|
||||
$isEmptyStage = false;
|
||||
$isEmptyHandle = false;
|
||||
|
||||
if($bug->status == 'active' or $bug->resolvedDate > "$end 23:59:59")
|
||||
{
|
||||
@@ -279,8 +275,8 @@ class testreportModel extends model
|
||||
$bugSummary['countBugByTask'] = $byCaseNum;
|
||||
$bugSummary['bugConfirmedRate'] = empty($resolvedBugs) ? 0 : round((zget($resolutionGroups, 'fixed', 0) + zget($resolutionGroups, 'postponed', 0)) / $resolvedBugs * 100, 2);
|
||||
$bugSummary['bugCreateByCaseRate'] = empty($byCaseNum) ? 0 : round($byCaseNum / count($foundBugs) * 100, 2);
|
||||
$bugInfo['bugStageGroups'] = $isEmptyStage ? array() : $stageGroups;
|
||||
$bugInfo['bugHandleGroups'] = $isEmptyHandle ? array() : $handleGroups;
|
||||
$bugInfo['bugStageGroups'] = $stageGroups;
|
||||
$bugInfo['bugHandleGroups'] = $handleGroups;
|
||||
|
||||
$this->app->loadLang('bug');
|
||||
$users = $this->loadModel('user')->getPairs('noclosed|noletter|nodeleted');
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php $sysURL = $this->session->notHead ? common::getSysURL() : '';?>
|
||||
<style>.c-date {width: 130px;}</style>
|
||||
<table class='table main-table' id='cases'>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -46,14 +45,17 @@
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
</tbody>
|
||||
<?php if(isset($pager)):?>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td class='text-right' colspan='9'><?php $pager->show('right', 'pagerjs');?></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
<?php endif;?>
|
||||
</table>
|
||||
<?php if(isset($pager)):?>
|
||||
<div class='table-footer'>
|
||||
<?php $pager->show('right', 'pagerjs');?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<?php else:?>
|
||||
<tr><td class='none-data' colspan='9'><?php echo $lang->testreport->none;?></td></tr>
|
||||
<?php endif;?>
|
||||
</table>
|
||||
<style>
|
||||
.c-date {width: 130px;}
|
||||
#cases + .table-footer {margin-top: -20px;}
|
||||
</style>
|
||||
|
||||
Regular → Executable
+3
-2
@@ -2112,8 +2112,9 @@ class testtaskModel extends model
|
||||
if(!isset($suites[$suiteIndex])) $suites[$suiteIndex] = $suite;
|
||||
|
||||
$case = new stdclass();
|
||||
if(!empty($caseResult->id)) $case->id = $caseResult->id;
|
||||
$case->product = $productID;
|
||||
$case->title = $caseResult->title;
|
||||
if(empty($caseResult->id)) $case->title = $caseResult->title;
|
||||
$case->pri = 3;
|
||||
$case->type = 'unit';
|
||||
$case->stage = 'unittest';
|
||||
@@ -2121,7 +2122,7 @@ class testtaskModel extends model
|
||||
$case->openedBy = $this->app->user->account;
|
||||
$case->openedDate = $now;
|
||||
$case->version = 1;
|
||||
$case->auto = 'unit';
|
||||
if(empty($caseResult->id)) $case->auto = 'unit';
|
||||
$case->frame = $frame;
|
||||
|
||||
$result = new stdclass();
|
||||
|
||||
@@ -76,6 +76,4 @@ $(document).ready(function()
|
||||
{
|
||||
toggleCopy(false);
|
||||
$('[data-id="edit"] a').modalTrigger({type: 'iframe', width: 500});
|
||||
|
||||
parent.$('#triggerModal .modal-content .modal-header .close').on('click', function(){parent.location.reload();});
|
||||
});
|
||||
|
||||
@@ -335,6 +335,8 @@ $(function()
|
||||
if(window.config.viewType == 'line') $('#modulemenu > .nav > li > a[href*=product][href*=all]').parent('li[data-id=all]').addClass('active');
|
||||
if(viewType == 'case' || viewType == 'caselib') $('#subNavbar li[data-id="' + viewType +'"]').addClass('active');
|
||||
});
|
||||
|
||||
if("<?php $from == 'doc'?>") parent.$('#triggerModal .modal-content .modal-header .close').on('click', function(){parent.location.reload();});
|
||||
</script>
|
||||
<style>
|
||||
.module-name {display: inline-block; max-width: calc(100% - 85px); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;}
|
||||
|
||||
@@ -131,7 +131,6 @@ class upgradeModel extends model
|
||||
/* Means open source/pro upgrade to biz or max. */
|
||||
if($this->config->edition != 'open')
|
||||
{
|
||||
if($fromEdition == 'open') $this->convertEstToEffort();
|
||||
if($fromEdition == 'open' or $fromEdition == 'pro')
|
||||
{
|
||||
$this->importBuildinModules();
|
||||
@@ -6814,14 +6813,13 @@ class upgradeModel extends model
|
||||
public function processCreatedInfo()
|
||||
{
|
||||
$objectTypes = array('productplan', 'release', 'testtask', 'build');
|
||||
$tables = array('productplan' => TABLE_PRODUCTPLAN, 'release' => TABLE_RELEASE, 'testtask' => TABLE_TESTTASK, 'build' => TABLE_BUILD);
|
||||
|
||||
$actions = $this->dao->select('objectType, objectID, actor, date')->from(TABLE_ACTION)->where('objectType')->in($objectTypes)->andWhere('action')->eq('opened')->fetchGroup('objectType');
|
||||
foreach($actions as $objectType => $objectActions)
|
||||
{
|
||||
foreach($objectActions as $action)
|
||||
{
|
||||
$this->dao->update($tables[$objectType])->set('createdBy')->eq($action->actor)->set('createdDate')->eq($action->date)->where('id')->eq($action->objectID)->exec();
|
||||
$this->dao->update($this->config->objectTables[$objectType])->set('createdBy')->eq($action->actor)->set('createdDate')->eq($action->date)->where('id')->eq($action->objectID)->exec();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7248,7 +7246,7 @@ class upgradeModel extends model
|
||||
|
||||
/**
|
||||
* Process feedback module
|
||||
*
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
@@ -7298,7 +7296,7 @@ class upgradeModel extends model
|
||||
/* Delete history module */
|
||||
$this->dao->delete()->from(TABLE_MODULE)->where('type')->eq('feedback')->andWhere('root')->eq(0)->exec();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert task team to table: zt_taskteam.
|
||||
*
|
||||
@@ -7320,7 +7318,8 @@ class upgradeModel extends model
|
||||
|
||||
$this->dao->insert(TABLE_TASKTEAM)->data($oldTeam)->exec();
|
||||
|
||||
$this->dao->update(TABLE_EFFORT)->set('`order`')->eq($order)->where('objectType')->eq('task')->andWhere('objectID')->eq($oldTeam->task)->exec();
|
||||
$this->dao->update(TABLE_TASKESTIMATE)->set('`order`')->eq($order)->where('task')->($oldTeam->task)->andWhere('account')->eq($oldTeam->account)->exec();
|
||||
$this->dao->update(TABLE_EFFORT)->set('`order`')->eq($order)->where('objectType')->eq('task')->andWhere('objectID')->eq($oldTeam->task)->andWhere('account')->eq($oldTeam->account)->exec();
|
||||
$order ++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,14 +90,19 @@ $(function()
|
||||
var password2Encrypted = false
|
||||
$('#password1').change(function(){password1Encrypted = false});
|
||||
$('#password2').change(function(){password2Encrypted = false});
|
||||
|
||||
var passwordStrength = 0;
|
||||
$('#submit').click(function()
|
||||
{
|
||||
if(!password1Encrypted || !password2Encrypted)
|
||||
{
|
||||
var password1 = $('#password1').val();
|
||||
var password2 = $('#password2').val();
|
||||
var passwordStrength = computePasswordStrength(password1);
|
||||
if(!password1Encrypted) $("#passwordLength").val(password1.length);
|
||||
var password1 = $('#password1').val();
|
||||
var password2 = $('#password2').val();
|
||||
if(!password1Encrypted)
|
||||
{
|
||||
passwordStrength = computePasswordStrength(password1);
|
||||
$("#passwordLength").val(password1.length);
|
||||
}
|
||||
|
||||
if($("form input[name=passwordStrength]").length == 0) $('#submit').after("<input type='hidden' name='passwordStrength' value='0' />");
|
||||
$("form input[name=passwordStrength]").val(passwordStrength);
|
||||
|
||||
@@ -4,14 +4,19 @@ $(function()
|
||||
var password2Encrypted = false
|
||||
$('#password1').change(function(){password1Encrypted = false});
|
||||
$('#password2').change(function(){password2Encrypted = false});
|
||||
|
||||
var passwordStrength = 0;
|
||||
$('#submit').click(function()
|
||||
{
|
||||
if(!password1Encrypted || !password2Encrypted)
|
||||
{
|
||||
var password1 = $('#password1').val().trim();
|
||||
var password2 = $('#password2').val().trim();
|
||||
var passwordStrength = computePasswordStrength(password1);
|
||||
if(!password1Encrypted) $("#passwordLength").val(password1.length);
|
||||
if(!password1Encrypted)
|
||||
{
|
||||
passwordStrength = computePasswordStrength(password1);
|
||||
$("#passwordLength").val(password1.length);
|
||||
}
|
||||
|
||||
if($("form input[name=passwordStrength]").length == 0) $('#submit').after("<input type='hidden' name='passwordStrength' value='0' />");
|
||||
$("form input[name=passwordStrength]").val(passwordStrength);
|
||||
|
||||
@@ -4,13 +4,15 @@ $(document).ready(function()
|
||||
var password2Encrypted = false
|
||||
$('#password1').change(function(){password1Encrypted = false});
|
||||
$('#password2').change(function(){password2Encrypted = false});
|
||||
|
||||
var passwordStrength = 0;
|
||||
$('form #submit').click(function()
|
||||
{
|
||||
if(!password1Encrypted || !password2Encrypted)
|
||||
{
|
||||
var password1 = $('#password1').val().trim();
|
||||
var password2 = $('#password2').val().trim();
|
||||
var passwordStrength = computePasswordStrength(password1);
|
||||
if(!password1Encrypted) passwordStrength = computePasswordStrength(password1);
|
||||
|
||||
if($("form input[name=passwordStrength]").length == 0) $('#submit').after("<input type='hidden' name='passwordStrength' value='0' />");
|
||||
$("form input[name=passwordStrength]").val(passwordStrength);
|
||||
|
||||
@@ -14,14 +14,19 @@ $(function()
|
||||
var password2Encrypted = false
|
||||
$('#password1').change(function(){password1Encrypted = false});
|
||||
$('#password2').change(function(){password2Encrypted = false});
|
||||
|
||||
var passwordStrength = 0;
|
||||
$('#submit').click(function()
|
||||
{
|
||||
if(!password1Encrypted || !password2Encrypted)
|
||||
{
|
||||
var password1 = $('#password1').val().trim();
|
||||
var password2 = $('#password2').val().trim();
|
||||
var passwordStrength = computePasswordStrength(password1);
|
||||
if(!password1Encrypted) $("#passwordLength").val(password1.length);
|
||||
if(!password1Encrypted)
|
||||
{
|
||||
passwordStrength = computePasswordStrength(password1);
|
||||
$("#passwordLength").val(password1.length);
|
||||
}
|
||||
|
||||
if($("form input[name=passwordStrength]").length == 0) $('#submit').after("<input type='hidden' name='passwordStrength' value='0' />");
|
||||
$("form input[name=passwordStrength]").val(passwordStrength);
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php include '../../common/view/datepicker.html.php';?>
|
||||
<?php js::import($jsRoot . 'md5.js');?>
|
||||
<?php $lang->user->placeholder->password1 = zget($lang->user->placeholder->passwordStrength, $config->safe->mode, '');?>
|
||||
<?php $lang->user->placeholder->password1 = zget($lang->user->placeholder->passwordStrength, !empty($config->safe->mode) ? $config->safe->mode : 0, '');?>
|
||||
<?php js::set('holders', $lang->user->placeholder);?>
|
||||
<?php js::set('roleGroup', $roleGroup);?>
|
||||
<?php
|
||||
@@ -54,7 +54,7 @@ $showVisionList = count($visionList) > 1;
|
||||
<td>
|
||||
<input type='password' style="display:none"> <!-- for disable autocomplete all browser -->
|
||||
<span class='input-group'>
|
||||
<?php echo html::password('password1', '', "class='form-control' onmouseup='checkPassword(this.value)' onkeyup='checkPassword(this.value)'");?>
|
||||
<?php echo html::password('password1', '', "class='form-control' onkeyup='checkPassword(this.value)'");?>
|
||||
<span class='input-group-addon' id='passwordStrength'></span>
|
||||
</span>
|
||||
</td>
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
<td>
|
||||
<input type='password' style="display:none"> <!-- Disable input password by browser automatically. -->
|
||||
<span class='input-group'>
|
||||
<?php echo html::password('password1', '', "class='form-control disabled-ie-placeholder' onmouseup='checkPassword(this.value)' onkeyup='checkPassword(this.value)' placeholder='" . zget($lang->user->placeholder->passwordStrength, $config->safe->mode, '') . "'");?>
|
||||
<?php echo html::password('password1', '', "class='form-control disabled-ie-placeholder' onkeyup='checkPassword(this.value)' placeholder='" . zget($lang->user->placeholder->passwordStrength, $config->safe->mode, '') . "'");?>
|
||||
<span class='input-group-addon' id='passwordStrength'></span>
|
||||
</span>
|
||||
</td>
|
||||
|
||||
@@ -29,7 +29,7 @@ include '../../common/view/header.lite.html.php';
|
||||
<div class='form-group'>
|
||||
<label for='password1'><?php echo $lang->user->password;?></label>
|
||||
<span class='input-group'>
|
||||
<?php echo html::password('password1', '', "class='form-control' required placeholder='" . zget($lang->user->placeholder->loginPassword, $config->safe->mode, '') . "' onmouseup='checkPassword(this.value)' onkeyup='checkPassword(this.value)'");?>
|
||||
<?php echo html::password('password1', '', "class='form-control' required placeholder='" . zget($lang->user->placeholder->loginPassword, $config->safe->mode, '') . "' onkeyup='checkPassword(this.value)'");?>
|
||||
<span class='input-group-addon' id='passwordStrength'></span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -212,6 +212,7 @@ class weeklyModel extends model
|
||||
->andWhere('execution')->in($executionIdList)
|
||||
->andWhere('date')->ge($monday)
|
||||
->andWhere('date')->le($sunday)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetch('count');
|
||||
}
|
||||
|
||||
@@ -239,6 +240,7 @@ class weeklyModel extends model
|
||||
->andWhere("(status='done' or closedReason= 'done')")
|
||||
->andWhere('finishedDate')->ge($monday)
|
||||
->andWhere('finishedDate')->le($sunday)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetchAll();
|
||||
return $this->loadModel('task')->processTasks($tasks);
|
||||
}
|
||||
@@ -266,6 +268,7 @@ class weeklyModel extends model
|
||||
->andWhere('status')->in('wait,doing,pause')
|
||||
->andWhere('deadline')->ge($monday)
|
||||
->andWhere('deadline')->le($sunday)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetchAll('id');
|
||||
|
||||
$postponed = $this->dao->select('*')
|
||||
@@ -274,6 +277,7 @@ class weeklyModel extends model
|
||||
->andWhere('finishedDate')->gt($nextMonday)
|
||||
->andWhere('deadline')->ge($monday)
|
||||
->andWhere('deadline')->lt($nextMonday)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetchAll('id');
|
||||
|
||||
$tasks = array_merge($unFinished, $postponed);
|
||||
@@ -302,6 +306,7 @@ class weeklyModel extends model
|
||||
->from(TABLE_TASK)
|
||||
->where('execution')->in($executionIdList)
|
||||
->andWhere("((deadline > '$nextMonday' and deadline < '$sencondMondy') or (estStarted > '$nextMonday' and estStarted < '$sencondMondy'))")
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetchAll('id');
|
||||
|
||||
return $this->loadModel('task')->processTasks($tasks);
|
||||
@@ -329,6 +334,7 @@ class weeklyModel extends model
|
||||
return $this->dao->select('type, sum(cast(estimate as decimal(10,2))) as workload')
|
||||
->from(TABLE_TASK)
|
||||
->where('execution')->in($executionIdList)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->groupBy('type')
|
||||
->fetchPairs();
|
||||
}
|
||||
@@ -354,6 +360,7 @@ class weeklyModel extends model
|
||||
->from(TABLE_TASK)
|
||||
->where('execution')->in($executionIdList)
|
||||
->andWhere('deadline')->ge($monday)
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetchAll('id');
|
||||
}
|
||||
|
||||
@@ -384,8 +391,7 @@ class weeklyModel extends model
|
||||
->where('execution')->in($executionIdList)
|
||||
->andWhere("parent")->ge(0)
|
||||
->andWhere("deleted")->eq(0)
|
||||
->andWhere("estStarted")->ge($monday)
|
||||
->andWhere("estStarted")->lt($nextMonday)
|
||||
->andWhere("((estStarted >= '$monday' AND estStarted < '$nextMonday') OR (deadline >= '$monday' AND deadline < '$nextMonday') OR (estStarted < '$monday' AND deadline > '$nextMonday'))")
|
||||
->fetchAll('id');
|
||||
|
||||
$PV = 0;
|
||||
@@ -490,6 +496,7 @@ class weeklyModel extends model
|
||||
->andWhere('execution')->in($executionIdList)
|
||||
->andWhere('date')->ge($monday)
|
||||
->andWhere('date')->lt($nextMonday)
|
||||
->andWhere('deleted')->eq('0')
|
||||
->fetch('consumed');
|
||||
|
||||
if(is_null($AC)) $AC = 0;
|
||||
|
||||
+19
-138
@@ -363,76 +363,6 @@ class executionTest
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the workload format and total.
|
||||
*
|
||||
* @param int $executionID
|
||||
* @param string $type
|
||||
* @param int $percent
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function checkWorkloadTest($executionID = 0, $type = '', $percent = 0)
|
||||
{
|
||||
global $tester;
|
||||
$tester->app->loadLang('programplan');
|
||||
$_POST['products'] = array(1, 81, 91);
|
||||
$_POST['percent'] = $percent;
|
||||
$_POST['parent'] = 0;
|
||||
|
||||
$oldExecution = $executionID ? $this->objectModel->getByID($executionID) : '';
|
||||
if(!empty($oldExecution->parent)) $_POST['parent'] = $oldExecution->parent;
|
||||
|
||||
$result = $this->objectModel->checkWorkload($type, $percent, $oldExecution);
|
||||
if(dao::isError()) return dao::getError(true);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check begin and end date.
|
||||
*
|
||||
* @param int $projectID
|
||||
* @param string $checkType empty|normal|gt|lt|eq
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function checkBeginAndEndDateTest($projectID, $checkType)
|
||||
{
|
||||
if($projectID) $project = $this->objectModel->getByID($projectID);
|
||||
switch($checkType)
|
||||
{
|
||||
case 'empty':
|
||||
$_POST['begin'] = '';
|
||||
$_POST['end'] = '';
|
||||
break;
|
||||
case 'normal':
|
||||
$_POST['begin'] = empty($project->begin) ? '' : date("Y-m-d",strtotime("+1 days",strtotime($project->begin)));
|
||||
$_POST['end'] = empty($project->end) ? '' : date("Y-m-d",strtotime("-1 days",strtotime($project->end)));
|
||||
break;
|
||||
case 'lt':
|
||||
$_POST['begin'] = empty($project->begin) ? '' : date("Y-m-d",strtotime("-1 days",strtotime($project->begin)));
|
||||
$_POST['end'] = empty($project->end) ? '' : date("Y-m-d",strtotime("-1 days",strtotime($project->end)));
|
||||
break;
|
||||
case 'gt':
|
||||
$_POST['begin'] = empty($project->begin) ? '' : date("Y-m-d",strtotime("+1 days",strtotime($project->begin)));
|
||||
$_POST['end'] = empty($project->end) ? '' : date("Y-m-d",strtotime("+1 days",strtotime($project->end)));
|
||||
break;
|
||||
case 'eq':
|
||||
$_POST['begin'] = empty($project->begin) ? '' : $project->begin;
|
||||
$_POST['end'] = empty($project->end) ? '' : $project->end;
|
||||
break;
|
||||
}
|
||||
|
||||
$begin = $_POST['begin'];
|
||||
$end = $_POST['end'];
|
||||
|
||||
$this->objectModel->checkBeginAndEndDate($projectID, $begin, $end);
|
||||
if(dao::isError()) return dao::getError(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* function getPairs test by execution
|
||||
*
|
||||
@@ -1225,6 +1155,25 @@ class executionTest
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Link all stories by execution.
|
||||
*
|
||||
* @param int $executionID
|
||||
* @param int $productID
|
||||
* @param int $planID
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function linkStoriesTest($executionID, $productID = 0, $planID = 0)
|
||||
{
|
||||
global $tester;
|
||||
if($planID) $tester->dao->update(TABLE_PROJECTPRODUCT)->set('plan')->eq($planID)->where('project')->eq($executionID)->andWhere('product')->eq($productID)->exec();
|
||||
|
||||
$this->objectModel->linkStories($executionID);
|
||||
$objects = $tester->dao->select('*')->from(TABLE_PROJECTSTORY)->where('project')->eq($executionID)->andWhere('product')->eq($productID)->fetchAll();
|
||||
return count($objects);
|
||||
}
|
||||
|
||||
/**
|
||||
* function linkCases test by execution
|
||||
*
|
||||
@@ -1398,41 +1347,6 @@ class executionTest
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* function getTeamSkip test by execution
|
||||
*
|
||||
* @param string $taskID
|
||||
* @param string $begin
|
||||
* @param string $end
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getTeamSkipTest($taskID, $begin, $end)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
$teams = $tester->dao->select('*')->from(TABLE_TEAM)->where('root')->eq($taskID)->andWhere('type')->eq('task')->orderBy('order')->fetchAll('account');
|
||||
|
||||
$object = $this->objectModel->getTeamSkip($teams, $begin, $end);
|
||||
|
||||
if(dao::isError())
|
||||
{
|
||||
$error = dao::getError();
|
||||
return $error;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(empty($object))
|
||||
{
|
||||
return '无跳转数据';
|
||||
}
|
||||
else
|
||||
{
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* function getTeams2Import test by execution
|
||||
*
|
||||
@@ -2208,39 +2122,6 @@ class executionTest
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get execution burn data.
|
||||
*
|
||||
* @param array $executionIDList
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getBurnDataTest($executionIDList)
|
||||
{
|
||||
global $tester;
|
||||
|
||||
$executions = $this->objectModel->getByIdList($executionIDList);
|
||||
$objects = $this->objectModel->getBurnData($executions);
|
||||
|
||||
$returns = array();
|
||||
foreach($objects as $executionID => $burnData)
|
||||
{
|
||||
$returns[$executionID] = '';
|
||||
foreach($burnData as $data) $returns[$executionID] .= ",$data->value";
|
||||
$returns[$executionID] = trim($returns[$executionID], ',');
|
||||
}
|
||||
|
||||
if(dao::isError())
|
||||
{
|
||||
$error = dao::getError();
|
||||
return $error;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $returns;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get begin and end for CFD.
|
||||
*
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 executionModel->checkBeginAndEndDate();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
测试传入空值 >> 1
|
||||
测试检查正常的日期 >> 1
|
||||
测试检查小于开始的日期 >> 迭代开始日期应大于等于项目的开始日期:2022-05-26。\n
|
||||
测试检查大于开始的日期 >> 迭代截止日期应小于等于项目的截止日期:2022-09-30。\n
|
||||
测试检查等于开始跟结束的日期 >> 1
|
||||
|
||||
*/
|
||||
|
||||
$projectIdList = array(0, 11);
|
||||
$checkType = array('empty', 'normal', 'lt', 'gt', 'eq');
|
||||
|
||||
$execution = new executionTest();
|
||||
|
||||
r($execution->checkBeginAndEndDateTest($projectIdList[0], $checkType[0])) && p() && e('1'); // 测试传入空值
|
||||
r($execution->checkBeginAndEndDateTest($projectIdList[1], $checkType[1])) && p() && e('1'); // 测试检查正常的日期
|
||||
r($execution->checkBeginAndEndDateTest($projectIdList[1], $checkType[2])) && p() && e('迭代开始日期应大于等于项目的开始日期:2022-05-26。\n'); // 测试检查小于开始的日期
|
||||
r($execution->checkBeginAndEndDateTest($projectIdList[1], $checkType[3])) && p() && e('迭代截止日期应小于等于项目的截止日期:2022-09-30。\n'); // 测试检查大于开始的日期
|
||||
r($execution->checkBeginAndEndDateTest($projectIdList[1], $checkType[4])) && p() && e('1'); // 测试检查等于开始跟结束的日期
|
||||
@@ -1,71 +0,0 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试 executionModel->checkWorkload();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
测试传入空数据 >> 0
|
||||
测试创建迭代的工作量 >> 0
|
||||
测试创建迭代的工作量 >> 工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n
|
||||
测试创建迭代的工作量 >> "工作量比例"必须为数字\n
|
||||
测试创建迭代的工作量 >> 0
|
||||
测试更新迭代的工作量 >> 0
|
||||
测试更新迭代的工作量 >> 工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n
|
||||
测试更新迭代的工作量 >> "工作量比例"必须为数字\n
|
||||
测试更新迭代的工作量 >> 0
|
||||
测试创建阶段的工作量 >> 0
|
||||
测试创建阶段的工作量 >> 工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n
|
||||
测试创建阶段的工作量 >> "工作量比例"必须为数字\n
|
||||
测试创建阶段的工作量 >> 0
|
||||
测试更新阶段的工作量 >> 0
|
||||
测试更新阶段的工作量 >> 工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n
|
||||
测试更新阶段的工作量 >> "工作量比例"必须为数字\n
|
||||
测试更新阶段的工作量 >> 0
|
||||
测试创建看板的工作量 >> 0
|
||||
测试创建看板的工作量 >> 工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n
|
||||
测试创建看板的工作量 >> "工作量比例"必须为数字\n
|
||||
测试创建看板的工作量 >> 0
|
||||
测试更新看板的工作量 >> 0
|
||||
测试更新看板的工作量 >> 工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n
|
||||
测试更新看板的工作量 >> "工作量比例"必须为数字\n
|
||||
测试更新看板的工作量 >> 0
|
||||
|
||||
*/
|
||||
|
||||
$executionIdList = array(0, 101, 131, 161);
|
||||
$typeList = array('', 'create', 'update');
|
||||
$percentList = array('0', '123', 'all', '10');
|
||||
|
||||
$execution = new executionTest();
|
||||
|
||||
r($execution->checkWorkloadTest($executionIdList[0], $typeList[0], $percentList[0])) && p() && e('0'); // 测试传入空数据
|
||||
r($execution->checkWorkloadTest($executionIdList[1], $typeList[1], $percentList[0])) && p() && e('0'); // 测试创建迭代的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[1], $typeList[1], $percentList[1])) && p() && e('工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n'); // 测试创建迭代的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[1], $typeList[1], $percentList[2])) && p() && e('"工作量比例"必须为数字\n'); // 测试创建迭代的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[1], $typeList[1], $percentList[3])) && p() && e('0'); // 测试创建迭代的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[1], $typeList[2], $percentList[0])) && p() && e('0'); // 测试更新迭代的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[1], $typeList[2], $percentList[1])) && p() && e('工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n'); // 测试更新迭代的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[1], $typeList[2], $percentList[2])) && p() && e('"工作量比例"必须为数字\n'); // 测试更新迭代的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[1], $typeList[2], $percentList[3])) && p() && e('0'); // 测试更新迭代的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[2], $typeList[1], $percentList[0])) && p() && e('0'); // 测试创建阶段的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[2], $typeList[1], $percentList[1])) && p() && e('工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n'); // 测试创建阶段的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[2], $typeList[1], $percentList[2])) && p() && e('"工作量比例"必须为数字\n'); // 测试创建阶段的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[2], $typeList[1], $percentList[3])) && p() && e('0'); // 测试创建阶段的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[2], $typeList[2], $percentList[0])) && p() && e('0'); // 测试更新阶段的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[2], $typeList[2], $percentList[1])) && p() && e('工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n'); // 测试更新阶段的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[2], $typeList[2], $percentList[2])) && p() && e('"工作量比例"必须为数字\n'); // 测试更新阶段的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[2], $typeList[2], $percentList[3])) && p() && e('0'); // 测试更新阶段的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[3], $typeList[1], $percentList[0])) && p() && e('0'); // 测试创建看板的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[3], $typeList[1], $percentList[1])) && p() && e('工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n'); // 测试创建看板的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[3], $typeList[1], $percentList[2])) && p() && e('"工作量比例"必须为数字\n'); // 测试创建看板的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[3], $typeList[1], $percentList[3])) && p() && e('0'); // 测试创建看板的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[3], $typeList[2], $percentList[0])) && p() && e('0'); // 测试更新看板的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[3], $typeList[2], $percentList[1])) && p() && e('工作量占比累计不应当超过100, 当前产品下的工作量之和为%\n'); // 测试更新看板的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[3], $typeList[2], $percentList[2])) && p() && e('"工作量比例"必须为数字\n'); // 测试更新看板的工作量
|
||||
r($execution->checkWorkloadTest($executionIdList[3], $typeList[2], $percentList[3])) && p() && e('0'); // 测试更新看板的工作量
|
||||
@@ -1,26 +0,0 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=executionModel->getBurnData();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
测试获取 执行ID 101 102 的燃尽图 >> 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,36,36,36,36,36,36,36,36,36,36,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,null
|
||||
测试获取 执行ID 101 103 111 的燃尽图 >> 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,36,36,36,36,36,36,36,36,36,36,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,23,23,23,23,23,23,23,23,23,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,null
|
||||
测试获取 执行ID 111 121 131 的燃尽图 >> 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,null;17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,null
|
||||
测试获取 执行ID 101 102 103 111 121 131 的燃尽图 >> 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,36,36,36,36,36,36,36,36,36,36,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,23,23,23,23,23,23,23,23,23,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,null;17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,null
|
||||
|
||||
*/
|
||||
|
||||
$executionIDList = array(array(101, 102), array(101, 103, 111), array(111, 121, 131), array(101, 102, 103, 111, 121, 131));
|
||||
|
||||
$execution = new executionTest();
|
||||
r($execution->getBurnDataTest($executionIDList[0])) && p('101;102') && e('21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,36,36,36,36,36,36,36,36,36,36,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,null'); // 测试获取 执行ID 101 102 的燃尽图
|
||||
r($execution->getBurnDataTest($executionIDList[1])) && p('101;103;111') && e('21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,36,36,36,36,36,36,36,36,36,36,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,23,23,23,23,23,23,23,23,23,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,null'); // 测试获取 执行ID 101 103 111 的燃尽图
|
||||
r($execution->getBurnDataTest($executionIDList[2])) && p('111;121;131') && e('0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,null;17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,null'); // 测试获取 执行ID 111 121 131 的燃尽图
|
||||
r($execution->getBurnDataTest($executionIDList[3])) && p('101;102;103;111;121;131') && e('21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,36,36,36,36,36,36,36,36,36,36,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,23,23,23,23,23,23,23,23,23,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,null;0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,27,27,27,27,27,27,27,27,27,null;17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,null'); // 测试获取 执行ID 101 102 103 111 121 131 的燃尽图
|
||||
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
@@ -10,22 +10,22 @@ title=executionModel->getSearchTasks();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
测试通过sql语句获取3个任务 id 倒序 execution = '101' and deleted = '0' and parent >= 0 >> 910:name:子任务10;909:name:子任务9,team:[930,920];908:name:子任务8,team:[919,929];
|
||||
测试通过sql语句获取3个任务 id 正序 execution = '101' and deleted = '0' and parent >= 0 >> 1:name:开发任务11,team:[911,921];901:name:子任务1,team:[922,912];902:name:子任务2,team:[923,913];
|
||||
测试通过sql语句获取5个任务 id 倒序 execution = '101' and deleted = '0' and parent >= 0 >> 910:name:子任务10;909:name:子任务9,team:[930,920];908:name:子任务8,team:[919,929];907:name:子任务7,team:[918,928];906:name:子任务6,team:[927,917];
|
||||
测试通过sql语句获取5个任务 id 正序 execution = '101' and deleted = '0' and parent >= 0 >> 1:name:开发任务11,team:[911,921];901:name:子任务1,team:[922,912];902:name:子任务2,team:[923,913];903:name:子任务3,team:[914,924];904:name:子任务4,team:[915,925];
|
||||
测试通过sql语句获取3个任务 id 倒序 execution = '101' and deleted = '0' and parent >= 0 >> 910:name:子任务10;909:name:子任务9;908:name:子任务8;
|
||||
测试通过sql语句获取3个任务 id 正序 execution = '101' and deleted = '0' and parent >= 0 >> 1:name:开发任务11;901:name:子任务1;902:name:子任务2;
|
||||
测试通过sql语句获取5个任务 id 倒序 execution = '101' and deleted = '0' and parent >= 0 >> 910:name:子任务10;909:name:子任务9;908:name:子任务8;907:name:子任务7;906:name:子任务6;
|
||||
测试通过sql语句获取5个任务 id 正序 execution = '101' and deleted = '0' and parent >= 0 >> 1:name:开发任务11;901:name:子任务1;902:name:子任务2;903:name:子任务3;904:name:子任务4;
|
||||
测试通过sql语句获取3个任务 id 倒序 type = 'devel' and fromBug != '0' and parent >= 0 >> 0
|
||||
测试通过sql语句获取3个任务 id 正序 type = 'devel' and fromBug != '0' and parent >= 0 >> 0
|
||||
测试通过sql语句获取5个任务 id 倒序 type = 'devel' and fromBug != '0' and parent >= 0 >> 0
|
||||
测试通过sql语句获取5个任务 id 正序 type = 'devel' and fromBug != '0' and parent >= 0 >> 0
|
||||
测试通过sql语句获取3个任务 id 倒序 execution = '101' and story != '0' and parent >= 0 >> 1:name:开发任务11,team:[911,921];
|
||||
测试通过sql语句获取3个任务 id 正序 execution = '101' and story != '0' and parent >= 0 >> 1:name:开发任务11,team:[911,921];
|
||||
测试通过sql语句获取5个任务 id 倒序 execution = '101' and story != '0' and parent >= 0 >> 1:name:开发任务11,team:[911,921];
|
||||
测试通过sql语句获取5个任务 id 正序 execution = '101' and story != '0' and parent >= 0 >> 1:name:开发任务11,team:[911,921];
|
||||
测试通过sql语句获取3个任务 id 倒序 module like '%2%' and type = 'design' and parent >= 0 >> 909:name:子任务9,team:[930,920];901:name:子任务1,team:[922,912];801:name:更多任务201;
|
||||
测试通过sql语句获取3个任务 id 正序 module like '%2%' and type = 'design' and parent >= 0 >> 1:name:开发任务11,team:[911,921];65:name:开发任务75;73:name:开发任务83;
|
||||
测试通过sql语句获取5个任务 id 倒序 module like '%2%' and type = 'design' and parent >= 0 >> 909:name:子任务9,team:[930,920];901:name:子任务1,team:[922,912];801:name:更多任务201;769:name:更多任务169;737:name:更多任务137;
|
||||
测试通过sql语句获取5个任务 id 正序 module like '%2%' and type = 'design' and parent >= 0 >> 1:name:开发任务11,team:[911,921];65:name:开发任务75;73:name:开发任务83;81:name:开发任务91;89:name:开发任务99;
|
||||
测试通过sql语句获取3个任务 id 倒序 execution = '101' and story != '0' and parent >= 0 >> 1:name:开发任务11;
|
||||
测试通过sql语句获取3个任务 id 正序 execution = '101' and story != '0' and parent >= 0 >> 1:name:开发任务11;
|
||||
测试通过sql语句获取5个任务 id 倒序 execution = '101' and story != '0' and parent >= 0 >> 1:name:开发任务11;
|
||||
测试通过sql语句获取5个任务 id 正序 execution = '101' and story != '0' and parent >= 0 >> 1:name:开发任务11;
|
||||
测试通过sql语句获取3个任务 id 倒序 module like '%2%' and type = 'design' and parent >= 0 >> 909:name:子任务9;901:name:子任务1;801:name:更多任务201;
|
||||
测试通过sql语句获取3个任务 id 正序 module like '%2%' and type = 'design' and parent >= 0 >> 1:name:开发任务11;65:name:开发任务75;73:name:开发任务83;
|
||||
测试通过sql语句获取5个任务 id 倒序 module like '%2%' and type = 'design' and parent >= 0 >> 909:name:子任务9;901:name:子任务1;801:name:更多任务201;769:name:更多任务169;737:name:更多任务137;
|
||||
测试通过sql语句获取5个任务 id 正序 module like '%2%' and type = 'design' and parent >= 0 >> 1:name:开发任务11;65:name:开发任务75;73:name:开发任务83;81:name:开发任务91;89:name:开发任务99;
|
||||
|
||||
*/
|
||||
|
||||
@@ -40,19 +40,19 @@ $orderBy = array('id_desc', 'id_asc');
|
||||
|
||||
|
||||
$execution = new executionTest();
|
||||
r($execution->getSearchTasksTest($condition[0], $recPerPage[0], $orderBy[0])) && p() && e('910:name:子任务10;909:name:子任务9,team:[930,920];908:name:子任务8,team:[919,929];'); // 测试通过sql语句获取3个任务 id 倒序 execution = '101' and deleted = '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[0], $recPerPage[0], $orderBy[1])) && p() && e('1:name:开发任务11,team:[911,921];901:name:子任务1,team:[922,912];902:name:子任务2,team:[923,913];'); // 测试通过sql语句获取3个任务 id 正序 execution = '101' and deleted = '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[0], $recPerPage[1], $orderBy[0])) && p() && e('910:name:子任务10;909:name:子任务9,team:[930,920];908:name:子任务8,team:[919,929];907:name:子任务7,team:[918,928];906:name:子任务6,team:[927,917];'); // 测试通过sql语句获取5个任务 id 倒序 execution = '101' and deleted = '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[0], $recPerPage[1], $orderBy[1])) && p() && e('1:name:开发任务11,team:[911,921];901:name:子任务1,team:[922,912];902:name:子任务2,team:[923,913];903:name:子任务3,team:[914,924];904:name:子任务4,team:[915,925];'); // 测试通过sql语句获取5个任务 id 正序 execution = '101' and deleted = '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[1], $recPerPage[0], $orderBy[0])) && p() && e('0'); // 测试通过sql语句获取3个任务 id 倒序 type = 'devel' and fromBug != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[1], $recPerPage[0], $orderBy[1])) && p() && e('0'); // 测试通过sql语句获取3个任务 id 正序 type = 'devel' and fromBug != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[1], $recPerPage[1], $orderBy[0])) && p() && e('0'); // 测试通过sql语句获取5个任务 id 倒序 type = 'devel' and fromBug != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[1], $recPerPage[1], $orderBy[1])) && p() && e('0'); // 测试通过sql语句获取5个任务 id 正序 type = 'devel' and fromBug != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[2], $recPerPage[0], $orderBy[0])) && p() && e('1:name:开发任务11,team:[911,921];'); // 测试通过sql语句获取3个任务 id 倒序 execution = '101' and story != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[2], $recPerPage[0], $orderBy[1])) && p() && e('1:name:开发任务11,team:[911,921];'); // 测试通过sql语句获取3个任务 id 正序 execution = '101' and story != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[2], $recPerPage[1], $orderBy[0])) && p() && e('1:name:开发任务11,team:[911,921];'); // 测试通过sql语句获取5个任务 id 倒序 execution = '101' and story != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[2], $recPerPage[1], $orderBy[1])) && p() && e('1:name:开发任务11,team:[911,921];'); // 测试通过sql语句获取5个任务 id 正序 execution = '101' and story != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[3], $recPerPage[0], $orderBy[0])) && p() && e('909:name:子任务9,team:[930,920];901:name:子任务1,team:[922,912];801:name:更多任务201;'); // 测试通过sql语句获取3个任务 id 倒序 module like '%2%' and type = 'design' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[3], $recPerPage[0], $orderBy[1])) && p() && e('1:name:开发任务11,team:[911,921];65:name:开发任务75;73:name:开发任务83;'); // 测试通过sql语句获取3个任务 id 正序 module like '%2%' and type = 'design' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[3], $recPerPage[1], $orderBy[0])) && p() && e('909:name:子任务9,team:[930,920];901:name:子任务1,team:[922,912];801:name:更多任务201;769:name:更多任务169;737:name:更多任务137;'); // 测试通过sql语句获取5个任务 id 倒序 module like '%2%' and type = 'design' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[3], $recPerPage[1], $orderBy[1])) && p() && e('1:name:开发任务11,team:[911,921];65:name:开发任务75;73:name:开发任务83;81:name:开发任务91;89:name:开发任务99;'); // 测试通过sql语句获取5个任务 id 正序 module like '%2%' and type = 'design' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[0], $recPerPage[0], $orderBy[0])) && p() && e('910:name:子任务10;909:name:子任务9;908:name:子任务8;'); // 测试通过sql语句获取3个任务 id 倒序 execution = '101' and deleted = '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[0], $recPerPage[0], $orderBy[1])) && p() && e('1:name:开发任务11;901:name:子任务1;902:name:子任务2;'); // 测试通过sql语句获取3个任务 id 正序 execution = '101' and deleted = '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[0], $recPerPage[1], $orderBy[0])) && p() && e('910:name:子任务10;909:name:子任务9;908:name:子任务8;907:name:子任务7;906:name:子任务6;'); // 测试通过sql语句获取5个任务 id 倒序 execution = '101' and deleted = '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[0], $recPerPage[1], $orderBy[1])) && p() && e('1:name:开发任务11;901:name:子任务1;902:name:子任务2;903:name:子任务3;904:name:子任务4;'); // 测试通过sql语句获取5个任务 id 正序 execution = '101' and deleted = '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[1], $recPerPage[0], $orderBy[0])) && p() && e('0'); // 测试通过sql语句获取3个任务 id 倒序 type = 'devel' and fromBug != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[1], $recPerPage[0], $orderBy[1])) && p() && e('0'); // 测试通过sql语句获取3个任务 id 正序 type = 'devel' and fromBug != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[1], $recPerPage[1], $orderBy[0])) && p() && e('0'); // 测试通过sql语句获取5个任务 id 倒序 type = 'devel' and fromBug != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[1], $recPerPage[1], $orderBy[1])) && p() && e('0'); // 测试通过sql语句获取5个任务 id 正序 type = 'devel' and fromBug != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[2], $recPerPage[0], $orderBy[0])) && p() && e('1:name:开发任务11;'); // 测试通过sql语句获取3个任务 id 倒序 execution = '101' and story != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[2], $recPerPage[0], $orderBy[1])) && p() && e('1:name:开发任务11;'); // 测试通过sql语句获取3个任务 id 正序 execution = '101' and story != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[2], $recPerPage[1], $orderBy[0])) && p() && e('1:name:开发任务11;'); // 测试通过sql语句获取5个任务 id 倒序 execution = '101' and story != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[2], $recPerPage[1], $orderBy[1])) && p() && e('1:name:开发任务11;'); // 测试通过sql语句获取5个任务 id 正序 execution = '101' and story != '0' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[3], $recPerPage[0], $orderBy[0])) && p() && e('909:name:子任务9;901:name:子任务1;801:name:更多任务201;'); // 测试通过sql语句获取3个任务 id 倒序 module like '%2%' and type = 'design' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[3], $recPerPage[0], $orderBy[1])) && p() && e('1:name:开发任务11;65:name:开发任务75;73:name:开发任务83;'); // 测试通过sql语句获取3个任务 id 正序 module like '%2%' and type = 'design' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[3], $recPerPage[1], $orderBy[0])) && p() && e('909:name:子任务9;901:name:子任务1;801:name:更多任务201;769:name:更多任务169;737:name:更多任务137;'); // 测试通过sql语句获取5个任务 id 倒序 module like '%2%' and type = 'design' and parent >= 0
|
||||
r($execution->getSearchTasksTest($condition[3], $recPerPage[1], $orderBy[1])) && p() && e('1:name:开发任务11;65:name:开发任务75;73:name:开发任务83;81:name:开发任务91;89:name:开发任务99;'); // 测试通过sql语句获取5个任务 id 正序 module like '%2%' and type = 'design' and parent >= 0
|
||||
|
||||
@@ -10,7 +10,8 @@ title=测试 executionModel->getTaskGroupByExecution();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
获取所有受限制的执行ID >> 1
|
||||
测试空数据 >> 0
|
||||
测试获取执行的任务 >> 3
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试executionModel->getTeamSkipTest();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
正常跳过 >> 901,user92,研发
|
||||
begin与end一致 >> 无跳转数据
|
||||
end与begin一致 >> 无跳转数据
|
||||
|
||||
*/
|
||||
|
||||
$taskID = 901;
|
||||
$begin = 'user92';
|
||||
$end = 'user93';
|
||||
|
||||
$execution = new executionTest();
|
||||
r($execution->getTeamSkipTest($taskID, $begin, $end)) && p('user92:root,account,role') && e('901,user92,研发'); // 正常跳过
|
||||
r($execution->getTeamSkipTest($taskID, $begin, $begin)) && p() && e('无跳转数据'); // begin与end一致
|
||||
r($execution->getTeamSkipTest($taskID, $end, $end)) && p() && e('无跳转数据'); // end与begin一致
|
||||
Executable
+29
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/execution.class.php';
|
||||
$db->switchDB();
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
|
||||
title=测试executionModel->linkStoryTest();
|
||||
cid=1
|
||||
pid=1
|
||||
|
||||
敏捷执行关联需求 >> 2
|
||||
瀑布执行关联需求 >> 0
|
||||
看板执行关联需求 >> 0
|
||||
|
||||
*/
|
||||
|
||||
$executionIDList = array('101', '131', '161');
|
||||
$productIDList = array('1', '0', '51');
|
||||
$planIDList = array('100', '0', '52');
|
||||
|
||||
$execution = new executionTest();
|
||||
r($execution->linkStoriesTest($executionIDList[0], $productIDList[0], $planIDList[0])) && p() && e('2'); // 敏捷执行关联需求
|
||||
r($execution->linkStoriesTest($executionIDList[1], $productIDList[1], $planIDList[1])) && p() && e('0'); // 瀑布执行关联需求
|
||||
r($execution->linkStoriesTest($executionIDList[2], $productIDList[2], $planIDList[2])) && p() && e('0'); // 看板执行关联需求
|
||||
|
||||
$db->restoreDB();
|
||||
Regular → Executable
Regular → Executable
@@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* ZUI: 数据表格 - v1.10.0 - 2021-11-04
|
||||
* ZUI: 数据表格 - v1.10.0 - 2022-09-06
|
||||
* http://openzui.com
|
||||
* GitHub: https://github.com/easysoft/zui.git
|
||||
* Copyright (c) 2021 cnezsoft.com; Licensed MIT
|
||||
*/.datatable-head,.datatable-rows{display:table;width:100%;table-layout:fixed}.datatable{margin-bottom:20px}.datatable>.datatable-head{-webkit-transition:-webkit-box-shadow .2s;-o-transition:box-shadow .2s;transition:-webkit-box-shadow .2s;transition:box-shadow .2s;transition:box-shadow .2s,-webkit-box-shadow .2s}.datatable .table{margin:0;table-layout:fixed}.datatable .table>tbody>tr>td,.datatable .table>thead>tr>th{min-width:20px}.datatable .table>tbody>tr>td.check-btn,.datatable .table>thead>tr>th.check-btn{width:30px;color:#9b9b9b;text-align:center;cursor:pointer}.datatable .table>tbody>tr.active>td.check-btn,.datatable .table>tbody>tr.hover>td.check-btn,.datatable .table>tbody>tr>td.check-btn.checked,.datatable .table>tbody>tr>td.check-btn:hover,.datatable .table>thead>tr>th.check-btn.checked,.datatable .table>thead>tr>th.check-btn:hover{color:#4f4f4f}.datatable .table>tbody>tr.active>td.check-btn>.icon-check-empty:before,.datatable .table>tbody>tr>td.check-btn.checked>.icon-check-empty:before,.datatable .table>thead>tr>th.check-btn.checked>.icon-check-empty:before{content:'\e642'}.datatable .table>thead>tr>th.col-hover{background-color:#e2e2e2}.datatable .table>tbody>tr.hover>td,.datatable .table>tbody>tr>td.col-hover{background-color:#ebf2f9}.datatable .table>tbody>tr.active.hover td{background-color:#ffdea2}.datatable.head-fixed>.datatable-head{position:fixed;z-index:1030;-webkit-box-shadow:0 1px 4px 0 rgba(0,0,0,.15);box-shadow:0 1px 4px 0 rgba(0,0,0,.15)}.datatable.sortable .datatable-head-span .table>thead>tr>th{overflow:hidden;white-space:nowrap;cursor:pointer}.datatable.sortable .datatable-head-span .table>thead>tr>th.text-center{padding-right:0;padding-left:0}.datatable.sortable .datatable-head-span .table>thead>tr>th:after{display:inline-block;margin-left:5px;font-family:ZenIcon;font-size:14px;font-style:normal;font-weight:400;font-variant:normal;line-height:1;color:grey;text-transform:none;content:'\e6bd';speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.datatable.sortable .datatable-head-span .table>thead>tr>th.sort-down:after{color:#145ccd;content:'\e6b8'}.datatable.sortable .datatable-head-span .table>thead>tr>th.sort-up:after{color:#145ccd;content:'\e6b9'}.datatable.sortable .datatable-head-span .table>thead>tr>th.check-btn:after,.datatable.sortable .datatable-head-span .table>thead>tr>th.sort-disabled:after{display:none}.datatable.sortable .datatable-head-span .table>thead>tr>th.sort-disabled{cursor:default}.datatable-wrapper{position:relative}.datatable-span{display:table-cell;vertical-align:top}.datatable-span.flexarea{overflow:hidden}.datatable-span.flexarea.datatable-head-span.dragging{cursor:move!important}.datatable-span.flexarea .table{position:relative;top:0;left:0}.datatable-span.flexarea .scrolled-shadow{position:absolute;top:0;bottom:0;display:none;width:20px;-webkit-box-shadow:0 0 10px rgba(0,0,0,.15);box-shadow:0 0 10px rgba(0,0,0,.15);opacity:0;-webkit-transition:all .4s cubic-bezier(.175,.885,.32,1);-o-transition:all .4s cubic-bezier(.175,.885,.32,1);transition:all .4s cubic-bezier(.175,.885,.32,1)}.datatable-span.flexarea .scrolled-in-shadow{left:-30px}.datatable-span.flexarea .scrolled-out-shadow{right:-30px}.datatable>.scroll-wrapper{position:relative;width:100%}.datatable .scroll-slide{position:absolute;right:-1px;bottom:0;left:-1px;display:none;height:11px;background:#e5e5e5;background:rgba(128,128,128,.1);border:1px solid #e5e5e5;border-bottom:none;opacity:0;-webkit-transition:opacity .5s,background .3s;-o-transition:opacity .5s,background .3s;transition:opacity .5s,background .3s}.datatable .scroll-slide>.bar{position:absolute;top:0;left:0;min-width:50px;height:10px;cursor:move;background-color:#a6a6a6}.datatable .scroll-slide:hover>.bar{background-color:grey}.datatable .scroll-slide.scroll-pos-out{bottom:-14px;height:15px}.datatable .scroll-slide.scroll-pos-out>.bar{height:14px}.datatable.show-scroll-slide.scrolling .scroll-slide,.datatable.show-scroll-slide.scrolling .scrolled-shadow,.datatable.show-scroll-slide:hover .scroll-slide,.datatable.show-scroll-slide:hover .scrolled-shadow{opacity:1}.datatable.show-scroll-slide .scroll-slide,.datatable.show-scroll-slide .scrolled-shadow{display:block}.datatable.show-scroll-slide.scrolled-in .scrolled-in-shadow{left:-20px}.datatable.show-scroll-slide.scrolled-out .scrolled-out-shadow{right:-20px}
|
||||
* Copyright (c) 2022 cnezsoft.com; Licensed MIT
|
||||
*/.datatable-head,.datatable-rows{display:table;width:100%;table-layout:fixed}.datatable{margin-bottom:20px}.datatable>.datatable-head{-webkit-transition:-webkit-box-shadow .2s;-o-transition:box-shadow .2s;transition:-webkit-box-shadow .2s;transition:box-shadow .2s;transition:box-shadow .2s,-webkit-box-shadow .2s}.datatable .table{margin:0;table-layout:fixed}.datatable .table>tbody>tr>td,.datatable .table>thead>tr>th{min-width:20px}.datatable .table>tbody>tr>td.check-btn,.datatable .table>thead>tr>th.check-btn{width:30px;color:#9b9b9b;text-align:center;cursor:pointer}.datatable .table>tbody>tr.active>td.check-btn,.datatable .table>tbody>tr.hover>td.check-btn,.datatable .table>tbody>tr>td.check-btn.checked,.datatable .table>tbody>tr>td.check-btn:hover,.datatable .table>thead>tr>th.check-btn.checked,.datatable .table>thead>tr>th.check-btn:hover{color:#4f4f4f}.datatable .table>tbody>tr.active>td.check-btn>.icon-check-empty:before,.datatable .table>tbody>tr>td.check-btn.checked>.icon-check-empty:before,.datatable .table>thead>tr>th.check-btn.checked>.icon-check-empty:before{content:'\e642'}.datatable .table>thead>tr>th.col-hover{background-color:#e2e2e2}.datatable .table>tbody>tr.hover>td,.datatable .table>tbody>tr>td.col-hover{background-color:#ebf2f9}.datatable .table>tbody>tr.active.hover td{background-color:#ffdea2}.datatable.head-fixed>.datatable-head{position:fixed;z-index:1030;-webkit-box-shadow:0 1px 4px 0 rgba(0,0,0,.15);box-shadow:0 1px 4px 0 rgba(0,0,0,.15)}.datatable.sortable .datatable-head-span .table>thead>tr>th{overflow:hidden;white-space:nowrap;cursor:pointer}.datatable.sortable .datatable-head-span .table>thead>tr>th.text-center{padding-right:0;padding-left:0}.datatable.sortable .datatable-head-span .table>thead>tr>th:after{display:inline-block;margin-left:5px;font-family:ZenIcon;font-size:14px;font-style:normal;font-weight:400;font-variant:normal;line-height:1;color:grey;text-transform:none;content:'\e6bd';speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.datatable.sortable .datatable-head-span .table>thead>tr>th.sort-down:after{color:#145ccd;content:'\e6b8'}.datatable.sortable .datatable-head-span .table>thead>tr>th.sort-up:after{color:#145ccd;content:'\e6b9'}.datatable.sortable .datatable-head-span .table>thead>tr>th.check-btn:after,.datatable.sortable .datatable-head-span .table>thead>tr>th.sort-disabled:after{display:none}.datatable.sortable .datatable-head-span .table>thead>tr>th.sort-disabled{cursor:default}.datatable-wrapper{position:relative}.datatable-span{display:table-cell;vertical-align:top}.datatable-span.flexarea{overflow:hidden}.datatable-span.flexarea.datatable-head-span.dragging{cursor:move!important}.datatable-span.flexarea .table{position:relative;top:0;left:0}.datatable-span.flexarea .scrolled-shadow{position:absolute;top:0;bottom:0;display:none;width:20px;-webkit-box-shadow:0 0 10px rgba(0,0,0,.15);box-shadow:0 0 10px rgba(0,0,0,.15);opacity:0;-webkit-transition:all .4s cubic-bezier(.175,.885,.32,1);-o-transition:all .4s cubic-bezier(.175,.885,.32,1);transition:all .4s cubic-bezier(.175,.885,.32,1)}.datatable-span.flexarea .scrolled-in-shadow{left:-30px}.datatable-span.flexarea .scrolled-out-shadow{right:-30px}.datatable>.scroll-wrapper{position:relative;width:100%}.datatable .scroll-slide{position:absolute;right:-1px;bottom:0;left:-1px;display:none;height:11px;background:#e5e5e5;background:rgba(128,128,128,.1);border:1px solid #e5e5e5;border-bottom:none;opacity:0;-webkit-transition:opacity .5s,background .3s;-o-transition:opacity .5s,background .3s;transition:opacity .5s,background .3s}.datatable .scroll-slide>.bar{position:absolute;top:0;left:0;height:10px;cursor:move;background-color:#a6a6a6}.datatable .scroll-slide:hover>.bar{background-color:grey}.datatable .scroll-slide.scroll-pos-out{bottom:-14px;height:15px}.datatable .scroll-slide.scroll-pos-out>.bar{height:14px}.datatable.show-scroll-slide.scrolling .scroll-slide,.datatable.show-scroll-slide.scrolling .scrolled-shadow,.datatable.show-scroll-slide:hover .scroll-slide,.datatable.show-scroll-slide:hover .scrolled-shadow{opacity:1}.datatable.show-scroll-slide .scroll-slide,.datatable.show-scroll-slide .scrolled-shadow{display:block}.datatable.show-scroll-slide.scrolled-in .scrolled-in-shadow{left:-20px}.datatable.show-scroll-slide.scrolled-out .scrolled-out-shadow{right:-20px}
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user