Merge branch 'master' of https://gitlab.zcorp.cc/easycorp/zentaopms into importExport
This commit is contained in:
@@ -1044,6 +1044,8 @@ class actionModel extends model
|
||||
if($this->app->getMethodName() == 'dynamic') $beginDate = $year - 1 . '-01-01';
|
||||
}
|
||||
|
||||
$programCondition = empty($this->app->user->view->programs) ? '0' : $this->app->user->view->programs;
|
||||
|
||||
/* Get actions. */
|
||||
$actions = $this->dao->select('*')->from(TABLE_ACTION)
|
||||
->where('objectType')->notIN('kanbanregion,kanbanlane,kanbancolumn')
|
||||
@@ -1070,6 +1072,7 @@ class actionModel extends model
|
||||
->beginIF($actionCondition)->andWhere("($actionCondition)")->fi()
|
||||
/* Filter out client login/logout actions. */
|
||||
->andWhere('action')->notin('disconnectxuanxuan,reconnectxuanxuan,loginxuanxuan,logoutxuanxuan')
|
||||
->andWhere("IF((objectType = 'program'), (objectID in ($programCondition)), '1=1')")
|
||||
->orderBy($orderBy)
|
||||
->page($pager)
|
||||
->fetchAll();
|
||||
@@ -1097,8 +1100,7 @@ class actionModel extends model
|
||||
foreach($this->app->user->rights['acls']['actions'] as $moduleName => $actions)
|
||||
{
|
||||
if(isset($this->lang->mainNav->$moduleName) and !empty($this->app->user->rights['acls']['views']) and !isset($this->app->user->rights['acls']['views'][$moduleName])) continue;
|
||||
$canViewPrograms = $moduleName == 'program' ? "`objectID` in ({$this->app->user->view->programs}) and " : '';
|
||||
$actionCondition .= "($canViewPrograms `objectType` = '$moduleName' and `action` " . helper::dbIN($actions) . ") or ";
|
||||
$actionCondition .= "(`objectType` = '$moduleName' and `action` " . helper::dbIN($actions) . ") or ";
|
||||
}
|
||||
$actionCondition = trim($actionCondition, 'or ');
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ class bug extends control
|
||||
|
||||
/* Set browse type. */
|
||||
$browseType = strtolower($browseType);
|
||||
if($this->cookie->preProductID != $productID or $this->cookie->preBranch != $branch or $browseType == 'bybranch')
|
||||
if($this->cookie->preProductID != $productID or ($this->cookie->preBranch != $branch and $product->type != 'normal' and $branch != 'all') or $browseType == 'bybranch')
|
||||
{
|
||||
$_COOKIE['bugModule'] = 0;
|
||||
setcookie('bugModule', 0, 0, $this->config->webRoot, '', $this->config->cookieSecure, false);
|
||||
|
||||
@@ -15,10 +15,6 @@
|
||||
<style>
|
||||
#ganttView {height: 600px;}
|
||||
#mainContent:before {background: #fff;}
|
||||
.gantt-fullscreen #header,
|
||||
.gantt-fullscreen #mainMenu,
|
||||
.gantt-fullscreen #footer {display: none!important;}
|
||||
.gantt-fullscreen #mainContent {position: fixed; top: 0; right: 0; bottom: 0; left: 0}
|
||||
.checkbox-primary {margin-top: 0px; margin-left: 10px;}
|
||||
form {display: block; margin-top: 0em; margin-block-end: 1em;}
|
||||
.gantt_task_content span.task-label, .gantt_task_content span.label-pri{display: none;}
|
||||
@@ -64,6 +60,11 @@ form {display: block; margin-top: 0em; margin-block-end: 1em;}
|
||||
#mainContent.loading #ganttContainer {padding: 40px;}
|
||||
#mainContent.loading .scrollVer_cell,
|
||||
#mainContent.loading .scrollVer_cell {display: none;}
|
||||
#
|
||||
.gantt-fullscreen #header,
|
||||
.gantt-fullscreen #mainMenu,
|
||||
.gantt-fullscreen #footer {display: none!important;}
|
||||
.gantt-fullscreen #mainContent {position: fixed; top: 0; right: 0; bottom: 0; left: 0}
|
||||
</style>
|
||||
<?php js::set('customUrl', $this->createLink('programplan', 'ajaxCustom'));?>
|
||||
<?php js::set('dateDetails', $dateDetails);?>
|
||||
@@ -90,7 +91,8 @@ form {display: block; margin-top: 0em; margin-block-end: 1em;}
|
||||
<div id='ganttContainer'>
|
||||
<div class='gantt' id='ganttView'></div>
|
||||
</div>
|
||||
<a id='ganttDownload' download='gantt-export-<?php echo $projectID;?>.png'></a>
|
||||
<?php $fileName = "gantt-export-{$projectID}";?>
|
||||
<a id='ganttDownload' target='hiddenwin' download='<?php echo "{$fileName}.png";?>'></a>
|
||||
</div>
|
||||
<script>
|
||||
var scriptLoadedMap = {};
|
||||
@@ -231,7 +233,7 @@ function drawGanttToCanvas(exportType, successCallback, errorCallback)
|
||||
orientation: width > height ? 'l' : 'p'
|
||||
});
|
||||
pdf.addImage(canvas, 0, 0, pdf.internal.pageSize.getWidth(), pdf.internal.pageSize.getHeight());
|
||||
pdf.save('gantt-export-<?php echo $projectID;?>.pdf');
|
||||
pdf.save('<?php echo "$fileName.pdf"?>');
|
||||
if(successCallback) successCallback(pdf);
|
||||
afterFinish();
|
||||
}, function(error)
|
||||
@@ -248,7 +250,7 @@ function drawGanttToCanvas(exportType, successCallback, errorCallback)
|
||||
var imageUrl = URL.createObjectURL(blob);
|
||||
if(navigator.msSaveBlob)
|
||||
{
|
||||
navigator.msSaveOrOpenBlob(blob, 'gantt-export-<?php echo $projectID;?>.png');
|
||||
navigator.msSaveOrOpenBlob(blob, '<?php echo $fileName; ?>.png');
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -32,7 +32,7 @@ $config->story->editor->assignto = array('id' => 'comment', 'tools' => 'simpleTo
|
||||
$config->story->list = new stdclass();
|
||||
$config->story->exportFields = '
|
||||
id, product, branch, module, plan, source, sourceNote, title, spec, verify, keywords,
|
||||
pri, estimate, status, stage, taskCountAB, bugCountAB, caseCountAB,
|
||||
pri, estimate, status, stage, category, taskCountAB, bugCountAB, caseCountAB,
|
||||
openedBy, openedDate, assignedTo, assignedDate, mailto,
|
||||
reviewedBy, reviewedDate,
|
||||
closedBy, closedDate, closedReason,
|
||||
|
||||
+252
-189
@@ -2436,11 +2436,260 @@ class story extends control
|
||||
/* format the fields of every story in order to export data. */
|
||||
if($_POST)
|
||||
{
|
||||
$this->loadModel('file');
|
||||
$this->loadModel('branch');
|
||||
$storyLang = $this->lang->story;
|
||||
$storyConfig = $this->config->story;
|
||||
|
||||
/* Create field lists. */
|
||||
$fields = $this->post->exportFields ? $this->post->exportFields : explode(',', $storyConfig->list->exportFields);
|
||||
foreach($fields as $key => $fieldName)
|
||||
{
|
||||
$fieldName = trim($fieldName);
|
||||
$fields[$fieldName] = isset($storyLang->$fieldName) ? $storyLang->$fieldName : $fieldName;
|
||||
unset($fields[$key]);
|
||||
}
|
||||
|
||||
$this->post->set('rows', $this->getExportStorys($orderBy));
|
||||
$this->fetch('port', 'export', 'model=story¶ms=productID=' . $productID . ',executionID=' . $executionID);
|
||||
/* Get stories. */
|
||||
$stories = array();
|
||||
if($this->session->storyOnlyCondition)
|
||||
{
|
||||
if($this->post->exportType == 'selected')
|
||||
{
|
||||
$stories = $this->dao->select('*')->from(TABLE_STORY)->where('id')->in($this->cookie->checkedItem)->orderBy($orderBy)->fetchAll('id');
|
||||
}
|
||||
else
|
||||
{
|
||||
$stories = $this->dao->select('*')->from(TABLE_STORY)->where($this->session->storyQueryCondition)->orderBy($orderBy)->fetchAll('id');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$field = $executionID ? 't2.id' : 't1.id';
|
||||
if($this->post->exportType == 'selected')
|
||||
{
|
||||
$stmt = $this->dbh->query("SELECT * FROM " . TABLE_STORY . "WHERE `id` IN({$this->cookie->checkedItem})" . " ORDER BY " . strtr($orderBy, '_', ' '));
|
||||
}
|
||||
else
|
||||
{
|
||||
$stmt = $this->dbh->query($this->session->storyQueryCondition . " ORDER BY " . strtr($orderBy, '_', ' '));
|
||||
}
|
||||
while($row = $stmt->fetch()) $stories[$row->id] = $row;
|
||||
}
|
||||
$storyIdList = array_keys($stories);
|
||||
|
||||
if($stories)
|
||||
{
|
||||
$children = array();
|
||||
foreach($stories as $story)
|
||||
{
|
||||
if($story->parent > 0 and isset($stories[$story->parent]))
|
||||
{
|
||||
$children[$story->parent][$story->id] = $story;
|
||||
unset($stories[$story->id]);
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($children))
|
||||
{
|
||||
$reorderStories = array();
|
||||
foreach($stories as $story)
|
||||
{
|
||||
$reorderStories[$story->id] = $story;
|
||||
if(isset($children[$story->id]))
|
||||
{
|
||||
foreach($children[$story->id] as $childrenID => $childrenStory)
|
||||
{
|
||||
$reorderStories[$childrenID] = $childrenStory;
|
||||
}
|
||||
}
|
||||
unset($stories[$story->id]);
|
||||
}
|
||||
$stories = $reorderStories;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get users, products and relations. */
|
||||
$users = $this->loadModel('user')->getPairs('noletter');
|
||||
$products = $this->product->getPairs('nocode');
|
||||
$relations = $this->story->getStoryRelationByIds($storyIdList, $type);
|
||||
|
||||
/* Get related objects id lists. */
|
||||
$relatedProductIdList = array();
|
||||
$relatedStoryIdList = array();
|
||||
$relatedPlanIdList = array();
|
||||
$relatedBranchIdList = array();
|
||||
$relatedStoryIds = array();
|
||||
|
||||
foreach($stories as $story)
|
||||
{
|
||||
$relatedProductIdList[$story->product] = $story->product;
|
||||
$relatedPlanIdList[$story->plan] = $story->plan;
|
||||
$relatedBranchIdList[$story->branch] = $story->branch;
|
||||
$relatedStoryIds[$story->id] = $story->id;
|
||||
|
||||
if(isset($relations[$story->id])) $story->childStories = $story->childStories . ',' . $relations[$story->id];
|
||||
|
||||
/* Process related stories. */
|
||||
$relatedStories = $story->childStories . ',' . $story->linkStories . ',' . $story->duplicateStory;
|
||||
$relatedStories = explode(',', $relatedStories);
|
||||
foreach($relatedStories as $storyID)
|
||||
{
|
||||
if($storyID) $relatedStoryIdList[$storyID] = trim($storyID);
|
||||
}
|
||||
}
|
||||
|
||||
$storyTasks = $this->loadModel('task')->getStoryTaskCounts($relatedStoryIds);
|
||||
$storyBugs = $this->loadModel('bug')->getStoryBugCounts($relatedStoryIds);
|
||||
$storyCases = $this->loadModel('testcase')->getStoryCaseCounts($relatedStoryIds);
|
||||
|
||||
/* Get related objects title or names. */
|
||||
$productsType = $this->dao->select('id, type')->from(TABLE_PRODUCT)->where('id')->in($relatedProductIdList)->fetchPairs();
|
||||
$relatedPlans = $this->dao->select('id, title')->from(TABLE_PRODUCTPLAN)->where('id')->in(join(',', $relatedPlanIdList))->fetchPairs();
|
||||
$relatedStories = $this->dao->select('id,title')->from(TABLE_STORY)->where('id')->in($relatedStoryIdList)->fetchPairs();
|
||||
$relatedFiles = $this->dao->select('id, objectID, pathname, title')->from(TABLE_FILE)->where('objectType')->eq($type)->andWhere('objectID')->in($storyIdList)->andWhere('extra')->ne('editor')->fetchGroup('objectID');
|
||||
$relatedSpecs = $this->dao->select('*')->from(TABLE_STORYSPEC)->where('`story`')->in($storyIdList)->orderBy('version desc')->fetchGroup('story');
|
||||
$relatedBranch = array('0' => $this->lang->branch->main) + $this->dao->select('id, name')->from(TABLE_BRANCH)->where('id')->in($relatedBranchIdList)->fetchPairs();
|
||||
$relatedModules = $this->loadModel('tree')->getAllModulePairs();
|
||||
|
||||
foreach($stories as $story)
|
||||
{
|
||||
$story->spec = '';
|
||||
$story->verify = '';
|
||||
if(isset($relatedSpecs[$story->id]))
|
||||
{
|
||||
$storySpec = $relatedSpecs[$story->id][0];
|
||||
$story->title = $storySpec->title;
|
||||
$story->spec = $storySpec->spec;
|
||||
$story->verify = $storySpec->verify;
|
||||
}
|
||||
|
||||
if($this->post->fileType == 'csv')
|
||||
{
|
||||
$story->spec = htmlspecialchars_decode($story->spec);
|
||||
$story->spec = str_replace("<br />", "\n", $story->spec);
|
||||
$story->spec = str_replace('"', '""', $story->spec);
|
||||
$story->spec = str_replace(' ', ' ', $story->spec);
|
||||
|
||||
$story->verify = htmlspecialchars_decode($story->verify);
|
||||
$story->verify = str_replace("<br />", "\n", $story->verify);
|
||||
$story->verify = str_replace('"', '""', $story->verify);
|
||||
$story->verify = str_replace(' ', ' ', $story->verify);
|
||||
}
|
||||
/* fill some field with useful value. */
|
||||
if(isset($products[$story->product])) $story->product = $this->post->fileType == 'word' ? $products[$story->product] : $products[$story->product] . "(#$story->product)";
|
||||
if(isset($relatedModules[$story->module])) $story->module = $this->post->fileType == 'word' ? $relatedModules[$story->module] : $relatedModules[$story->module] . "(#$story->module)";
|
||||
if(isset($relatedBranch[$story->branch])) $story->branch = $relatedBranch[$story->branch] . "(#$story->branch)";
|
||||
if(isset($story->plan))
|
||||
{
|
||||
$plans = '';
|
||||
foreach(explode(',', $story->plan) as $planID)
|
||||
{
|
||||
if(empty($planID)) continue;
|
||||
if(isset($relatedPlans[$planID])) $plans .= $this->post->fileType == 'word' ? $relatedPlans[$planID] : $relatedPlans[$planID] . "(#$planID)";
|
||||
}
|
||||
$story->plan = $plans;
|
||||
}
|
||||
if(isset($relatedStories[$story->duplicateStory]) and $story->closedReason != 'duplicate') $story->duplicateStory = $relatedStories[$story->duplicateStory];
|
||||
|
||||
if(isset($storyLang->priList[$story->pri])) $story->pri = $storyLang->priList[$story->pri];
|
||||
if(isset($storyLang->statusList[$story->status])) $story->status = $this->processStatus('story', $story);
|
||||
if(isset($storyLang->stageList[$story->stage])) $story->stage = $storyLang->stageList[$story->stage];
|
||||
if(isset($storyLang->reasonList[$story->closedReason])) $story->closedReason = $storyLang->reasonList[$story->closedReason];
|
||||
if(isset($storyLang->sourceList[$story->source])) $story->source = $storyLang->sourceList[$story->source];
|
||||
if(isset($storyLang->categoryList[$story->category])) $story->category = $storyLang->categoryList[$story->category];
|
||||
|
||||
if(isset($users[$story->openedBy])) $story->openedBy = $users[$story->openedBy];
|
||||
if(isset($users[$story->assignedTo])) $story->assignedTo = $users[$story->assignedTo] . "(#$story->assignedTo)";
|
||||
if(isset($users[$story->lastEditedBy])) $story->lastEditedBy = $users[$story->lastEditedBy];
|
||||
if(isset($users[$story->closedBy])) $story->closedBy = $users[$story->closedBy];
|
||||
|
||||
if(isset($storyTasks[$story->id])) $story->taskCountAB = $storyTasks[$story->id];
|
||||
if(isset($storyBugs[$story->id])) $story->bugCountAB = $storyBugs[$story->id];
|
||||
if(isset($storyCases[$story->id])) $story->caseCountAB = $storyCases[$story->id];
|
||||
|
||||
$story->openedDate = substr($story->openedDate, 0, 10);
|
||||
$story->assignedDate = substr($story->assignedDate, 0, 10);
|
||||
$story->lastEditedDate = substr($story->lastEditedDate, 0, 10);
|
||||
$story->closedDate = substr($story->closedDate, 0, 10);
|
||||
|
||||
if($story->linkStories)
|
||||
{
|
||||
$tmpLinkStories = array();
|
||||
$linkStoriesIdList = explode(',', $story->linkStories);
|
||||
foreach($linkStoriesIdList as $linkStoryID)
|
||||
{
|
||||
$linkStoryID = trim($linkStoryID);
|
||||
$tmpLinkStories[] = isset($relatedStories[$linkStoryID]) ? $relatedStories[$linkStoryID] : $linkStoryID;
|
||||
}
|
||||
$story->linkStories = join("; \n", $tmpLinkStories);
|
||||
}
|
||||
|
||||
if($story->childStories)
|
||||
{
|
||||
$tmpChildStories = array();
|
||||
$childStoriesIdList = explode(',', $story->childStories);
|
||||
foreach($childStoriesIdList as $childStoryID)
|
||||
{
|
||||
if(empty($childStoryID)) continue;
|
||||
|
||||
$childStoryID = trim($childStoryID);
|
||||
$tmpChildStories[] = isset($relatedStories[$childStoryID]) ? $relatedStories[$childStoryID] : $childStoryID;
|
||||
}
|
||||
$story->childStories = join("; \n", $tmpChildStories);
|
||||
}
|
||||
|
||||
/* Set related files. */
|
||||
$story->files = '';
|
||||
if(isset($relatedFiles[$story->id]))
|
||||
{
|
||||
foreach($relatedFiles[$story->id] as $file)
|
||||
{
|
||||
$fileURL = common::getSysURL() . helper::createLink('file', 'download', "fileID=$file->id");
|
||||
$story->files .= html::a($fileURL, $file->title, '_blank') . '<br />';
|
||||
}
|
||||
}
|
||||
|
||||
$story->mailto = trim(trim($story->mailto), ',');
|
||||
$mailtos = explode(',', $story->mailto);
|
||||
$story->mailto = '';
|
||||
foreach($mailtos as $mailto)
|
||||
{
|
||||
$mailto = trim($mailto);
|
||||
if(isset($users[$mailto])) $story->mailto .= $users[$mailto] . ',';
|
||||
}
|
||||
$story->mailto = rtrim($story->mailto, ',');
|
||||
|
||||
$story->reviewedBy = trim(trim($story->reviewedBy), ',');
|
||||
$reviewedBys = explode(',', $story->reviewedBy);
|
||||
$story->reviewedBy = '';
|
||||
foreach($reviewedBys as $reviewedBy)
|
||||
{
|
||||
$reviewedBy = trim($reviewedBy);
|
||||
if(isset($users[$reviewedBy])) $story->reviewedBy .= $users[$reviewedBy] . ',';
|
||||
}
|
||||
$story->reviewedBy = rtrim($story->reviewedBy, ',');
|
||||
|
||||
/* Set child story title. */
|
||||
if($story->parent > 0 && strpos($story->title, htmlentities('>', ENT_COMPAT | ENT_HTML401, 'UTF-8')) !== 0) $story->title = '>' . $story->title;
|
||||
}
|
||||
|
||||
if($executionID)
|
||||
{
|
||||
$header = new stdclass();
|
||||
$header->name = 'execution';
|
||||
$header->tableName = TABLE_EXECUTION;
|
||||
|
||||
$this->post->set('header', $header);
|
||||
}
|
||||
if(!(in_array('platform', $productsType) or in_array('branch', $productsType))) unset($fields['branch']);// If products's type are normal, unset branch field.
|
||||
|
||||
if($this->config->edition != 'open') list($fields, $stories) = $this->loadModel('workflowfield')->appendDataFromFlow($fields, $stories);
|
||||
|
||||
$this->post->set('fields', $fields);
|
||||
$this->post->set('rows', $stories);
|
||||
$this->post->set('kind', 'story');
|
||||
$this->fetch('file', 'export2' . $this->post->fileType, $_POST);
|
||||
}
|
||||
|
||||
$fileName = $type == 'requirement' ? $this->lang->URCommon : $this->lang->SRCommon;
|
||||
@@ -2465,197 +2714,11 @@ class story extends control
|
||||
}
|
||||
|
||||
$this->view->fileName = $fileName;
|
||||
$this->view->allExportFields = $this->config->story->exportFields;
|
||||
$this->view->allExportFields = $this->config->story->list->exportFields;
|
||||
$this->view->customExport = true;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
public function getExportStorys($orderBy = 'id_desc')
|
||||
{
|
||||
$this->loadModel('file');
|
||||
$this->loadModel('branch');
|
||||
$storyLang = $this->lang->story;
|
||||
$storyConfig = $this->config->story;
|
||||
|
||||
/* Create field lists. */
|
||||
$fields = $this->post->exportFields ? $this->post->exportFields : explode(',', $storyConfig->list->exportFields);
|
||||
foreach($fields as $key => $fieldName)
|
||||
{
|
||||
$fieldName = trim($fieldName);
|
||||
$fields[$fieldName] = isset($storyLang->$fieldName) ? $storyLang->$fieldName : $fieldName;
|
||||
unset($fields[$key]);
|
||||
}
|
||||
|
||||
/* Get stories. */
|
||||
$stories = array();
|
||||
if($this->session->storyOnlyCondition)
|
||||
{
|
||||
if($this->post->exportType == 'selected')
|
||||
{
|
||||
$stories = $this->dao->select('id,title,linkStories,childStories,parent,mailto,reviewedBy')->from(TABLE_STORY)->where('id')->in($this->cookie->checkedItem)->orderBy($orderBy)->fetchAll('id');
|
||||
}
|
||||
else
|
||||
{
|
||||
$stories = $this->dao->select('id,title,linkStories,childStories,parent,mailto,reviewedBy')->from(TABLE_STORY)->where($this->session->storyQueryCondition)->orderBy($orderBy)->fetchAll('id');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$field = $executionID ? 't2.id' : 't1.id';
|
||||
if($this->post->exportType == 'selected')
|
||||
{
|
||||
$stmt = $this->dbh->query("SELECT * FROM " . TABLE_STORY . "WHERE `id` IN({$this->cookie->checkedItem})" . " ORDER BY " . strtr($orderBy, '_', ' '));
|
||||
}
|
||||
else
|
||||
{
|
||||
$stmt = $this->dbh->query($this->session->storyQueryCondition . " ORDER BY " . strtr($orderBy, '_', ' '));
|
||||
}
|
||||
while($row = $stmt->fetch()) $stories[$row->id] = $row;
|
||||
}
|
||||
$storyIdList = array_keys($stories);
|
||||
|
||||
if($stories)
|
||||
{
|
||||
$children = array();
|
||||
foreach($stories as $story)
|
||||
{
|
||||
if($story->parent > 0 and isset($stories[$story->parent]))
|
||||
{
|
||||
$children[$story->parent][$story->id] = $story;
|
||||
unset($stories[$story->id]);
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($children))
|
||||
{
|
||||
$reorderStories = array();
|
||||
foreach($stories as $story)
|
||||
{
|
||||
$reorderStories[$story->id] = $story;
|
||||
if(isset($children[$story->id]))
|
||||
{
|
||||
foreach($children[$story->id] as $childrenID => $childrenStory)
|
||||
{
|
||||
$reorderStories[$childrenID] = $childrenStory;
|
||||
}
|
||||
}
|
||||
unset($stories[$story->id]);
|
||||
}
|
||||
$stories = $reorderStories;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get users, products and relations. */
|
||||
$users = $this->loadModel('user')->getPairs('noletter');
|
||||
$products = $this->product->getPairs('nocode');
|
||||
$relatedStoryIds = array();
|
||||
foreach($stories as $story)
|
||||
{
|
||||
$relatedStoryIds[$story->id] = $story->id;
|
||||
}
|
||||
|
||||
|
||||
$storyTasks = $this->loadModel('task')->getStoryTaskCounts($relatedStoryIds);
|
||||
$storyBugs = $this->loadModel('bug')->getStoryBugCounts($relatedStoryIds);
|
||||
$storyCases = $this->loadModel('testcase')->getStoryCaseCounts($relatedStoryIds);
|
||||
|
||||
/* Get related objects title or names. */
|
||||
$relatedSpecs = $this->dao->select('*')->from(TABLE_STORYSPEC)->where('`story`')->in($storyIdList)->orderBy('version desc')->fetchGroup('story');
|
||||
|
||||
foreach($stories as $story)
|
||||
{
|
||||
$story->spec = '';
|
||||
$story->verify = '';
|
||||
if(isset($relatedSpecs[$story->id]))
|
||||
{
|
||||
$storySpec = $relatedSpecs[$story->id][0];
|
||||
$story->title = $storySpec->title;
|
||||
$story->spec = $storySpec->spec;
|
||||
$story->verify = $storySpec->verify;
|
||||
}
|
||||
|
||||
if($this->post->fileType == 'csv')
|
||||
{
|
||||
$story->spec = htmlspecialchars_decode($story->spec);
|
||||
$story->spec = str_replace("<br />", "\n", $story->spec);
|
||||
$story->spec = str_replace('"', '""', $story->spec);
|
||||
$story->spec = str_replace(' ', ' ', $story->spec);
|
||||
|
||||
$story->verify = htmlspecialchars_decode($story->verify);
|
||||
$story->verify = str_replace("<br />", "\n", $story->verify);
|
||||
$story->verify = str_replace('"', '""', $story->verify);
|
||||
$story->verify = str_replace(' ', ' ', $story->verify);
|
||||
}
|
||||
/* fill some field with useful value. */
|
||||
|
||||
if(isset($storyTasks[$story->id])) $story->taskCountAB = $storyTasks[$story->id];
|
||||
if(isset($storyBugs[$story->id])) $story->bugCountAB = $storyBugs[$story->id];
|
||||
if(isset($storyCases[$story->id])) $story->caseCountAB = $storyCases[$story->id];
|
||||
|
||||
if($story->linkStories)
|
||||
{
|
||||
$tmpLinkStories = array();
|
||||
$linkStoriesIdList = explode(',', $story->linkStories);
|
||||
foreach($linkStoriesIdList as $linkStoryID)
|
||||
{
|
||||
$linkStoryID = trim($linkStoryID);
|
||||
$tmpLinkStories[] = isset($relatedStories[$linkStoryID]) ? $relatedStories[$linkStoryID] : $linkStoryID;
|
||||
}
|
||||
$story->linkStories = join("; \n", $tmpLinkStories);
|
||||
}
|
||||
|
||||
if($story->childStories)
|
||||
{
|
||||
$tmpChildStories = array();
|
||||
$childStoriesIdList = explode(',', $story->childStories);
|
||||
foreach($childStoriesIdList as $childStoryID)
|
||||
{
|
||||
if(empty($childStoryID)) continue;
|
||||
|
||||
$childStoryID = trim($childStoryID);
|
||||
$tmpChildStories[] = isset($relatedStories[$childStoryID]) ? $relatedStories[$childStoryID] : $childStoryID;
|
||||
}
|
||||
$story->childStories = join("; \n", $tmpChildStories);
|
||||
}
|
||||
|
||||
/* Set related files. */
|
||||
$story->files = '';
|
||||
if(isset($relatedFiles[$story->id]))
|
||||
{
|
||||
foreach($relatedFiles[$story->id] as $file)
|
||||
{
|
||||
$fileURL = common::getSysURL() . helper::createLink('file', 'download', "fileID=$file->id");
|
||||
$story->files .= html::a($fileURL, $file->title, '_blank') . '<br />';
|
||||
}
|
||||
}
|
||||
|
||||
$story->mailto = trim(trim($story->mailto), ',');
|
||||
$mailtos = explode(',', $story->mailto);
|
||||
$story->mailto = '';
|
||||
foreach($mailtos as $mailto)
|
||||
{
|
||||
$mailto = trim($mailto);
|
||||
if(isset($users[$mailto])) $story->mailto .= $users[$mailto] . ',';
|
||||
}
|
||||
$story->mailto = rtrim($story->mailto, ',');
|
||||
|
||||
$story->reviewedBy = trim(trim($story->reviewedBy), ',');
|
||||
$reviewedBys = explode(',', $story->reviewedBy);
|
||||
$story->reviewedBy = '';
|
||||
foreach($reviewedBys as $reviewedBy)
|
||||
{
|
||||
$reviewedBy = trim($reviewedBy);
|
||||
if(isset($users[$reviewedBy])) $story->reviewedBy .= $users[$reviewedBy] . ',';
|
||||
}
|
||||
$story->reviewedBy = rtrim($story->reviewedBy, ',');
|
||||
|
||||
/* Set child story title. */
|
||||
if($story->parent > 0 && strpos($story->title, htmlentities('>', ENT_COMPAT | ENT_HTML401, 'UTF-8')) !== 0) $story->title = '>' . $story->title;
|
||||
}
|
||||
|
||||
return $stories;
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX: get stories of a user in html select.
|
||||
*
|
||||
|
||||
@@ -216,7 +216,8 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->assignedTo;?></th>
|
||||
<td><?php echo html::select('assignedTo', $users, $story->assignedTo, 'class="form-control chosen"');?></td>
|
||||
<?php $assignedToList = $story->status == 'closed' ? $users + array('closed' => 'Closed') : $users;?>
|
||||
<td><?php echo html::select('assignedTo', $assignedToList, $story->assignedTo, 'class="form-control chosen"');?></td>
|
||||
</tr>
|
||||
<?php if($isShowReviewer):?>
|
||||
<tr>
|
||||
|
||||
@@ -1823,7 +1823,7 @@ class taskModel extends model
|
||||
|
||||
if(!empty($task->team))
|
||||
{
|
||||
$myConsumed = $task->team[$task->assignedTo]->consumed;
|
||||
$myConsumed = $task->team[$this->app->user->account]->consumed;
|
||||
|
||||
$newTeamInfo = new stdClass();
|
||||
$newTeamInfo->consumed = $myConsumed + $consumed;
|
||||
@@ -1831,7 +1831,7 @@ class taskModel extends model
|
||||
$this->dao->update(TABLE_TEAM)->data($newTeamInfo)
|
||||
->where('root')->eq($taskID)
|
||||
->andWhere('type')->eq('task')
|
||||
->andWhere('account')->eq($task->assignedTo)
|
||||
->andWhere('account')->eq($this->app->user->account)
|
||||
->exec();
|
||||
|
||||
$data = $this->computeHours4Multiple($task, $data);
|
||||
|
||||
@@ -131,7 +131,7 @@ function setStories()
|
||||
productID = $('#product').val();
|
||||
branch = $('#branch').val();
|
||||
if(typeof(branch) == 'undefined') branch = 0;
|
||||
link = createLink('story', 'ajaxGetProductStories', 'productID=' + productID + '&branch=' + branch + '&moduleID=' + moduleID + '&storyID=0&onlyOption=false&status=noclosed&limit=50&type=full&hasParent=1&executionID=' + executionID);
|
||||
link = createLink('story', 'ajaxGetProductStories', 'productID=' + productID + '&branch=' + branch + '&moduleID=' + moduleID + '&storyID=0&onlyOption=false&status=noclosed&limit=0&type=full&hasParent=1&executionID=' + executionID);
|
||||
|
||||
$.get(link, function(stories)
|
||||
{
|
||||
@@ -141,7 +141,7 @@ function setStories()
|
||||
$('#story').val(value);
|
||||
$('#story_chosen').remove();
|
||||
$('#story').next('.picker').remove();
|
||||
$("#story").chosen();
|
||||
$("#story").picker();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -364,7 +364,7 @@ function loadStories(productID, moduleID, num)
|
||||
{
|
||||
var branchIDName = (config.currentMethod == 'batchcreate' || config.currentMethod == 'showimport') ? '#branch' : '#branches';
|
||||
var branchID = $(branchIDName + num).val();
|
||||
var storyLink = createLink('story', 'ajaxGetProductStories', 'productID=' + productID + '&branch=' + branchID + '&moduleID=' + moduleID + '&storyID=0&onlyOption=false&status=noclosed&limit=50&type=full&hasParent=1&executionID=0&number=' + num);
|
||||
var storyLink = createLink('story', 'ajaxGetProductStories', 'productID=' + productID + '&branch=' + branchID + '&moduleID=' + moduleID + '&storyID=0&onlyOption=false&status=noclosed&limit=0&type=full&hasParent=1&executionID=0&number=' + num);
|
||||
$.get(storyLink, function(stories)
|
||||
{
|
||||
if(!stories) stories = '<select id="story' + num + '" name="story[' + num + ']" class="form-control"></select>';
|
||||
@@ -378,7 +378,7 @@ function loadStories(productID, moduleID, num)
|
||||
$('#story' + i + "_chosen").remove();
|
||||
$('#story' + i).next('.picker').remove();
|
||||
$('#story' + i).attr('name', 'story[' + i + ']');
|
||||
$('#story' + i).chosen();
|
||||
$('#story' + i).picker();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -387,7 +387,7 @@ function loadStories(productID, moduleID, num)
|
||||
$('#story' + num + "_chosen").remove();
|
||||
$('#story' + num).next('.picker').remove();
|
||||
$('#story' + num).attr('name', 'story[' + num + ']');
|
||||
$('#story' + num).chosen();
|
||||
$('#story' + num).picker();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
<td class="text-center"><?php echo $i;?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, $product->type, ' hidden')?> branchBox'><?php echo html::select("branch[$i]", $branches, $branch, "class='form-control' onchange='setModules(this.value, $productID, $i)'");?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'module', ' hidden')?> moduleBox' style='overflow:visible'><?php echo html::select("module[$i]", $moduleOptionMenu, $currentModuleID, "class='form-control chosen' onchange='loadStories($productID, this.value, $i)' data-drop_direction='down'");?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'story', ' hidden'); echo $hiddenStory;?> storyBox' style='overflow:visible'> <?php echo html::select("story[$i]", $storyPairs, $story ? $story->id : '', 'class="form-control chosen"');?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'story', ' hidden'); echo $hiddenStory;?> storyBox' style='overflow:visible'> <?php echo html::select("story[$i]", $storyPairs, $story ? $story->id : '', 'class="form-control picker-select"');?></td>
|
||||
<td style='overflow:visible'>
|
||||
<div class="input-control has-icon-right">
|
||||
<?php echo html::input("title[$i]", '', "class='form-control title-import'");?>
|
||||
@@ -141,7 +141,7 @@
|
||||
<td class="text-center">%s</td>
|
||||
<td class='text-left<?php echo zget($visibleFields, $product->type, ' hidden')?> branchBox'><?php echo html::select("branch[%s]", $branches, $branch, "class='form-control chosen' onchange='setModules(this.value, $productID, \"%s\")'");?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'module', ' hidden')?> moduleBox' style='overflow:visible'><?php echo html::select("module[%s]", $moduleOptionMenu, $currentModuleID, "class='form-control chosen' onchange='loadStories($productID, this.value, \"%s\")' data-drop_direction='down'");?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'story', ' hidden'); echo $hiddenStory;?> storyBox' style='overflow:visible'> <?php echo html::select("story[%s]", $storyPairs, '', 'class="form-control chosen"');?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'story', ' hidden'); echo $hiddenStory;?> storyBox' style='overflow:visible'> <?php echo html::select("story[%s]", $storyPairs, '', 'class="form-control picker-select"');?></td>
|
||||
<td style='overflow:visible'>
|
||||
<div class="input-control has-icon-right">
|
||||
<?php echo html::input("title[%s]", '', "class='form-control title-import'");?>
|
||||
@@ -180,7 +180,7 @@
|
||||
<td class="text-center"><?php echo $i;?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, $product->type, ' hidden')?> branchBox'><?php echo html::select("branch[$i]", $branches, $branch, "class='form-control' onchange='setModules(this.value, $productID, $i)'");?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'module', ' hidden')?> moduleBox' style='overflow:visible'><?php echo html::select("module[$i]", $moduleOptionMenu, $currentModuleID, "class='form-control chosen' onchange='loadStories($productID, this.value, $i)' data-drop_direction='down'");?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'story', ' hidden'); echo $hiddenStory;?> storyBox' style='overflow:visible'> <?php echo html::select("story[$i]", $storyPairs, $story ? $story->id : '', 'class="form-control chosen"');?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'story', ' hidden'); echo $hiddenStory;?> storyBox' style='overflow:visible'> <?php echo html::select("story[$i]", $storyPairs, $story ? $story->id : '', 'class="form-control picker-select"');?></td>
|
||||
<td style='overflow:visible'>
|
||||
<div class="input-control has-icon-right">
|
||||
<?php echo html::input("title[$i]", '', "class='form-control title-import'");?>
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
</td>
|
||||
<?php endif;?>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'module', ' hidden')?>' style='overflow:visible'><?php echo html::select("modules[$caseID]", zget($modulePairs, $caseID, array(0 => '/')), $cases[$caseID]->module, "class='form-control chosen' onchange='loadStories($productID, this.value, $caseID)'");?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'story', ' hidden')?>' style='overflow:visible'><?php echo html::select("story[$caseID]", $stories, $cases[$caseID]->story, "class='form-control chosen'");?></td>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'story', ' hidden')?>' style='overflow:visible'><?php echo html::select("story[$caseID]", $stories, $cases[$caseID]->story, "class='form-control picker-select'");?></td>
|
||||
<td style='overflow:visible' title='<?php echo $cases[$caseID]->title?>'>
|
||||
<div class='input-group'>
|
||||
<div class="input-control has-icon-right">
|
||||
|
||||
@@ -84,7 +84,7 @@ foreach(explode(',', $config->testcase->create->requiredFields) as $field)
|
||||
<th><?php echo $lang->testcase->lblStory;?></th>
|
||||
<td colspan='2'>
|
||||
<div class='input-group' id='storyIdBox'>
|
||||
<?php echo html::select('story', $stories, $storyID, 'class="form-control chosen" onchange="setPreview();" data-no_results_text="' . $lang->searchMore . '"');?>
|
||||
<?php echo html::select('story', $stories, $storyID, 'class="form-control picker-select" onchange="setPreview();" data-no_results_text="' . $lang->searchMore . '"');?>
|
||||
<span class='input-group-btn' style='width: 0.01%'>
|
||||
<?php if($storyID == 0): ?>
|
||||
<a href='' id='preview' class='btn hidden'><?php echo $lang->preview;?></a>
|
||||
|
||||
@@ -204,7 +204,7 @@
|
||||
<?php if(!$isLibCase):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->testcase->story;?></th>
|
||||
<td class='text-left'><div id='storyIdBox'><?php echo html::select('story', $stories, $case->story, 'class="form-control chosen"');?></div>
|
||||
<td class='text-left'><div id='storyIdBox'><?php echo html::select('story', $stories, $case->story, 'class="form-control picker-select"');?></div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
|
||||
@@ -5038,7 +5038,7 @@ class upgradeModel extends model
|
||||
public function computeObjectMembers()
|
||||
{
|
||||
$this->app->loadLang('user');
|
||||
$projects = $this->dao->select('id,days')->from(TABLE_PROJECT)->where('type')->eq('project')->fetchAll('id');
|
||||
$projects = $this->dao->select('id,days,PM')->from(TABLE_PROJECT)->where('type')->eq('project')->fetchAll('id');
|
||||
$projectIdList = array_keys($projects);
|
||||
|
||||
/* Get product and sprint team. */
|
||||
@@ -5091,7 +5091,9 @@ class upgradeModel extends model
|
||||
|
||||
$projectMember = array_filter($projectMember);
|
||||
$project = zget($projects, $projectID, '');
|
||||
$members = implode(',', $projectMember);
|
||||
|
||||
if(!empty($project) and !isset($projectMember[$project->PM])) $projectMember[$project->PM] = $project->PM;
|
||||
$members = implode(',', $projectMember);
|
||||
|
||||
$this->dao->update(TABLE_DOCLIB)
|
||||
->set('users')->eq($members)
|
||||
|
||||
@@ -24,3 +24,4 @@ html[lang='en'] #loginPanel .table-form > tbody > tr > th {width: 80px;}
|
||||
.table-row-extension .alert {margin-bottom: 0px !important;}
|
||||
.table-row-extension .content {color: #3c4353;}
|
||||
.table-row-extension .expired-tips {cursor: pointer;}
|
||||
[lang^=fr] #loginPanel .table-form > tbody > tr > th {width: 100px;}
|
||||
|
||||
Reference in New Issue
Block a user