Merge branch 'master' of https://gitlab.zcorp.cc/easycorp/zentaopms into importExport
This commit is contained in:
@@ -200,3 +200,5 @@ ALTER TABLE `zt_sqlview` ENGINE='InnoDB';
|
||||
ALTER TABLE `zt_searchindex` ADD FULLTEXT `title_content` (`title`, `content`);
|
||||
ALTER TABLE `zt_searchindex` DROP INDEX `title`;
|
||||
ALTER TABLE `zt_searchindex` DROP INDEX `content`;
|
||||
|
||||
UPDATE `zt_project` SET `closedDate`='' AND `closedBy`='' WHERE `status` != 'closed';
|
||||
|
||||
@@ -1719,8 +1719,8 @@ class bugModel extends model
|
||||
->beginIF($type != 'closedBy' and $this->app->moduleName == 'block')->andWhere('t1.status')->ne('closed')->fi()
|
||||
->beginIF($type != 'all' and $type != 'bySearch')->andWhere("t1.`$type`")->eq($account)->fi()
|
||||
->beginIF($type == 'bySearch' and $moduleName == 'workBug')->andWhere("t1.assignedTo")->eq($account)->fi()
|
||||
->beginIF($type == 'bySearch' and $moduleName == 'contributeBug')
|
||||
->beginIF($type == 'assignedTo' and $moduleName == 'workBug')->andWhere('t1.status')->ne('closed')->fi()
|
||||
->beginIF($type == 'bySearch' and $moduleName == 'contributeBug')
|
||||
->andWhere('t1.openedBy', 1)->eq($account)
|
||||
->orWhere('t1.closedBy')->eq($account)
|
||||
->orWhere('t1.resolvedBy')->eq($account)
|
||||
|
||||
@@ -119,6 +119,39 @@ $config->execution->search['params']['canceledDate'] = array('operator' => '='
|
||||
$config->execution->search['params']['lastEditedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
$config->execution->search['params']['activatedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
|
||||
$app->loadLang('execution');
|
||||
$config->execution->all = new stdclass();
|
||||
$config->execution->all->search['module'] = 'execution';
|
||||
$config->execution->all->search['fields']['name'] = $lang->execution->execName;
|
||||
$config->execution->all->search['fields']['id'] = $lang->execution->execId;
|
||||
$config->execution->all->search['fields']['status'] = $lang->execution->execStatus;
|
||||
$config->execution->all->search['fields']['project'] = $lang->execution->project;
|
||||
$config->execution->all->search['fields']['PM'] = $lang->execution->owner;
|
||||
$config->execution->all->search['fields']['openedBy'] = $lang->execution->openedBy;
|
||||
$config->execution->all->search['fields']['openedDate'] = $lang->execution->openedDate;
|
||||
$config->execution->all->search['fields']['begin'] = $lang->execution->begin;
|
||||
$config->execution->all->search['fields']['end'] = $lang->execution->end;
|
||||
$config->execution->all->search['fields']['realBegan'] = $lang->execution->realBegan;
|
||||
$config->execution->all->search['fields']['realEnd'] = $lang->execution->realEnd;
|
||||
$config->execution->all->search['fields']['closedBy'] = $lang->execution->closedBy;
|
||||
$config->execution->all->search['fields']['lastEditedDate'] = $lang->execution->lastEditedDate;
|
||||
$config->execution->all->search['fields']['closedDate'] = $lang->execution->closedDate;
|
||||
|
||||
$config->execution->all->search['params']['name'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
|
||||
$config->execution->all->search['params']['id'] = array('operator' => '=', 'control' => 'input', 'values' => '');
|
||||
$config->execution->all->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => array('') + $lang->execution->statusList);
|
||||
$config->execution->all->search['params']['project'] = array('operator' => '=', 'control' => 'select', 'values' => '');
|
||||
$config->execution->all->search['params']['PM'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
|
||||
$config->execution->all->search['params']['openedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
|
||||
$config->execution->all->search['params']['openedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
$config->execution->all->search['params']['begin'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
$config->execution->all->search['params']['end'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
$config->execution->all->search['params']['realBegan'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
$config->execution->all->search['params']['realEnd'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
$config->execution->all->search['params']['closedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
|
||||
$config->execution->all->search['params']['lastEditedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
$config->execution->all->search['params']['closedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
|
||||
|
||||
$config->printKanban = new stdClass();
|
||||
$config->printKanban->col['story'] = 1;
|
||||
$config->printKanban->col['wait'] = 2;
|
||||
|
||||
@@ -241,7 +241,7 @@ class execution extends control
|
||||
$this->view->moduleID = $moduleID;
|
||||
$this->view->moduleTree = $this->tree->getTaskTreeMenu($executionID, $productID, $startModuleID = 0, array('treeModel', 'createTaskLink'), $extra);
|
||||
$this->view->memberPairs = $memberPairs;
|
||||
$this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products), 'noempty');
|
||||
$this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products));
|
||||
$this->view->setModule = true;
|
||||
$this->view->canBeChanged = common::canModify('execution', $execution); // Determines whether an object is editable.
|
||||
$this->view->showBranch = $showBranch;
|
||||
@@ -3678,13 +3678,14 @@ class execution extends control
|
||||
* @param int $projectID
|
||||
* @param string $orderBy
|
||||
* @param int $productID
|
||||
* @param string $param
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function all($status = 'undone', $projectID = 0, $orderBy = 'order_asc', $productID = 0, $recTotal = 0, $recPerPage = 100, $pageID = 1)
|
||||
public function all($status = 'undone', $projectID = 0, $orderBy = 'order_asc', $productID = 0, $param = '', $recTotal = 0, $recPerPage = 100, $pageID = 1)
|
||||
{
|
||||
$this->app->loadLang('my');
|
||||
$this->app->loadLang('product');
|
||||
@@ -3714,10 +3715,14 @@ class execution extends control
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
|
||||
$queryID = ($status == 'bySearch') ? (int)$param : 0;
|
||||
$actionURL = $this->createLink('execution', 'all', "status=bySearch&projectID=$projectID&orderBy=$orderBy&productID=$productID¶m=myQueryID");
|
||||
$this->execution->buildSearchFrom($queryID, $actionURL);
|
||||
|
||||
$this->view->title = $this->lang->execution->allExecutions;
|
||||
$this->view->position[] = $this->lang->execution->allExecutions;
|
||||
|
||||
$executionStats = $this->project->getStats($projectID, $status, $productID, 0, 30, $orderBy, $pager);
|
||||
$executionStats = $this->project->getStats($projectID, $status, $productID, 0, 30, $orderBy, $pager, false, $queryID);
|
||||
|
||||
$parentIdList = array();
|
||||
foreach($executionStats as $execution)
|
||||
@@ -3742,6 +3747,7 @@ class execution extends control
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
$this->view->status = $status;
|
||||
$this->view->from = $from;
|
||||
$this->view->param = $param;
|
||||
$this->view->isStage = (isset($project->model) and $project->model == 'waterfall') ? true : false;
|
||||
|
||||
$this->display();
|
||||
|
||||
@@ -35,3 +35,4 @@ canvas {height: 28px;}
|
||||
.parent.has-child.c-name.flex, .table-child-bottom > .c-name.flex {border-bottom: 1px solid #cbd0db !important;}
|
||||
.parent.has-child.c-name.flex {margin-bottom: -2px !important;}
|
||||
#tableCustomBtn {padding-bottom: 5px;}
|
||||
#bysearchTab {margin-left: 5px;}
|
||||
|
||||
@@ -137,6 +137,7 @@ $lang->execution->batchCreateTask = 'Batch create task';
|
||||
$lang->execution->kanbanNoLinkProduct = "Kanban not linked {$lang->productCommon}";
|
||||
$lang->execution->myTask = "My Task";
|
||||
$lang->execution->list = "{$lang->executionCommon} List";
|
||||
$lang->execution->allProject = 'All';
|
||||
|
||||
/* Fields of zt_team. */
|
||||
$lang->execution->root = 'Root';
|
||||
|
||||
@@ -137,11 +137,12 @@ $lang->execution->batchCreateTask = 'Batch create task';
|
||||
$lang->execution->kanbanNoLinkProduct = "Kanban not linked {$lang->productCommon}";
|
||||
$lang->execution->myTask = "My Task";
|
||||
$lang->execution->list = 'List';
|
||||
$lang->execution->allProject = 'All';
|
||||
|
||||
/* Fields of zt_team. */
|
||||
$lang->execution->root = 'Root';
|
||||
$lang->execution->estimate = 'estimate';
|
||||
$lang->execution->consumed = 'consumed';
|
||||
$lang->execution->estimate = 'Estimate';
|
||||
$lang->execution->consumed = 'Consumed';
|
||||
$lang->execution->left = 'Left';
|
||||
|
||||
if($this->config->systemMode == 'new') $lang->execution->copyTeamTip = "copy Project/{$lang->execution->common} team members";
|
||||
|
||||
@@ -137,6 +137,7 @@ $lang->execution->batchCreateTask = 'Batch create task';
|
||||
$lang->execution->kanbanNoLinkProduct = "Kanban not linked {$lang->productCommon}";
|
||||
$lang->execution->myTask = "My Task";
|
||||
$lang->execution->list = "{$lang->executionCommon} List";
|
||||
$lang->execution->allProject = 'Tous';
|
||||
|
||||
/* Fields of zt_team. */
|
||||
$lang->execution->root = 'Root';
|
||||
|
||||
@@ -137,6 +137,7 @@ $lang->execution->batchCreateTask = '批量建任务';
|
||||
$lang->execution->kanbanNoLinkProduct = "看板没有关联{$lang->productCommon}";
|
||||
$lang->execution->myTask = "我的任务";
|
||||
$lang->execution->list = '列表';
|
||||
$lang->execution->allProject = '全部项目';
|
||||
|
||||
/* Fields of zt_team. */
|
||||
$lang->execution->root = '源ID';
|
||||
|
||||
@@ -949,6 +949,8 @@ class executionModel extends model
|
||||
->setDefault('status', 'doing')
|
||||
->setDefault('lastEditedBy', $this->app->user->account)
|
||||
->setDefault('lastEditedDate', $now)
|
||||
->setDefault('closedBy', '')
|
||||
->setDefault('closedDate', '')
|
||||
->stripTags($this->config->execution->editor->activate['id'], $this->config->allowedTags)
|
||||
->remove('comment,readjustTime,readjustTask')
|
||||
->get();
|
||||
@@ -4722,4 +4724,23 @@ class executionModel extends model
|
||||
echo '</td>';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Build search form
|
||||
*
|
||||
* @param int $queryID
|
||||
* @param string $actionURL
|
||||
* @return void
|
||||
* */
|
||||
public function buildSearchFrom($queryID, $actionURL)
|
||||
{
|
||||
$this->config->execution->all->search['queryID'] = $queryID;
|
||||
$this->config->execution->all->search['actionURL'] = $actionURL;
|
||||
|
||||
$projectPairs = array(0 => '');
|
||||
$projectPairs += $this->loadModel('project')->getPairsByProgram();
|
||||
$this->config->execution->all->search['params']['project']['values'] = $projectPairs + array('all' => $this->lang->execution->allProject);
|
||||
|
||||
$this->loadModel('search')->setSearchParams($this->config->execution->all->search);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ js::set('isCNLang', !$this->loadModel('common')->checkNotCN())
|
||||
<?php echo html::select('project', $projects, $projectID, "class='form-control chosen' data-placeholder='{$lang->execution->selectProject}'");?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php echo $lang->execution->byQuery;?></a>
|
||||
</div>
|
||||
<div class='btn-toolbar pull-right'>
|
||||
<?php common::printLink('execution', 'export', "status=$status&productID=$productID&orderBy=$orderBy&from=$from", "<i class='icon-export muted'> </i> " . $lang->export, '', "class='btn btn-link export'")?>
|
||||
@@ -69,6 +70,7 @@ js::set('isCNLang', !$this->loadModel('common')->checkNotCN())
|
||||
</div>
|
||||
</div>
|
||||
<div id='mainContent' class="main-row fade">
|
||||
<div class="cell<?php if($status == 'bySearch') echo ' show';?>" id="queryBox" data-module='execution'></div>
|
||||
<?php if(empty($executionStats)):?>
|
||||
<div class="table-empty-tip">
|
||||
<p>
|
||||
@@ -91,7 +93,7 @@ js::set('isCNLang', !$this->loadModel('common')->checkNotCN())
|
||||
<nav class="btn-toolbar pull-right setting"></nav>
|
||||
</div>
|
||||
<?php
|
||||
$vars = "status=$status&projectID=$projectID&orderBy=%s&productID=$productID&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";
|
||||
$vars = "status=$status&projectID=$projectID&orderBy=%s&productID=$productID¶m=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";
|
||||
if($useDatatable) include '../../common/view/datatable.html.php';
|
||||
else include '../../common/view/tablesorter.html.php';
|
||||
|
||||
|
||||
@@ -226,6 +226,7 @@
|
||||
<td colspan='13'>
|
||||
<div class="table-row segments-list">
|
||||
<?php if($groupBy == 'assignedTo' and isset($members[$task->assignedTo])) printf($lang->execution->memberHours, zget($users, $task->assignedTo), $members[$task->assignedTo]->totalHours);?>
|
||||
<?php if($groupBy == 'assignedTo' and $task->assignedTo and !isset($members[$task->assignedTo])) printf($lang->execution->memberHours, zget($users, $task->assignedTo), '0.0');?>
|
||||
<?php if($groupBy == 'assignedTo' and empty($task->assignedTo)):?>
|
||||
<div class="table-col">
|
||||
<div class="clearfix segments">
|
||||
|
||||
@@ -407,7 +407,7 @@ function renderKanbanItem(item, $item)
|
||||
$user.html(renderUsersAvatar(assignedTo, item.id)).attr('title', title);
|
||||
}
|
||||
|
||||
if(kanban.performable == 1)
|
||||
if(kanban.performable == 1 && (item.fromType == '' || item.fromType == 'execution'))
|
||||
{
|
||||
var $progress = $item.children('.progress-box');
|
||||
if(!$progress.length) $progress = $('<div class="progress-box"><div class="progress"><div class="progress-bar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width: ' + item.progress + '%;"></div></div><div class="progress-number">' + item.progress + '%</div></div>').appendTo($item);
|
||||
@@ -1189,7 +1189,7 @@ function createCardMenu(options)
|
||||
var items = [];
|
||||
if(privs.includes('editCard') && card.fromType == '') items.push({label: kanbanLang.editCard, icon: 'edit', url: createLink('kanban', 'editCard', 'cardID=' + card.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
|
||||
if(privs.includes('deleteCard')) items.push({label: card.fromType == '' ? kanbanLang.deleteCard : kanbanLang.removeCard, icon: card.fromType == '' ? 'trash' : 'unlink', url: createLink('kanban', 'deleteCard', 'cardID=' + card.id), attrs: {'target': 'hiddenwin'}});
|
||||
if(kanban.performable == 1)
|
||||
if(kanban.performable == 1 && card.fromType == '')
|
||||
{
|
||||
if(card.status == 'done')
|
||||
{
|
||||
|
||||
@@ -1207,6 +1207,10 @@ class kanbanModel extends model
|
||||
->andWhere('action')->eq('opened')
|
||||
->fetchPairs();
|
||||
}
|
||||
elseif($fromType == 'execution')
|
||||
{
|
||||
$executionProgress = $this->loadModel('project')->computerProgress($objects);
|
||||
}
|
||||
|
||||
/* Data for constructing the card. */
|
||||
foreach($objectCards as $objectID => $cardsInfo)
|
||||
@@ -1231,6 +1235,7 @@ class kanbanModel extends model
|
||||
if($delay > 0) $objectCard->delay = $delay;
|
||||
}
|
||||
$objectCard->execType = $object->type;
|
||||
$objectCard->progress = isset($executionProgress[$objectID]->progress) ? $executionProgress[$objectID]->progress : 0;
|
||||
}
|
||||
|
||||
$objectCard->desc = strip_tags(htmlspecialchars_decode($object->desc));
|
||||
|
||||
@@ -47,7 +47,12 @@
|
||||
#archivedCards .card-item .has-color .info > .label-pri {border-color: #FFFFFF;}
|
||||
#archivedCards .card-item .has-color .progress-box > .progress-number {color: #FFFFFF;}
|
||||
#archivedCards .progress-box {width: 97%;}
|
||||
#performable {padding: 25px 10px !important;}
|
||||
#archivedCards .no-progress {padding: 7px 10px !important;}
|
||||
#archivedCards .has-progress {padding: 21px 10px !important;}
|
||||
#archivedCards .has-desc.has-progress {padding: 26px 10px !important;}
|
||||
#archivedCards .has-desc.no-progress {padding: 19px 10px !important;}
|
||||
#archivedCards .has-avatar.has-progress {padding: 24px 10px !important;}
|
||||
#archivedCards .has-avatar.no-progress {padding: 9px 10px !important;}
|
||||
</style>
|
||||
<?php
|
||||
$app->loadLang('execution');
|
||||
@@ -71,6 +76,7 @@ js::set('systemMode', $this->config->systemMode);
|
||||
<div class='card-item' data-card='<?php echo $card->id;?>'>
|
||||
<div class='col-xs-10'>
|
||||
<?php
|
||||
$class = '';
|
||||
$color = '';
|
||||
if($card->color == '#b10b0b') $color = 'has-color red';
|
||||
if($card->color == '#cfa227') $color = 'has-color yellow';
|
||||
@@ -98,7 +104,11 @@ js::set('systemMode', $this->config->systemMode);
|
||||
$name = isset($card->title) ? $card->title : $card->name;
|
||||
if(common::hasPriv($card->fromType, 'view')) echo html::a($this->createLink($card->fromType, 'view', "id=$card->fromID"), $name, '', "class='cardName' title='$name'");
|
||||
if(!common::hasPriv($card->fromType, 'view')) echo "<div class='cardName' title='$name'>$name</div>";
|
||||
if($card->fromType == 'productplan' or $card->fromType == 'build') echo "<div class='desc' title='$card->desc'>$card->desc</div>";
|
||||
if($card->fromType == 'productplan' or $card->fromType == 'build')
|
||||
{
|
||||
echo "<div class='desc' title='$card->desc'>$card->desc</div>";
|
||||
if(!empty($card->desc)) $class .= ' has-desc';
|
||||
}
|
||||
echo "<div class='info $card->fromType'>";
|
||||
if(isset($lang->{$card->fromType}->statusList[$card->objectStatus])) echo "<span class='label label-$card->objectStatus'>" . $lang->{$card->fromType}->statusList[$card->objectStatus] . '</span>';
|
||||
if(isset($card->date) and !helper::isZeroDate($card->date)) echo "<span class='time label label-light'>" . date("Y-m-d", strtotime($card->date)) . "</span>"
|
||||
@@ -147,6 +157,7 @@ js::set('systemMode', $this->config->systemMode);
|
||||
if($count > 2) continue;
|
||||
echo html::smallAvatar(array('avatar' => $usersAvatar[$account], 'account' => $account, 'name' => $users[$account]), 'avatar-circle');
|
||||
$count ++;
|
||||
$class .= ' has-avatar';
|
||||
}
|
||||
?>
|
||||
<?php if($count > 2) echo "<span>...</span>";?>
|
||||
@@ -159,11 +170,12 @@ js::set('systemMode', $this->config->systemMode);
|
||||
echo "<div class='users pull-right' title='" . $users[$assignedToList] . "'>";
|
||||
echo html::smallAvatar(array('avatar' => $usersAvatar[$assignedToList], 'account' => $assignedToList, 'name' => $users[$assignedToList]), 'avatar-circle');
|
||||
echo "</div>";
|
||||
$class .= ' has-avatar';
|
||||
}
|
||||
?>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<?php if($kanban->performable):?>
|
||||
<?php if($kanban->performable and ($card->fromType == 'execution' or empty($card->fromType))):?>
|
||||
<div class='progress-box'>
|
||||
<div class='progress'>
|
||||
<div class="progress-bar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width: <?php echo round($card->progress, 2) . '%';?>"></div>
|
||||
@@ -173,7 +185,8 @@ js::set('systemMode', $this->config->systemMode);
|
||||
<?php endif;?>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-2 card-actions' <?php if($kanban->performable) echo "id='performable'";?>>
|
||||
<?php $class .= (!empty($kanban->performable) and ($card->fromType == 'execution' or empty($card->fromType))) ? ' has-progress' : ' no-progress';?>
|
||||
<div class='col-xs-2 card-actions<?php echo $class;?>'>
|
||||
<?php
|
||||
$CRKanban = !(isset($this->config->CRKanban) and $this->config->CRKanban == '0' and $kanban->status == 'closed');
|
||||
$canRestore = (commonModel::hasPriv('kanban', 'restoreCard') and $CRKanban);
|
||||
|
||||
@@ -189,7 +189,7 @@
|
||||
<td class='text-left nobr' title='<?php echo $story->title?>'>
|
||||
<?php
|
||||
if($story->parent > 0) echo "<span class='label label-badge label-light' title={$lang->story->children}>{$lang->story->childrenAB}</span>";
|
||||
echo html::a($viewLink , $story->title);
|
||||
echo html::a($viewLink , $story->title, '', "style='color: $story->color'");
|
||||
?>
|
||||
</td>
|
||||
<td><?php echo zget($users, $story->openedBy);?></td>
|
||||
|
||||
@@ -180,7 +180,7 @@ function showEditCheckbox(show)
|
||||
executionID = $tr.attr('data-id');
|
||||
if(show)
|
||||
{
|
||||
var marginLeft = $tr.find('td:first').find('span.table-nest-icon').css('margin-left');
|
||||
var marginLeft = '7px';
|
||||
|
||||
$tr.find('td:first').prepend("<div class='checkbox-primary'><input type='checkbox' name='executionIDList[]' value='" + executionID + "' id='executionIDList" + executionID + "'/><label for='executionIDList" + executionID + "'></lable></div>");
|
||||
$tr.find('td:first').find('.checkbox-primary').css('margin-left', marginLeft).css('width', '14');
|
||||
|
||||
@@ -2329,17 +2329,48 @@ class projectModel extends model
|
||||
* @param int $projectID
|
||||
* @param string $status
|
||||
* @param int $productID
|
||||
* @param int $branch
|
||||
* @param int $itemCounts
|
||||
* @param string $orderBy
|
||||
* @param object $pager
|
||||
* @param bool $withTasks
|
||||
* @param int $queryID
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getStats($projectID = 0, $status = 'undone', $productID = 0, $branch = 0, $itemCounts = 30, $orderBy = 'id_asc', $pager = null, $withTasks = false)
|
||||
public function getStats($projectID = 0, $status = 'undone', $productID = 0, $branch = 0, $itemCounts = 30, $orderBy = 'id_asc', $pager = null, $withTasks = false, $queryID = 0)
|
||||
{
|
||||
if(empty($productID))
|
||||
{
|
||||
$myExecutionIDList = array();
|
||||
$query = '';
|
||||
if($status == 'bySearch')
|
||||
{
|
||||
$status = 'all';
|
||||
if($queryID)
|
||||
{
|
||||
$query = $this->loadModel('search')->getQuery($queryID);
|
||||
if($query)
|
||||
{
|
||||
$this->session->set('executionQuery', $query->sql);
|
||||
$this->session->set('executionForm', $query->form);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->session->set('executionQuery', ' 1 = 1');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if($this->session->executionQuery == false) $this->session->set('executionQuery', ' 1 = 1');
|
||||
}
|
||||
$query = $this->session->executionQuery;
|
||||
$allProject = "`project` = 'all'";
|
||||
|
||||
if(strpos($query, $allProject) !== false) $query = str_replace($allProject, '1', $query);
|
||||
$query = preg_replace('/(`\w*`)/', 't1.$1',$query);
|
||||
}
|
||||
|
||||
if($status == 'involved')
|
||||
{
|
||||
$myExecutionIDList = $this->dao->select('root')->from(TABLE_TEAM)
|
||||
@@ -2351,6 +2382,7 @@ class projectModel extends model
|
||||
$executions = $this->dao->select('t1.*,t2.name projectName, t2.model as projectModel')->from(TABLE_EXECUTION)->alias('t1')
|
||||
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
|
||||
->where('t1.type')->in('sprint,stage,kanban')
|
||||
->beginIF(!empty($query))->andWhere($query)->fi()
|
||||
->beginIF($projectID != 0)->andWhere('t1.project')->eq($projectID)->fi()
|
||||
->beginIF($projectID == 0 and $this->config->vision)->andWhere('t1.vision')->eq($this->config->vision)->fi()
|
||||
->beginIF(!empty($myExecutionIDList))->andWhere('t1.id')->in(array_keys($myExecutionIDList))->fi()
|
||||
|
||||
+11
-6
@@ -1841,15 +1841,20 @@ class storyModel extends model
|
||||
if($oldStory->branch) $story->plan = $planID;
|
||||
|
||||
/* Append the plan id to plan field if product is multi and story is all branch. */
|
||||
if($this->session->currentProductType != 'normal' and empty($story->branch) and $planID != 0)
|
||||
if($this->session->currentProductType != 'normal' and empty($story->branch))
|
||||
{
|
||||
$branchPlanPairs = $this->dao->select('branch, id as plan')->from(TABLE_PRODUCTPLAN)
|
||||
->where('product')->eq($oldStory->product)
|
||||
->andWhere('id')->in($oldStory->plan)
|
||||
->fetchPairs();
|
||||
if(isset($branchPlanPairs[$plan->branch])) $branchPlanPairs[$plan->branch] = $planID;
|
||||
|
||||
$story->plan = $oldStory->plan ? ',' . implode(',', $branchPlanPairs) : ",$planID";
|
||||
if($planID == 0 and !empty($oldStory->plan) and isset($branchPlanPairs[0]) and $branchPlanPairs[0] != $planID) $unlinkPlans[$branchPlanPairs[0]] = empty($unlinkPlans[$branchPlanPairs[0]]) ? $storyID : "{$unlinkPlans[$branchPlanPairs[0]]},$storyID";
|
||||
if($planID != 0)
|
||||
{
|
||||
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";
|
||||
if($story->plan != $oldStory->plan and !empty($planID)) $link2Plans[$planID] = empty($link2Plans[$planID]) ? $storyID : "{$link2Plans[$planID]},$storyID";
|
||||
}
|
||||
}
|
||||
|
||||
/* Change stage. */
|
||||
@@ -1878,8 +1883,8 @@ class storyModel extends model
|
||||
if(!dao::isError())
|
||||
{
|
||||
$allChanges[$storyID] = common::createChanges($oldStory, $story);
|
||||
if($story->plan != $oldStory->plan and !empty($oldStory->plan)) $unlinkPlans[$oldStory->plan] = empty($unlinkPlans[$oldStory->plan]) ? $storyID : "{$unlinkPlans[$oldStory->plan]},$storyID";
|
||||
if($story->plan != $oldStory->plan and !empty($story->plan)) $link2Plans[$story->plan] = empty($link2Plans[$story->plan]) ? $storyID : "{$link2Plans[$story->plan]},$storyID";
|
||||
if($story->plan != $oldStory->plan and !empty($oldStory->plan) and strpos($story->plan, ',') === false) $unlinkPlans[$oldStory->plan] = empty($unlinkPlans[$oldStory->plan]) ? $storyID : "{$unlinkPlans[$oldStory->plan]},$storyID";
|
||||
if($story->plan != $oldStory->plan and !empty($story->plan) and strpos($story->plan, ',') === false) $link2Plans[$story->plan] = empty($link2Plans[$story->plan]) ? $storyID : "{$link2Plans[$story->plan]},$storyID";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-1
@@ -63,6 +63,7 @@ class taskModel extends model
|
||||
$requiredFields = str_replace(",story,", ',', "$requiredFields");
|
||||
$requiredFields = str_replace(",estStarted,", ',', "$requiredFields");
|
||||
$requiredFields = str_replace(",deadline,", ',', "$requiredFields");
|
||||
$requiredFields = str_replace(",module,", ',', "$requiredFields");
|
||||
}
|
||||
|
||||
$this->loadModel('file');
|
||||
@@ -3626,6 +3627,18 @@ class taskModel extends model
|
||||
public function printAssignedHtml($task, $users)
|
||||
{
|
||||
$btnTextClass = '';
|
||||
if(!empty($task->team) and $task->mode == 'multi' and $task->status != 'closed')
|
||||
{
|
||||
$assignedToText = $this->lang->task->team;
|
||||
|
||||
$teamMembers = array();
|
||||
foreach($task->team as $teamMember) $teamMembers[] = zget($users, $teamMember->account);
|
||||
$assignedToTitle = implode($this->lang->comma, $teamMembers);
|
||||
}
|
||||
else
|
||||
{
|
||||
$assignedToText = $assignedToTitle = zget($users, $task->assignedTo);
|
||||
}
|
||||
$assignedToText = (!empty($task->team) and $task->mode == 'multi' and $task->status != 'closed') ? $this->lang->task->team : zget($users, $task->assignedTo);
|
||||
|
||||
if(empty($task->assignedTo))
|
||||
@@ -3638,7 +3651,7 @@ class taskModel extends model
|
||||
$btnClass = $task->assignedTo == 'closed' ? ' disabled' : '';
|
||||
$btnClass = "iframe btn btn-icon-left btn-sm {$btnClass}";
|
||||
$assignToLink = $task->assignedTo == 'closed' ? '#' : helper::createLink('task', 'assignTo', "executionID=$task->execution&taskID=$task->id", '', true);
|
||||
$assignToHtml = html::a($assignToLink, "<i class='icon icon-hand-right'></i> <span title='" . zget($users, $task->assignedTo) . "' class='{$btnTextClass}'>{$assignedToText}</span>", '', "class='$btnClass'");
|
||||
$assignToHtml = html::a($assignToLink, "<i class='icon icon-hand-right'></i> <span title='" . $assignedToTitle . "' class='{$btnTextClass}'>{$assignedToText}</span>", '', "class='$btnClass'");
|
||||
|
||||
echo !common::hasPriv('task', 'assignTo', $task) ? "<span style='padding-left: 21px' class='{$btnTextClass}'>{$assignedToText}</span>" : $assignToHtml;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ if(window.self !== window.top) window.top.location.href = window.location.href;
|
||||
|
||||
$(document).ready(function()
|
||||
{
|
||||
timeoutID = null;
|
||||
|
||||
/* Fix bug for misc-ping */
|
||||
$('#hiddenwin').removeAttr('id');
|
||||
|
||||
@@ -33,10 +35,19 @@ $(document).ready(function()
|
||||
var link = createLink('user', 'login');
|
||||
var keepLogin = $('#keepLoginon').attr('checked') == 'checked' ? 1 : 0;
|
||||
var captcha = $('#captcha').length == 1 ? $('#captcha').val() : '';
|
||||
var timeout = true;
|
||||
|
||||
clearTimeout(timeoutID);
|
||||
timeoutID = setTimeout(function()
|
||||
{
|
||||
if(timeout) alert(loginTimeoutTip);
|
||||
}, 4000);
|
||||
|
||||
$.get(createLink('user', 'refreshRandom'), function(data)
|
||||
{
|
||||
var rand = data;
|
||||
timeout = false;
|
||||
|
||||
$.ajax
|
||||
({
|
||||
url: link,
|
||||
|
||||
@@ -251,6 +251,7 @@ $lang->user->error->noEmail = 'The user does not register email. Please
|
||||
$lang->user->error->errorEmail = 'The account does not match the email. Please enter a new one.';
|
||||
$lang->user->error->emailSetting = 'No email is configured in the system. Contact the admin to reset the email.';
|
||||
$lang->user->error->sendMailFail = 'Message sending failed, please try again!';
|
||||
$lang->user->error->loginTimeoutTip = 'Login failed, please check if the proxy service is normal.';
|
||||
|
||||
$lang->user->contactFieldList['phone'] = $lang->user->phone;
|
||||
$lang->user->contactFieldList['mobile'] = $lang->user->mobile;
|
||||
|
||||
@@ -251,6 +251,7 @@ $lang->user->error->noEmail = 'The user does not register email. Please
|
||||
$lang->user->error->errorEmail = 'The account does not match the email. Please enter a new one.';
|
||||
$lang->user->error->emailSetting = 'No email is configured in the system. Contact the admin to reset the email.';
|
||||
$lang->user->error->sendMailFail = 'Message sending failed, please try again!';
|
||||
$lang->user->error->loginTimeoutTip = 'Login failed, please check if the proxy service is normal.';
|
||||
|
||||
$lang->user->contactFieldList['phone'] = $lang->user->phone;
|
||||
$lang->user->contactFieldList['mobile'] = $lang->user->mobile;
|
||||
|
||||
@@ -251,6 +251,7 @@ $lang->user->error->noEmail = 'The user does not register email. Please
|
||||
$lang->user->error->errorEmail = 'The account does not match the email. Please enter a new one.';
|
||||
$lang->user->error->emailSetting = 'No email is configured in the system. Contact the admin to reset the email.';
|
||||
$lang->user->error->sendMailFail = 'Message sending failed, please try again!';
|
||||
$lang->user->error->loginTimeoutTip = 'Échec de la connexion, veuillez vérifier si le service proxy est activé.';
|
||||
|
||||
$lang->user->contactFieldList['phone'] = $lang->user->phone;
|
||||
$lang->user->contactFieldList['mobile'] = $lang->user->mobile;
|
||||
|
||||
@@ -251,6 +251,7 @@ $lang->user->error->noEmail = '该用户未绑定邮箱,请联系管
|
||||
$lang->user->error->errorEmail = '用户名和邮箱不匹配,请重新输入。';
|
||||
$lang->user->error->emailSetting = '系统未配置发信邮箱,请联系管理员重置。';
|
||||
$lang->user->error->sendMailFail = '邮件发送失败,请重试!';
|
||||
$lang->user->error->loginTimeoutTip = '系统登录失败,请检查代理服务是否正常';
|
||||
|
||||
$lang->user->contactFieldList['phone'] = $lang->user->phone;
|
||||
$lang->user->contactFieldList['mobile'] = $lang->user->mobile;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
include '../../common/view/header.lite.html.php';
|
||||
if(empty($config->notMd5Pwd))js::import($jsRoot . 'md5.js');
|
||||
?>
|
||||
<?php js::set('loginTimeoutTip', $lang->user->error->loginTimeoutTip);?>
|
||||
<main id="main" class="fade no-padding">
|
||||
<div class="container" id="login">
|
||||
<div id="loginPanel">
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<?php
|
||||
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
|
||||
include dirname(dirname(dirname(__FILE__))) . '/class/todo.class.php';
|
||||
$db->switchDB();
|
||||
su('admin');
|
||||
|
||||
/**
|
||||
@@ -12,25 +13,28 @@ pid=1
|
||||
|
||||
测试创建周期日待办 >> 11
|
||||
测试创建周期周待办 >> 9
|
||||
测试创建周期月待办 >> 70
|
||||
测试创建周期月待办 >> `%d`
|
||||
|
||||
*/
|
||||
|
||||
$days = 31;
|
||||
$begin = call_user_func_array('date', array('Y-m-d'));
|
||||
$end = call_user_func_array('date', array('Y-m-d', strtotime("+$days days")));
|
||||
$todo1 = new stdclass();
|
||||
$todo1->name = 'cycle生成的待办1';
|
||||
$todo1->config = '{"specify":{"month":"0","day":"1"},"day":"1","type":"day","beforeDays":11,"end":"","begin":"2022-03-23"}';
|
||||
$todo1->config = '{"specify":{"month":"0","day":"1"},"day":"1","type":"day","beforeDays":11,"end":"' . $end . '","begin":"' . $begin . '"}';
|
||||
|
||||
$todo2 = new stdclass();
|
||||
$todo2->name = 'cycle生成的待办2';
|
||||
$todo2->config = '{"specify":{"month":"0","day":"1"},"week":"2,4,7","type":"week","beforeDays":31,"end":"","begin":"2022-03-23"}';
|
||||
$todo2->config = '{"specify":{"month":"0","day":"1"},"week":"2,4,7","type":"week","beforeDays":31,"end":"' . $end . '","begin":"' . $begin . '"}';
|
||||
|
||||
$todo3 = new stdclass();
|
||||
$todo3->name = 'cycle生成的待办3';
|
||||
$todo3->config = '{"specify":{"month":"0","day":"1"},"month":"1,8,13,15,27,29,30","type":"month","beforeDays":301,"end":"","begin":"2022-03-23"}';
|
||||
$todo3->config = '{"specify":{"month":"0","day":"1"},"month":"1,8,13,15,27,29,30","type":"month","beforeDays":301,"end":"' . $end . '","begin":"' . $begin . '"}';
|
||||
|
||||
$todo = new todoTest();
|
||||
|
||||
r($todo->createByCycleTest($todo1)) && p() && e('11'); // 测试创建周期日待办
|
||||
r($todo->createByCycleTest($todo2)) && p() && e('9'); // 测试创建周期周待办
|
||||
r($todo->createByCycleTest($todo3)) && p() && e('70'); // 测试创建周期月待办
|
||||
system("./ztest init");
|
||||
r($todo->createByCycleTest($todo1)) && p() && e('11'); // 测试创建周期日待办
|
||||
r($todo->createByCycleTest($todo2)) && p() && e('9'); // 测试创建周期周待办
|
||||
r($todo->createByCycleTest($todo3)) && p() && e('`%d`'); // 测试创建周期月待办
|
||||
$db->restoreDB();
|
||||
|
||||
Reference in New Issue
Block a user