diff --git a/config/filter.php b/config/filter.php index f3d859fd6d..17961573b8 100644 --- a/config/filter.php +++ b/config/filter.php @@ -34,6 +34,7 @@ $filter->qa = new stdclass(); $filter->story = new stdclass(); $filter->task = new stdclass(); $filter->testcase = new stdclass(); +$filter->program = new stdclass(); $filter->project = new stdclass(); $filter->testreport = new stdclass(); $filter->testsuite = new stdclass(); @@ -68,6 +69,7 @@ $filter->file->download = new stdclass(); $filter->product->browse = new stdclass(); $filter->product->default = new stdclass(); $filter->product->index = new stdclass(); +$filter->program->default = new stdclass(); $filter->project->default = new stdclass(); $filter->project->story = new stdclass(); $filter->project->task = new stdclass(); @@ -128,6 +130,8 @@ $filter->product->default->cookie['preProductID'] = 'int'; $filter->product->index->cookie['preBranch'] = 'int'; $filter->product->export->cookie['checkedItem'] = 'reg::checked'; +$filter->program->index->cookie['programType'] = 'code'; + $filter->project->default->cookie['lastProject'] = 'int'; $filter->project->default->cookie['projectMode'] = 'code'; $filter->project->story->cookie['storyModuleParam'] = 'int'; diff --git a/db/update15.0.sql b/db/update15.0.sql index edfd21a4ec..408393d3b1 100644 --- a/db/update15.0.sql +++ b/db/update15.0.sql @@ -1,5 +1,6 @@ ALTER TABLE `zt_project` CHANGE `type` `type` varchar(20) COLLATE 'utf8_general_ci' NOT NULL DEFAULT 'waterfall' AFTER `catID`, -ADD `program` mediumint(8) NOT NULL DEFAULT '0' AFTER `type`, +ADD `category` char(30) NOT NULL AFTER `type`, +ADD `program` mediumint(8) NOT NULL DEFAULT '0' AFTER `category`, ADD `budget` varchar(30) NOT NULL DEFAULT '0' AFTER `program`, ADD `budgetUnit` char(30) NOT NULL DEFAULT 'yuan' AFTER `budget`; diff --git a/module/common/lang/zh-cn.php b/module/common/lang/zh-cn.php index 25d6f1f916..47b29b5e43 100644 --- a/module/common/lang/zh-cn.php +++ b/module/common/lang/zh-cn.php @@ -130,7 +130,7 @@ $lang->mainNav->recent = ' 近期|recent|i $lang->dividerMenu = ',admin,recent,'; $lang->menu = new stdclass(); -$lang->menu->project = new stdclass(); +$lang->menu->project = ''; /* 查询条中可以选择的对象列表。*/ $lang->searchObjects['bug'] = 'Bug'; diff --git a/module/program/control.php b/module/program/control.php index 3b893f37da..c89b4a4ccb 100644 --- a/module/program/control.php +++ b/module/program/control.php @@ -11,20 +11,13 @@ class program extends control { if(common::hasPriv('program', 'create')) $this->lang->pageActions = html::a($this->createLink('program', 'create'), " " . $this->lang->program->create, '', "class='btn btn-primary'"); - //$programType = $this->cookie->programType; - $programType = 'bylist'; + $programType = $this->cookie->programType; - if($programType == 'bylist') - { - $this->app->loadClass('pager', $static = true); - $pager = new pager($recTotal, $recPerPage, $pageID); - $projectList = $this->project->getProjectStats($status, 0, 0, 30, $orderBy, $pager, 'program'); - $this->view->pager = $pager; - } + $this->app->loadClass('pager', $static = true); + $pager = new pager($recTotal, $recPerPage, $pageID); + $this->view->pager = $pager; - if(!$programType || $programType == 'bygrid') $projectList = $this->project->getList($status, 0, 0, 0, 'program'); - - $this->view->projectList = $projectList; + $this->view->projectList = $this->program->getList($status, $orderBy, $pager); $this->view->status = $status; $this->view->orderBy = $orderBy; $this->view->users = $this->loadModel('user')->getPairs('noletter'); @@ -34,7 +27,7 @@ class program extends control $this->display(); } - public function create() + public function create($type = 'scrum', $copyProgramID = '') { if($_POST) { @@ -47,10 +40,33 @@ class program extends control $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('index'))); } - $this->view->pmUsers = $this->loadModel('user')->getPairs('noclosed|nodeleted|pmfirst'); - $this->view->title = $this->lang->program->create; - $this->view->position[] = $this->lang->program->create; - $this->view->groups = $this->loadModel('group')->getPairs(); + $name = ''; + $code = ''; + $team = ''; + $whitelist = ''; + $acl = 'open'; + if($copyProgramID) + { + $copyProgram = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($copyProgramID)->fetch(); + $name = $copyProgram->name; + $code = $copyProgram->code; + $team = $copyProgram->team; + $acl = $copyProgram->acl; + $whitelist = $copyProgram->whitelist; + } + + $this->view->title = $this->lang->program->create; + $this->view->position[] = $this->lang->program->create; + $this->view->groups = $this->loadModel('group')->getPairs(); + $this->view->pmUsers = $this->loadModel('user')->getPairs('noclosed|nodeleted|pmfirst'); + $this->view->programs = array('' => '') + $this->program->getPairsByType($type); + $this->view->type = $type; + $this->view->name = $name; + $this->view->code = $code; + $this->view->team = $team; + $this->view->acl = $acl; + $this->view->whitelist = $whitelist; + $this->view->copyProgramID = $copyProgramID; $this->display(); } diff --git a/module/program/css/create.css b/module/program/css/create.css new file mode 100644 index 0000000000..c6c42d376b --- /dev/null +++ b/module/program/css/create.css @@ -0,0 +1,9 @@ +#copyProjectModal {padding: 0} +#copyProjectModal {padding: 0 2px} +#copyProjectModal > div {position: relative;} +#copyProjectModal a {display: block; min-height: 30px; line-height: 30px; padding: 5px 15px; border: 1px solid #e5e5e5; color: #333; margin: 5px 0; border-radius: 3px;} +#copyProjectModal a > i {display: inline-block; margin-right: 5px;} +#copyProjectModal a:hover {border:1px solid #00a9fc; background-color: #E9F2FB; text-decoration: none} +#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} diff --git a/module/program/js/common.js b/module/program/js/common.js index 92397e88dc..4f3ee6a1a3 100644 --- a/module/program/js/common.js +++ b/module/program/js/common.js @@ -1,9 +1,3 @@ -$().ready(function() -{ - $('#navbar').find('li').removeClass('active'); - if(typeof(status) == 'undefined' || !status) status = 'all'; - $('#navbar').find('a[href*=' + status + ']').parent().addClass('active'); -}); function setWhite(acl) { acl == 'custom' ? $('#whitelistBox').removeClass('hidden') : $('#whitelistBox').addClass('hidden'); @@ -14,3 +8,104 @@ function setProgramType(type) $.cookie('programType', type, {expires:config.cookieLife, path:config.webRoot}); location.href = location.href; } + +/** + * Convert a date string like 2011-11-11 to date object in js. + * + * @param string $date + * @access public + * @return date + */ +function convertStringToDate(dateString) +{ + dateString = dateString.split('-'); + return new Date(dateString[0], dateString[1] - 1, dateString[2]); +} + +/** + * Compute delta of two days. + * + * @param string $date1 + * @param string $date1 + * @access public + * @return int + */ +function computeDaysDelta(date1, date2) +{ + date1 = convertStringToDate(date1); + date2 = convertStringToDate(date2); + delta = (date2 - date1) / (1000 * 60 * 60 * 24) + 1; + + weekEnds = 0; + for(i = 0; i < delta; i++) + { + if((weekend == 2 && date1.getDay() == 6) || date1.getDay() == 0) weekEnds ++; + date1 = date1.valueOf(); + date1 += 1000 * 60 * 60 * 24; + date1 = new Date(date1); + } + return delta - weekEnds; +} + +/** + * Compute work days. + * + * @access public + * @return void + */ +function computeWorkDays(currentID) +{ + isBactchEdit = false; + if(currentID) + { + index = currentID.replace('begins[', ''); + index = index.replace('ends[', ''); + index = index.replace(']', ''); + if(!isNaN(index)) isBactchEdit = true; + } + + if(isBactchEdit) + { + beginDate = $('#begins\\[' + index + '\\]').val(); + endDate = $('#ends\\[' + index + '\\]').val(); + } + else + { + beginDate = $('#begin').val(); + endDate = $('#end').val(); + } + + if(beginDate && endDate) + { + if(isBactchEdit) $('#dayses\\[' + index + '\\]').val(computeDaysDelta(beginDate, endDate)); + if(!isBactchEdit) $('#days').val(computeDaysDelta(beginDate, endDate)); + } + else if($('input[checked="true"]').val()) + { + computeEndDate(); + } +} + +/** + * Compute the end date for project. + * + * @param int $delta + * @access public + * @return void + */ +function computeEndDate(delta) +{ + beginDate = $('#begin').val(); + if(!beginDate) return; + + delta = parseInt(delta); + beginDate = convertStringToDate(beginDate); + if((delta == 7 || delta == 14) && (beginDate.getDay() == 1)) + { + delta = (weekend == 2) ? (delta - 2) : (delta - 1); + } + + endDate = beginDate.addDays(delta - 1).toString('yyyy-MM-dd'); + $('#end').val(endDate).datetimepicker('update'); + computeWorkDays(); +} diff --git a/module/program/js/create.js b/module/program/js/create.js new file mode 100644 index 0000000000..e79af3d3b6 --- /dev/null +++ b/module/program/js/create.js @@ -0,0 +1,9 @@ +$(function() +{ + $('#copyProjects a').click(function(){setCopyProject($(this).data('id')); $('#copyProjectModal').modal('hide')}); +}); + +function setCopyProject(programID) +{ + location.href = createLink('program', 'create', 'type=' + type + '©ProgramID=' + programID); +} diff --git a/module/program/lang/zh-cn.php b/module/program/lang/zh-cn.php index 0057a534cf..f703bbb352 100644 --- a/module/program/lang/zh-cn.php +++ b/module/program/lang/zh-cn.php @@ -3,7 +3,8 @@ $lang->program->index = '项目主页'; $lang->program->common = '项目'; $lang->program->stage = '阶段'; $lang->program->name = '项目名称'; -$lang->program->type = '项目类型'; +$lang->program->type = '管理方式'; +$lang->program->category = '项目类型'; $lang->program->desc = '项目描述'; $lang->program->code = '项目代号'; $lang->program->begin = '计划开始日期'; @@ -33,3 +34,6 @@ $lang->program->unitList['dollar'] = 'Dollars'; $lang->program->typeList['scrum'] = "Scrum"; $lang->program->typeList['cmmi'] = "瀑布"; + +$lang->program->categoryList['single'] = "单产品项目"; +$lang->program->categoryList['multiple'] = "多产品项目"; diff --git a/module/program/model.php b/module/program/model.php index 87d0c5bd06..3195ff721c 100644 --- a/module/program/model.php +++ b/module/program/model.php @@ -1,12 +1,35 @@ dao->select('*')->from(TABLE_PROJECT) + ->where('iscat')->eq(0) + ->andWhere('program')->eq(0) + ->andWhere('deleted')->eq(0) + ->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->projects)->fi() + ->beginIF($status != 'all')->andWhere('status')->eq($status)->fi() + ->orderBy($orderBy) + ->page($pager) + ->fetchAll('id'); + } + + public function getPairsByType($type) + { + return $this->dao->select('id, name')->from(TABLE_PROJECT) + ->where('iscat')->eq(0) + ->andWhere('type')->eq($type) + ->andWhere('program')->eq(0) + ->andWhere('deleted')->eq(0) + ->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->projects)->fi() + ->fetchPairs(); + } + public function create() { $this->lang->project->team = $this->lang->project->teamname; $project = fixer::input('post') ->setDefault('status', 'wait') - ->setDefault('type', 'program') ->setIF($this->post->acl != 'custom', 'whitelist', '') ->setDefault('openedBy', $this->app->user->account) ->setDefault('openedDate', helper::now()) @@ -28,13 +51,14 @@ class programModel extends model /* Add the creater to the team. */ if(!dao::isError()) { - $projectID = $this->dao->lastInsertId(); - $today = helper::today(); + $programID = $this->dao->lastInsertId(); + $today = helper::today(); /* Save order. */ - $this->dao->update(TABLE_PROJECT)->set('`order`')->eq($projectID * 5)->where('id')->eq($projectID)->exec(); - $this->file->updateObjectID($this->post->uid, $projectID, 'project'); + $this->dao->update(TABLE_PROJECT)->set('`order`')->eq($programID * 5)->where('id')->eq($programID)->exec(); + $this->file->updateObjectID($this->post->uid, $programID, 'project'); + /* $product = new stdclass(); $product->name = $project->name; $product->project = $projectID; @@ -46,8 +70,9 @@ class programModel extends model $productID = $this->dao->lastInsertId(); $this->dao->update(TABLE_PRODUCT)->set('`order`')->eq($productID * 5)->where('id')->eq($productID)->exec(); + */ - /* Create doc lib. */ + /* Create doc lib. $this->app->loadLang('doc'); $lib = new stdclass(); $lib->product = $productID; @@ -60,13 +85,13 @@ class programModel extends model $docLibID = $this->dao->lastInsertId(); $this->loadModel('doc')->syncDocModule($docLibID); - /* Insert into projectproduct. */ - //$data = new stdclass(); - //$data->project = $projectID; - //$data->product = $productID; - //$this->dao->insert(TABLE_PROJECTPRODUCT)->data($data)->exec(); + $data = new stdclass(); + $data->project = $projectID; + $data->product = $productID; + $this->dao->insert(TABLE_PROJECTPRODUCT)->data($data)->exec(); + */ - return $projectID; + return $programID; } } diff --git a/module/program/view/create.html.php b/module/program/view/create.html.php index 60e6c00369..3848b2c293 100644 --- a/module/program/view/create.html.php +++ b/module/program/view/create.html.php @@ -38,21 +38,28 @@

