diff --git a/module/convert/config.php b/module/convert/config.php index 62daea9fcc..9c5aff8f35 100644 --- a/module/convert/config.php +++ b/module/convert/config.php @@ -11,3 +11,4 @@ define('JIRA_RESOLUTION', '`resolution`'); define('JIRA_PROJECTVERSION', '`projectversion`'); define('JIRA_NODEASSOCIATION', '`nodeassociation`'); define('JIRA_FILEATTACHMENT', '`fileattachment`'); +define('JIRA_TMPRELATION', '`jiratmprelation`'); diff --git a/module/convert/control.php b/module/convert/control.php index 837ec388f6..cdf3fd6792 100644 --- a/module/convert/control.php +++ b/module/convert/control.php @@ -314,7 +314,7 @@ class convert extends control if($_POST) { - $this->session->set('linkType', $_POST); + $this->session->set('jiraRelation', $_POST); $response['result'] = 'success'; $response['message'] = $this->lang->saveSuccess; @@ -391,7 +391,7 @@ class convert extends control * @access public * @return void */ - public function importJira($method = 'db', $type = 'user', $lastID = 0) + public function importJira($method = 'db', $type = 'user', $lastID = 0, $createTable = false) { set_time_limit(0); @@ -399,7 +399,7 @@ class convert extends control { if(helper::isAjaxRequest()) { - $result = $this->convert->importJiraFromDB($type, $lastID); + $result = $this->convert->importJiraFromDB($type, $lastID, $createTable); if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); if(isset($result['finished']) and $result['finished']) { @@ -423,8 +423,9 @@ class convert extends control //$this->convert->importJiraFromFile(); } - $this->view->type = $type; - $this->view->title = $this->lang->convert->jira->importJira; + $this->view->type = $type; + $this->view->method = $method; + $this->view->title = $this->lang->convert->jira->importJira; $this->display(); } } diff --git a/module/convert/model.php b/module/convert/model.php index 3c5bcc52f1..1621664b24 100644 --- a/module/convert/model.php +++ b/module/convert/model.php @@ -102,8 +102,10 @@ class convertModel extends model * @access public * @return void */ - public function importJiraFromDB($type = '', $lastID = 0) + public function importJiraFromDB($type = '', $lastID = 0, $createTable = false) { + if($createTable) $this->createTmpTable4Jira(); + $this->connectDB($this->session->jiraDB); $limit = 1000; @@ -127,12 +129,14 @@ class convertModel extends model if($module == 'user') $this->importJiraUser($dataList); if($module == 'project') $this->importJiraProject($dataList); + if($module == 'issue') $this->importJiraIssue($dataList); return array('type' => $module, 'count' => count($dataList), 'lastID' => max(array_keys($dataList))); } - - return array('finished' => true); } + + $this->dbh->exec("DROP TABLE" . JIRA_TMPRELATION); + return array('finished' => true); } /** @@ -144,18 +148,28 @@ class convertModel extends model */ public function getJiraData($module = '', $lastID = 0, $limit = 0) { + $dataList = array(); if($module == 'user') { $dataList = $this->dao->dbh($this->sourceDBH)->select('t1.`ID`, t1.`lower_user_name` as account, t1.`lower_display_name` as realname, t1.`lower_email_address` as email, t1.created_date as `join`, t2.user_key as userCode')->from(JIRA_USERINFO)->alias('t1') ->leftJoin(JIRA_USER)->alias('t2')->on('t1.`lower_user_name` = t2.`lower_user_name`') - ->where('t1.active')->eq(1) + ->where(1) ->beginIF($lastID)->andWhere('t1.ID')->gt($lastID)->fi() ->orderBy('t1.ID asc')->limit($limit) ->fetchAll('ID'); } - elesif($module == 'project') + elseif($module == 'project') { - $dataList = $this->dao->dbh($this->sourceDBH)->select('*')->from('project') + $dataList = $this->dao->dbh($this->sourceDBH)->select('*')->from(JIRA_PROJECT) + ->where(1) + ->beginIF($lastID)->andWhere('ID')->gt($lastID)->fi() + ->orderBy('ID asc')->limit($limit) + ->fetchAll('ID'); + } + elseif($module == 'issue') + { + $dataList = $this->dao->dbh($this->sourceDBH)->select('*')->from(JIRA_ISSUE) + ->where(1) ->beginIF($lastID)->andWhere('ID')->gt($lastID)->fi() ->orderBy('ID asc')->limit($limit) ->fetchAll('ID'); @@ -198,5 +212,394 @@ class convertModel extends model public function importJiraProject($dataList) { + global $app; + $app->loadConfig('execution'); + $app->loadLang('doc'); + $now = helper::now(); + + foreach($dataList as $id => $data) + { + $projectRelation = array(); + $executionRelation = array(); + $productRelation = array(); + + /* Create project. */ + $project = new stdclass(); + $project->name = $data->pname; + $project->code = $data->pkey; + $project->desc = $data->DESCRIPTION; + $project->status = 'wait'; + $project->type = 'project'; + $project->model = 'scrum'; + $project->grade = 1; + $project->acl = 'open'; + $project->end = date('Y-m-d', time() + 24 * 3600); + + $project->PM = $this->getJiraAccount($data->LEAD); + $project->openedBy = $this->getJiraAccount($data->LEAD); + $project->openedDate = $now; + $project->openedVersion = $this->config->version; + $this->dao->dbh($this->dbh)->insert(TABLE_PROJECT)->data($project)->exec(); + + $projectID = $this->dao->dbh($this->dbh)->lastInsertID(); + $this->dao->dbh($this->dbh)->update(TABLE_PROJECT)->set('`order`')->eq($projectID * 5)->set('path')->eq(",$projectID,")->where('id')->eq($projectID)->exec(); + + $member = new stdclass(); + $member->root = $projectID; + $member->account = $project->openedBy; + $member->role = ''; + $member->join = ''; + $member->type = 'project'; + $member->days = 0; + $member->hours = $this->config->execution->defaultWorkhours; + $this->dao->dbh($this->dbh)->insert(TABLE_TEAM)->data($member)->exec(); + + /* Create doc lib. */ + $lib = new stdclass(); + $lib->project = $projectID; + $lib->name = $this->lang->doclib->main['project']; + $lib->type = 'project'; + $lib->main = '1'; + $lib->acl = 'default'; + $this->dao->dbh($this->dbh)->insert(TABLE_DOCLIB)->data($lib)->exec(); + + /* Create execution. */ + $execution = new stdclass(); + $execution->name = $data->pname; + $execution->code = $data->pkey; + $execution->desc = $data->DESCRIPTION; + $execution->status = 'wait'; + $execution->project = $projectID; + $execution->parent = $projectID; + $execution->grade = 1; + $execution->type = 'sprint'; + $execution->acl = 'open'; + $execution->end = date('Y-m-d', time() + 24 * 3600); + + $execution->PM = $project->PM; + $execution->openedBy = $project->openedBy; + $execution->openedDate = $now; + $execution->openedVersion = $this->config->version; + $this->dao->dbh($this->dbh)->insert(TABLE_PROJECT)->data($execution)->exec(); + + $executionID = $this->dao->dbh($this->dbh)->lastInsertID(); + $this->dao->dbh($this->dbh)->update(TABLE_PROJECT)->set('`order`')->eq($executionID * 5)->set('path')->eq(",$projectID,$executionID,")->where('id')->eq($executionID)->exec(); + + $member = new stdclass(); + $member->root = $executionID; + $member->account = $execution->openedBy; + $member->role = ''; + $member->join = ''; + $member->type = 'execution'; + $member->days = 0; + $member->hours = $this->config->execution->defaultWorkhours; + $this->dao->dbh($this->dbh)->insert(TABLE_TEAM)->data($member)->exec(); + + /* Create doc lib. */ + $lib = new stdclass(); + $lib->project = $projectID; + $lib->execution = $executionID; + $lib->name = $this->lang->doclib->main['project']; + $lib->type = 'execution'; + $lib->main = '1'; + $lib->acl = 'default'; + $this->dao->dbh($this->dbh)->insert(TABLE_DOCLIB)->data($lib)->exec(); + + /* Create product. */ + $product = new stdclass(); + $product->name = $project->name; + $product->code = $project->code; + $product->type = 'normal'; + $product->status = 'normal'; + $product->acl = 'open'; + + $product->createdBy = $project->openedBy; + $product->createdDate = helper::now(); + $product->createdVersion = $this->config->version; + $this->dao->dbh($this->dbh)->insert(TABLE_PRODUCT)->data($product)->exec(); + + $productID = $this->dao->dbh($this->dbh)->lastInsertID(); + + /* Create doc lib. */ + $lib = new stdclass(); + $lib->product = $productID; + $lib->name = $this->lang->doclib->main['product']; + $lib->type = 'product'; + $lib->main = '1'; + $lib->acl = 'default'; + $this->dao->dbh($this->dbh)->insert(TABLE_DOCLIB)->data($lib)->exec(); + + $this->dao->dbh($this->dbh)->update(TABLE_PRODUCT)->set('`order`')->eq($productID * 5)->where('id')->eq($productID)->exec(); + $this->dao->dbh($this->dbh)->replace(TABLE_PROJECTPRODUCT)->set('project')->eq($projectID)->set('product')->eq($productID)->exec(); + $this->dao->dbh($this->dbh)->replace(TABLE_PROJECTPRODUCT)->set('project')->eq($executionID)->set('product')->eq($productID)->exec(); + + $projectRelation['AType'] = 'jproject'; + $projectRelation['BType'] = 'zproject'; + $projectRelation['AID'] = $id; + $projectRelation['BID'] = $projectID; + + $this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($projectRelation)->exec(); + + $executionRelation['AType'] = 'jproject'; + $executionRelation['BType'] = 'zexecution'; + $executionRelation['AID'] = $id; + $executionRelation['BID'] = $executionID; + + $this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($executionRelation)->exec(); + } + } + + public function importJiraIssue($dataList) + { + $relations = $this->session->jiraRelation; + + $this->app->loadLang('story'); + $this->app->loadLang('task'); + $this->app->loadLang('bug'); + + $projectRelation = $this->dao->dbh($this->dbh)->select('AID,BID')->from(JIRA_TMPRELATION) + ->where('AType')->eq('jproject') + ->andWhere('BType')->eq('zproject') + ->fetchPairs(); + + $projectProduct = $this->dao->dbh($this->dbh)->select('project,product')->from(TABLE_PROJECTPRODUCT) + ->where('project')->in(array_values($projectRelation)) + ->fetchPairs(); + + $projectExecution = $this->dao->dbh($this->dbh)->select('project,id')->from(TABLE_PROJECT) + ->where('project')->in(array_values($projectRelation)) + ->fetchPairs(); + + $issueTypeList = array(); + foreach($relations['jiraObject'] as $id => $jiraCode) + { + $issueTypeList[$jiraCode] = $relations['zentaoObject'][$id]; + } + + $reasonList = array(); + $resolutionList = array(); + foreach($relations['jiraResolution'] as $id => $jiraCode) + { + if(!empty($relations['zentaoReason'][$id])) $reasonList[$jiraCode] = $relations['zentaoReason'][$id]; + if(!empty($relations['zentaoResolution'][$id])) $resolutionList[$jiraCode] = $relations['zentaoResolution'][$id]; + } + + $projectKeys = $this->dao->dbh($this->sourceDBH)->select('ID, ORIGINALKEY as oldKey, pkey as newKey')->from(JIRA_PROJECT)->fetchAll('ID'); + + $issueObjectType = array(); + foreach($dataList as $id => $data) + { + $issueType = isset($issueTypeList[$data->issuetype]) ? $issueTypeList[$data->issuetype] : 'task'; + $issueID = $data->ID; + $issueProject = $data->PROJECT; + + if(!isset($projectRelation[$issueProject])) continue; + + $projectID = $projectRelation[$issueProject]; + $productID = $projectProduct[$projectID]; + $executionID = $projectExecution[$projectID]; + + if($issueType == 'requirement' or $issueType == 'story') + { + $story = new stdclass(); + $story->product = $productID; + $story->title = $data->SUMMARY; + $story->type = $issueType; + $story->pri = $data->PRIORITY; + $story->version = 1; + $story->stage = $this->convertStage($data->issuestatus); + $story->status = $this->convertStatus('story', $data->issuestatus); + $story->openedBy = $this->getJiraAccount($data->CREATOR); + $story->openedDate = substr($data->CREATED, 0, 19); + $story->assignedTo = $this->getJiraAccount($data->ASSIGNEE); + + if($data->RESOLUTION) + { + $story->closedReason = zget($reasonList, $data->RESOLUTION, ''); + if($story->closedReason and !isset($this->lang->story->reasonList[$story->closedReason])) $story->closedReason = 'done'; + } + + $this->dao->dbh($this->dbh)->insert(TABLE_STORY)->data($story)->exec(); + + if(!dao::isError()) + { + $storyID = $this->dao->dbh($this->dbh)->lastInsertID(); + + $storyDesc = new stdclass(); + $storyDesc->story = $storyID; + $storyDesc->version = 1; + $storyDesc->title = $story->title; + $storyDesc->spec = $data->DESCRIPTION; + $this->dao->dbh($this->dbh)->replace(TABLE_STORYSPEC)->data($storyDesc)->exec(); + $this->dao->dbh($this->dbh)->replace(TABLE_PROJECTSTORY)->set('project')->eq($projectID) + ->set('product')->eq($productID) + ->set('story')->eq($storyID) + ->set('version')->eq('1') + ->exec(); + + $this->dao->dbh($this->dbh)->replace(TABLE_PROJECTSTORY)->set('project')->eq($executionID) + ->set('product')->eq($productID) + ->set('story')->eq($storyID) + ->set('version')->eq('1') + ->exec(); + + $storyRelation['AType'] = 'jstory'; + $storyRelation['BType'] = 'zstory'; + $storyRelation['AID'] = $issueID; + $storyRelation['BID'] = $storyID; + $this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($storyRelation)->exec(); + + $issueRelation['AType'] = 'jissueid'; + $issueRelation['BType'] = 'zissuetype'; + $issueRelation['AID'] = $issueID; + $issueRelation['extra'] = 'story'; + $this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($issueRelation)->exec(); + } + } + elseif($issueType == 'task' or $issueType == 'subTask') + { + $task = new stdclass(); + $task->project = $projectID; + $task->execution = $executionID; + $task->name = $data->SUMMARY; + $task->type = 'devel'; + $task->pri = $data->PRIORITY; + $task->status = $this->convertStatus('task', $data->issuestatus); + $task->desc = $data->DESCRIPTION; + $task->openedBy = $this->getJiraAccount($data->CREATOR); + $task->openedDate = substr($data->CREATED, 0, 19); + $task->assignedTo = $this->getJiraAccount($data->ASSIGNEE); + if($data->RESOLUTION) + { + $task->closedReason = zget($reasonList, $data->RESOLUTION, ''); + if($task->closedReason and !isset($this->lang->task->reasonList[$task->closedReason])) $task->closedReason = 'cancel'; + } + + $this->dao->dbh($this->dbh)->insert(TABLE_TASK)->data($task)->exec(); + $taskID = $this->dao->dbh($this->dbh)->lastInsertID(); + + $taskRelation['AType'] = 'jtask'; + $taskRelation['BType'] = 'ztask'; + $taskRelation['AID'] = $issueID; + $taskRelation['BID'] = $taskID; + $this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($taskRelation)->exec(); + + $issueRelation['AType'] = 'jissueid'; + $issueRelation['BType'] = 'zissuetype'; + $issueRelation['AID'] = $issueID; + $issueRelation['extra'] = 'task'; + $this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($issueRelation)->exec(); + } + elseif($issueType == 'bug') + { + $bug = new stdclass(); + $bug->product = $productID; + $bug->project = $projectID; + $bug->title = $data->SUMMARY; + $bug->pri = $data->PRIORITY; + $bug->status = $this->convertStatus('bug', $data->issuestatus); + $bug->steps = $data->DESCRIPTION; + $bug->openedBy = $this->getJiraAccount($data->CREATOR); + $bug->openedDate = substr($data->CREATED, 0, 19); + $bug->openedBuild = 'trunk'; + $bug->assignedTo = $this->getJiraAccount($data->ASSIGNEE); + + if($data->RESOLUTION) + { + $bug->resolution = zget($resolutionList, $data->RESOLUTION, ''); + if($bug->resolution and !isset($this->lang->bug->resolutionList[$bug->resolution])) $bug->resolution = 'fixed'; + } + + $this->dao->dbh($this->dbh)->insert(TABLE_BUG)->data($bug)->exec(); + $bugID = $this->dao->dbh($this->dbh)->lastInsertID(); + + $bugRelation['AType'] = 'jbug'; + $bugRelation['BType'] = 'zbug'; + $bugRelation['AID'] = $issueID; + $bugRelation['BID'] = $bugID; + $this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($bugRelation)->exec(); + + $issueRelation['AType'] = 'jissueid'; + $issueRelation['BType'] = 'zissuetype'; + $issueRelation['AID'] = $issueID; + $issueRelation['extra'] = 'bug'; + $this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($issueRelation)->exec(); + } + + $oldKey = zget($projectKeys[$issueProject], 'oldKey', ''); + $newKey = zget($projectKeys[$issueProject], 'newKey', ''); + $issueKey = $oldKey ? $oldKey . '-' . $data->issuenum : $newKey . '-' . $data->issuenum; + + $fileRelation['AType'] = 'jissueid'; + $fileRelation['BType'] = 'jfilepath'; + $fileRelation['AID'] = $issueID; + $fileRelation['extra'] = "{$oldKey}/10000/{$issueKey}/"; + + $this->dao->dbh($this->dbh)->insert(JIRA_TMPRELATION)->data($fileRelation)->exec(); + } + } + + public function convertStatus($objectType, $jiraStatus) + { + $relations = $this->session->jiraRelation; + + $status = 'active'; + if($objectType == 'task') $status = 'wait'; + + $arrayKey = "{$objectType}Status"; + foreach($relations['jiraStatus'] as $id => $jiraCode) + { + if($jiraCode == $jiraStatus) + { + if(!empty($relations[$arrayKey][$id])) $status = $relations[$arrayKey][$id]; + } + } + + return $status; + } + + public function convertStage($jiraStatus) + { + $stage = 'wait'; + $relations = $this->session->jiraRelation; + + foreach($relations['jiraStatus'] as $id => $jiraCode) + { + if($jiraCode == $jiraStatus) + { + if(!empty($relations['storyStage'][$id])) $stage = $relations['storyStage'][$id]; + } + } + + return $stage; + } + + public function getJiraAccount($userKey) + { + if(strpos($userKey, 'JIRAUSER') === false) return $userKey; + + return $this->dao->dbh($this->sourceDBH)->select('lower_user_name')->from(JIRA_USER)->where('user_key')->eq($userKey)->fetch('lower_user_name'); + } + + public function createTmpTable4Jira() + { +$sql = <<dbh->exec($sql); + } + catch(Exception $e){} } } diff --git a/module/convert/view/importjira.html.php b/module/convert/view/importjira.html.php index 7182862158..e764849fd9 100644 --- a/module/convert/view/importjira.html.php +++ b/module/convert/view/importjira.html.php @@ -19,7 +19,7 @@
-
convert->jira->start, '', "class='btn btn-primary' id='execButton'");?>
+
convert->jira->start, '', "class='btn btn-primary' id='execButton'");?>