program->create;?>

+
+ +
- + - + - + + + + + @@ -67,20 +74,32 @@ + + + + + + - + + @@ -94,11 +113,11 @@ - + - + - - + - + + + + + @@ -92,13 +93,14 @@ - + + - + + +
program->type;?>program->typeList, '', "class='form-control'");?>program->typeList, $type, '');?>
program->name;?>
program->code;?>
program->category;?>program->categoryList, '', "class='form-control'");?>
program->PM;?>program->dateRange;?>
- program->begin . "' required");?> + program->begin . "' required");?> program->to;?> - program->end . "' required");?> + program->end . "' required");?>
project->days;?> +
+ + project->day;?> +
+
project->teamname;?>
project->status;?>
project->acl;?>project->aclList, 'open', "onclick='setWhite(this.value);'", 'block'));?>project->aclList, $acl, "onclick='setWhite(this.value);'", 'block'));?>
@@ -111,4 +130,33 @@ + + diff --git a/module/program/view/index.html.php b/module/program/view/index.html.php index 6b8ba6fbc9..ca83d4c11a 100644 --- a/module/program/view/index.html.php +++ b/module/program/view/index.html.php @@ -78,12 +78,13 @@ recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?>
- idAB);?> - program->name);?>idAB);?> program->code);?>program->budget);?>program->name);?>program->type);?>program->begin);?>program->end);?>program->budget);?> program->PM);?> program->desc;?> actions;?>
- id);?> - id);?>code;?> createLink('project', 'task', 'projectID=' . $project->id), $project->name);?> code;?>program->typeList, $project->type, '');?>begin;?>end;?> budget . ' ' . zget($lang->program->unitList, $project->budgetUnit);?> PM);?> desc);?>