diff --git a/config/zentaopms.php b/config/zentaopms.php index 7043664e3c..064f99a08f 100644 --- a/config/zentaopms.php +++ b/config/zentaopms.php @@ -193,11 +193,16 @@ define('TABLE_RELATION', '`' . $config->db->prefix . 'relation`'); define('TABLE_REPOHISTORY', '`' . $config->db->prefix . 'repohistory`'); define('TABLE_REPOFILES', '`' . $config->db->prefix . 'repofiles`'); define('TABLE_REPOBRANCH', '`' . $config->db->prefix . 'repobranch`'); -if(!defined('TABLE_LANG')) define('TABLE_LANG', '`' . $config->db->prefix . 'lang`'); -if(!defined('TABLE_STAGE')) define('TABLE_STAGE', '`' . $config->db->prefix . 'stage`'); -if(!defined('TABLE_DESIGN')) define('TABLE_DESIGN', '`' . $config->db->prefix . 'design`'); -if(!defined('TABLE_DESIGNSPEC')) define('TABLE_DESIGNSPEC', '`' . $config->db->prefix . 'designspec`'); -if(!defined('TABLE_RISK')) define('TABLE_RISK', '`' . $config->db->prefix . 'risk`'); +if(!defined('TABLE_LANG')) define('TABLE_LANG', '`' . $config->db->prefix . 'lang`'); +if(!defined('TABLE_STAGE')) define('TABLE_STAGE', '`' . $config->db->prefix . 'stage`'); +if(!defined('TABLE_DESIGN')) define('TABLE_DESIGN', '`' . $config->db->prefix . 'design`'); +if(!defined('TABLE_DESIGNSPEC')) define('TABLE_DESIGNSPEC', '`' . $config->db->prefix . 'designspec`'); +if(!defined('TABLE_ISSUE')) define('TABLE_ISSUE', '`' . $config->db->prefix . 'issue`'); +if(!defined('TABLE_RISK')) define('TABLE_RISK', '`' . $config->db->prefix . 'risk`'); +if(!defined('TABLE_PROJECTSPEC')) define('TABLE_PROJECTSPEC', '`' . $config->db->prefix . 'projectspec`'); +if(!defined('TABLE_WORKESTIMATION')) define('TABLE_WORKESTIMATION', '`' . $config->db->prefix . 'workestimation`'); +if(!defined('TABLE_DURATIONESTIMATION')) define('TABLE_DURATIONESTIMATION', '`' . $config->db->prefix . 'durationestimation`'); +if(!defined('TABLE_BUDGET')) define('TABLE_BUDGET', '`' . $config->db->prefix . 'budget`'); $config->objectTables['product'] = TABLE_PRODUCT; $config->objectTables['story'] = TABLE_STORY; diff --git a/db/update20.0.sql b/db/update20.0.sql index a7432df7b2..e115a922b3 100644 --- a/db/update20.0.sql +++ b/db/update20.0.sql @@ -95,6 +95,34 @@ CREATE TABLE `zt_designspec` ( UNIQUE KEY `design` (`design`,`version`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; +-- DROP TABLE IF EXISTS `zt_issue`; +CREATE TABLE `zt_issue` ( + `id` mediumint(8) UNSIGNED NOT NULL AUTO_INCREMENT, + `program` varchar(255) NOT NULL, + `product` varchar(255) NOT NULL, + `commit` varchar(30) NOT NULL, + `project` mediumint(9) NOT NULL DEFAULT '0', + `name` varchar(255) NOT NULL, + `parent` mediumint(8) unsigned NOT NULL, + `status` varchar(30) NOT NULL, + `subStatus` varchar(30) NOT NULL, + `createdBy` varchar(30) NOT NULL, + `createdDate` datetime NOT NULL, + `editedBy` varchar(30) NOT NULL, + `editedDate` datetime NOT NULL, + `commitBy` varchar(30) NOT NULL, + `commitDate` datetime NOT NULL, + `assignedTo` varchar(30) NOT NULL, + `assignedBy` varchar(30) NOT NULL, + `assignedDate` datetime NOT NULL, + `deleted` enum('0','1') NOT NULL DEFAULT '0', + `story` char(30) NOT NULL, + `desc` text NOT NULL, + `version` smallint(6) NOT NULL, + `type` char(30) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + CREATE TABLE `zt_risk` ( `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, `program` varchar(255) NOT NULL, @@ -115,22 +143,86 @@ CREATE TABLE `zt_risk` ( `addedDate` date NOT NULL, `resolution` text NOT NULL, `resolvedBy` varchar(30) NOT NULL, + `activateBy` varchar(30) NOT NULL, + `activateDate` date NOT NULL, + `closeBy` varchar(30) NOT NULL, + `closedDate` date NOT NULL, + `assignedTo` varchar(30) NOT NULL, + `assignedBy` varchar(30) NOT NULL, + `cancelBy` varchar(30) NOT NULL, + `cancelDate` datetime NOT NULL, + `cancelReason` char(30) NOT NULL, + `hangupBy` varchar(30) NOT NULL, + `hangupdDate` datetime NOT NULL, + `trackedBy` varchar(30) NOT NULL, + `trackedDate` datetime NOT NULL, + `assignedDate` datetime NOT NULL, + `deleted` enum('0','1') NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- DROP TABLE IF EXISTS `zt_projectspec`; +CREATE TABLE `zt_projectspec` ( + `project` mediumint(8) NOT NULL, + `version` smallint(6) NOT NULL, + `name` varchar(255) NOT NULL, + `milestone` enum('0','1') NOT NULL DEFAULT '0', + `begin` date NOT NULL, + `end` date NOT NULL, + UNIQUE KEY `project` (`project`,`version`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- DROP TABLE IF EXISTS `zt_budget`; +CREATE TABLE `zt_budget` ( + `id` int(8) NOT NULL AUTO_INCREMENT, + `program` mediumint(8) NOT NULL, + `stage` char(30) NOT NULL, + `subject` mediumint(8) NOT NULL, + `amount` char(30) NOT NULL, + `name` varchar(255) NOT NULL, + `desc` text NOT NULL, + `createdBy` char(30) NOT NULL, + `createdDate` date NOT NULL, + `lastEditedBy` char(30) NOT NULL, + `lastEditedDate` date NOT NULL, + `deleted` enum('0','1') NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- DROP TABLE IF EXISTS `zt_durationestimation`; +CREATE TABLE `zt_durationestimation` ( + `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, + `program` mediumint(8) unsigned NOT NULL, + `stage` mediumint(9) NOT NULL, + `workload` varchar(255) NOT NULL, + `worktimeRate` varchar(255) NOT NULL, + `people` varchar(255) NOT NULL, + `startDate` date NOT NULL, + `endDate` date NOT NULL, `createdBy` varchar(30) NOT NULL, `createdDate` datetime NOT NULL, `editedBy` varchar(30) NOT NULL, `editedDate` datetime NOT NULL, - `cancelBy` varchar(30) NOT NULL, - `cancelDate` datetime NOT NULL, - `cancelReason` char(30) NOT NULL, - `assignedTo` varchar(30) NOT NULL, - `assignedDate` datetime NOT NULL, - `hangupBy` varchar(30) NOT NULL, - `hangupdDate` datetime NOT NULL, - `activateBy` varchar(30) NOT NULL, - `activateDate` datetime NOT NULL, - `isChange` enum('0','1') NOT NULL DEFAULT '0', - `trackedBy` varchar(30) NOT NULL, - `trackedDate` datetime NOT NULL, `deleted` enum('0','1') NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- DROP TABLE IF EXISTS `zt_workestimation`; +CREATE TABLE `zt_workestimation` ( + `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, + `program` mediumint(8) unsigned NOT NULL, + `scale` mediumint(8) unsigned NOT NULL, + `productivity` smallint(3) unsigned NOT NULL, + `duration` mediumint(8) unsigned NOT NULL, + `unitLaborCost` mediumint(8) unsigned NOT NULL, + `totalLaborCost` mediumint(8) unsigned NOT NULL, + `createdBy` varchar(30) NOT NULL, + `createdDate` datetime NOT NULL, + `editedBy` varchar(30) NOT NULL, + `editedDate` datetime NOT NULL, + `assignedTo` varchar(30) NOT NULL, + `assignedDate` datetime NOT NULL, + `deleted` enum('0','1') NOT NULL DEFAULT '0', + `dayHour` float(5,2) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/module/budget/config.php b/module/budget/config.php new file mode 100644 index 0000000000..0364a0fd80 --- /dev/null +++ b/module/budget/config.php @@ -0,0 +1,9 @@ +budget = new stdclass(); +$config->budget->editor = new stdclass(); +$config->budget->create = new stdclass(); + +$config->budget->editor->create = array('id' => 'desc', 'tools' => 'simpleTools'); +$config->budget->editor->edit = array('id' => 'desc', 'tools' => 'simpleTools'); + +$config->budget->create->requiredFields = 'stage,subject,name'; diff --git a/module/budget/control.php b/module/budget/control.php new file mode 100644 index 0000000000..7092ff65eb --- /dev/null +++ b/module/budget/control.php @@ -0,0 +1,166 @@ +view->program = $this->loadModel('project')->getByID($this->session->program); + } + + public function browse($orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) + { + $this->app->loadClass('pager', $static = true); + $pager = pager::init($recTotal, $recPerPage, $pageID); + + $this->view->title = $this->lang->budget->common . $this->lang->budget->list; + $this->view->position[] = $this->lang->budget->common . $this->lang->budget->list; + $this->view->budgets = $this->budget->getList($orderBy, $pager); + $this->view->orderBy = $orderBy; + $this->view->pager = $pager; + $this->view->modules = $this->loadModel('tree')->getOptionMenu(0, $viewType = 'subject', $startModuleID = 0); + $this->view->stages = $this->loadModel('programplan')->getPlanPairsForBudget($this->session->program); + $this->view->users = $this->loadModel('user')->getPairs('noclosed|noletter'); + $this->display(); + } + + public function summary() + { + $getSubjectStructure = $this->budget->getSubjectStructure(); + $isChildren = false; + if(is_array($getSubjectStructure)) + { + foreach($getSubjectStructure as $subjects) + { + if(isset($subjects['hasChild'])) + { + $isChildren = true; + break; + } + } + } + + $this->view->title = $this->lang->budget->common . $this->lang->budget->summary; + $this->view->position[] = $this->lang->budget->common . $this->lang->budget->summary; + $this->view->subjectStructure = $getSubjectStructure; + $this->view->isChildren = $isChildren; + $this->view->subjects = $this->budget->getSubjects(); + $this->view->stages = $this->budget->getStages(); + $this->view->stagePairs = $this->loadModel('programplan')->getPlanPairsForBudget($this->session->program); + $this->view->summary = $this->budget->getSummary(); + $this->view->modules = $this->loadModel('tree')->getOptionMenu(0, $viewType = 'subject', $startModuleID = 0); + $this->display(); + } + + public function create() + { + if($_POST) + { + $budgetID = $this->budget->create(); + + if(dao::isError()) + { + $response['result'] = 'fail'; + $response['message'] = dao::getError(); + $this->send($response); + } + + $this->loadModel('action')->create('budget', $budgetID, 'created'); + + $response['result'] = 'success'; + $response['message'] = $this->lang->saveSuccess; + $response['locate'] = inlink('browse'); + $this->send($response); + } + + $this->view->title = $this->lang->budget->create . $this->lang->budget->common; + $this->view->position[] = $this->lang->budget->create . $this->lang->budget->common; + $this->view->subjects = array(0 => '') + $this->budget->getSubjectOption(); + $this->view->stages = $this->loadModel('programplan')->getPlanPairsForBudget($this->session->program); + $this->display(); + } + + public function edit($budgetID) + { + if($_POST) + { + $changes = $this->budget->update($budgetID); + + if(dao::isError()) + { + $response['result'] = 'fail'; + $response['message'] = dao::getError(); + $this->send($response); + } + + if($changes) + { + $actionID = $this->loadModel('action')->create('budget', $budgetID, 'edited'); + $this->action->logHistory($actionID, $changes); + } + + $response['result'] = 'success'; + $response['message'] = $this->lang->saveSuccess; + $response['locate'] = inlink('browse'); + $this->send($response); + } + + $this->view->title = $this->lang->budget->edit . $this->lang->budget->common; + $this->view->position[] = $this->lang->budget->edit . $this->lang->budget->common; + $this->view->subjects = array('' => '') + $this->budget->getSubjectOption(); + $this->view->stages = $this->loadModel('programplan')->getPlanPairsForBudget($this->session->program); + $this->view->budget = $this->budget->getByID($budgetID); + $this->display(); + } + + public function view($budgetID) + { + $this->view->stages = $this->budget->getStages(); + $this->view->subjects = $this->budget->getSubjectOption(); + $this->view->stages = $this->loadModel('programplan')->getPlanPairsForBudget($this->session->program); + $this->view->budget = $this->budget->getByID($budgetID); + $this->view->actions = $this->loadModel('action')->getList('budget', $budgetID); + $this->view->users = $this->loadModel('user')->getPairs('noclosed|noletter'); + $this->display(); + } + + public function delete($budgetID = 0, $confirm = 'no') + { + if($confirm == 'no') + { + echo js::confirm($this->lang->budget->confirmDelete, $this->createLink('budget', 'delete', "id=$budgetID&confirm=yes")); + exit; + } + else + { + $this->budget->delete(TABLE_BUDGET, $budgetID); + die(js::locate(inlink('browse'), 'parent')); + } + + } + + public function batchCreate() + { + if($_POST) + { + $this->budget->batchCreate(); + + if(dao::isError()) + { + $response['result'] = 'fail'; + $response['message'] = dao::getError(); + $this->send($response); + } + + $response['result'] = 'success'; + $response['message'] = $this->lang->saveSuccess; + $response['locate'] = inlink('browse'); + $this->send($response); + } + + $this->view->title = $this->lang->budget->batchCreate . $this->lang->budget->common; + $this->view->position[] = $this->lang->budget->batchCreate . $this->lang->budget->common; + $this->view->subjects = array('' => '') + $this->budget->getSubjectOption(); + $this->view->stages = $this->loadModel('programplan')->getPlanPairsForBudget($this->session->program); + $this->display(); + } +} diff --git a/module/budget/css/common.css b/module/budget/css/common.css new file mode 100644 index 0000000000..b42452795d --- /dev/null +++ b/module/budget/css/common.css @@ -0,0 +1 @@ +#pageNav{display: none} diff --git a/module/budget/lang/zh-cn.php b/module/budget/lang/zh-cn.php new file mode 100644 index 0000000000..a40a73b968 --- /dev/null +++ b/module/budget/lang/zh-cn.php @@ -0,0 +1,28 @@ +budget->create = '新建'; +$lang->budget->edit = '编辑'; +$lang->budget->total = '总预算'; +$lang->budget->summary = '汇总'; +$lang->budget->browse = '列表'; +$lang->budget->list = '列表'; +$lang->budget->view = '详情'; +$lang->budget->delete = '删除'; +$lang->budget->batchCreate = '批量新建'; +$lang->budget->common = '费用估算'; +$lang->budget->id = '编号'; +$lang->budget->stage = '阶段'; +$lang->budget->subject = '科目'; +$lang->budget->name = '费用名称'; +$lang->budget->amount = '预计金额'; +$lang->budget->desc = '说明'; +$lang->budget->yuan = '元'; +$lang->budget->dollar = 'Dollars'; +$lang->budget->createdBy = '由谁创建'; +$lang->budget->createdDate = '创建时间'; +$lang->budget->lastEditedBy = '由谁编辑'; +$lang->budget->lastEditedDate = '编辑时间'; +$lang->budget->basicInfo = '基本信息'; +$lang->budget->noData = '暂无记录,'; + +$lang->budget->summaryReport = '汇总表'; +$lang->budget->confirmDelete = '您确定要删除吗?'; diff --git a/module/budget/model.php b/module/budget/model.php new file mode 100644 index 0000000000..3b8be575eb --- /dev/null +++ b/module/budget/model.php @@ -0,0 +1,182 @@ +loadModel('tree')->getOptionMenu(0, $viewType = 'subject', $startModuleID = 0); + $subjectList = $this->dao->select('*')->from(TABLE_MODULE)->where('id')->in(array_keys($subjects))->fetchAll(); + + foreach($subjectList as $subject) + { + if(isset($subjects[$subject->parent])) unset($subjects[$subject->parent]); + if($subject->grade > 2) unset($subjects[$subject->id]); + } + + return $subjects; + } + + public function getByID($budgetID) + { + $budget = $this->dao->select('*')->from(TABLE_BUDGET)->where('id')->eq($budgetID)->fetch(); + $budget = $this->loadModel('file')->replaceImgURL($budget, 'desc'); + + return $budget; + } + + public function getList($orderBy = 'id_desc', $pager = null) + { + return $this->dao->select('*')->from(TABLE_BUDGET) + ->where('program')->eq($this->session->program) + ->andWhere('deleted')->eq(0) + ->orderBy($orderBy) + ->page($pager) + ->fetchAll(); + } + + public function getStages() + { + return $this->dao->select('stage')->from(TABLE_BUDGET) + ->where('program')->eq($this->session->program) + ->andWhere('deleted')->eq(0) + ->orderBy('stage_asc') + ->fetchPairs(); + } + + public function getSubjects() + { + return $this->dao->select('subject')->from(TABLE_BUDGET) + ->where('program')->eq($this->session->program) + ->andWhere('deleted')->eq(0) + ->orderBy('subject_asc') + ->fetchPairs(); + } + + public function getSubjectStructure() + { + $subjects = $this->getSubjects(); + + $structure = array(); + foreach($subjects as $subjectID) + { + $subject = $this->loadModel('tree')->getById($subjectID); + if($subject->grade == 1) + { + $structure[$subject->id][] = $subject->id; + continue; + } + + $structure[$subject->parent][] = $subject->id; + $structure[$subject->parent]['hasChild'] = true; + } + + return $structure; + } + + public function getSummary() + { + $budgets = $this->dao->select('*')->from(TABLE_BUDGET) + ->where('program')->eq($this->session->program) + ->andWhere('deleted')->eq(0) + ->fetchAll(); + + $summary = array(); + foreach($budgets as $budget) + { + $summary[$budget->subject] = isset($summary[$budget->subject]) ? $summary[$budget->subject] : array(); + $summary[$budget->subject][$budget->stage] = isset($summary[$budget->subject][$budget->stage]) ? $summary[$budget->subject][$budget->stage] : 0; + $summary[$budget->subject][$budget->stage] += $budget->amount; + } + + $total = 0; + foreach($summary as $subject => $stageSummary) + { + $summary[$subject]['summary'] = 0; + foreach($stageSummary as $amount) + { + $summary[$subject]['summary'] += $amount; + $total += $amount; + } + } + + $summary['total'] = $total; + return $summary; + } + + public function create() + { + $budget = fixer::input('post') + ->setDefault('createdBy', $this->app->user->account) + ->setDefault('createdDate', helper::today()) + ->setDefault('program', $this->session->program) + ->cleanFloat('amount') + ->remove('uid') + ->get(); + + $this->dao->insert(TABLE_BUDGET)->data($budget) + ->autoCheck() + ->batchCheck($this->config->budget->create->requiredFields, 'notempty') + ->exec(); + + $budgetID = $this->dao->lastInsertID(); + return $budgetID; + } + + public function batchCreate() + { + $today = helper::today(); + $budgets = fixer::input('post')->get(); + + foreach($budgets->name as $i => $name) + { + if(!$name) continue; + $data = new stdclass(); + $data->name = $name; + $data->program = $this->session->program; + $data->stage = $budgets->stage[$i]; + $data->subject = $budgets->subject[$i]; + $data->amount = (float)$budgets->amount[$i]; + $data->desc = nl2br($budgets->desc[$i]); + $data->createdBy = $this->app->user->account; + $data->createdDate = $today; + + foreach(explode(',', $this->config->budget->create->requiredFields) as $field) + { + $field = trim($field); + if($field and empty($data->$field)) + { + dao::$errors['message'][] = sprintf($this->lang->error->notempty, $this->lang->budget->$field); + return false; + } + } + + + $this->dao->insert(TABLE_BUDGET)->data($data) + ->autoCheck() + ->exec(); + + $budgetID = $this->dao->lastInsertID(); + $this->loadModel('action')->create('budget', $budgetID, 'Opened'); + } + + return !dao::isError(); + } + + public function update($budgetID) + { + $oldBudget = $this->getByID($budgetID); + $budget = fixer::input('post') + ->setDefault('lastEditedBy', $this->app->user->account) + ->setDefault('lastEditedDate', helper::today()) + ->cleanFloat('amount') + ->remove('uid') + ->get(); + + $this->dao->update(TABLE_BUDGET)->data($budget) + ->where('id')->eq($budgetID) + ->autoCheck() + ->batchCheck($this->config->budget->create->requiredFields, 'notempty') + ->exec(); + + if(!dao::isError()) return common::createChanges($oldBudget, $budget); + } +} diff --git a/module/budget/view/batchcreate.html.php b/module/budget/view/batchcreate.html.php new file mode 100644 index 0000000000..5b490df9ce --- /dev/null +++ b/module/budget/view/batchcreate.html.php @@ -0,0 +1,44 @@ + + +
+
+
+

budget->batchCreate;?>

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
idAB;?>budget->stage;?> budget->subject;?> budget->name;?> budget->amount;?> budget->desc;?>
+
+ + budget->{$program->budgetUnit};?> +
+
+
+
+
+ diff --git a/module/budget/view/browse.html.php b/module/budget/view/browse.html.php new file mode 100644 index 0000000000..689a79e0b4 --- /dev/null +++ b/module/budget/view/browse.html.php @@ -0,0 +1,65 @@ + + + +
+
+ +
+

+ budget->noData;?> + + createLink('budget', 'create', ''), " " . $lang->budget->create, '', "class='btn btn-info'");?> + +

+
+ +
+ + recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> + + + + + + + + + + + + + + + + + + + + + + + + + + +
budget->id);?>budget->name);?>budget->stage);?>budget->subject);?>budget->amount);?>budget->createdBy);?>budget->createdDate);?>actions;?>
id);?>createLink('budget', 'view', "id=$budget->id"), $budget->name);?>stage);?>subject);?>amount;?>createdBy);?>createdDate;?> + id", $budget, 'list');?> + id", $budget, 'list', '', 'hiddenwin');?> +
+ +
+ +
+
+ diff --git a/module/budget/view/create.html.php b/module/budget/view/create.html.php new file mode 100644 index 0000000000..b005081791 --- /dev/null +++ b/module/budget/view/create.html.php @@ -0,0 +1,46 @@ + + +
+
+
+

budget->create . $lang->budget->common;?>

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
budget->stage;?>
budget->subject;?>
budget->amount;?> +
+ + budget->{$program->budgetUnit};?> +
+
budget->name;?>
budget->desc;?>
+
+
+
+ diff --git a/module/budget/view/edit.html.php b/module/budget/view/edit.html.php new file mode 100644 index 0000000000..fad79e0138 --- /dev/null +++ b/module/budget/view/edit.html.php @@ -0,0 +1,46 @@ + + +
+
+
+

budget->edit . $lang->budget->common;?>

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
budget->stage;?> stage, 'class="form-control chosen"');?>
budget->subject;?> subject, 'class="form-control chosen"');?>
budget->amount;?> +
+ amount, 'class="form-control"');?> + budget->{$program->budgetUnit};?> +
+
budget->name;?> name, 'class="form-control"');?>
budget->desc;?> desc, 'class="form-control"');?>
+
+
+ diff --git a/module/budget/view/summary.html.php b/module/budget/view/summary.html.php new file mode 100644 index 0000000000..6487dad899 --- /dev/null +++ b/module/budget/view/summary.html.php @@ -0,0 +1,90 @@ + + + +
+
+ + + + + + $structure):?> + + + + + + + + $structure):?> + "; + } + else + { + echo ""; + } + } + ?> + + + + + + + + + + + + + + + + + + + +
budget->subject . '/' . $lang->budget->stage?>budget->summary; ?>
" . zget($modules, $subject) . "
+ + + + + +
budget->summary;?> + + + + + +
+
budget->total . ':' . $summary['total'] . $lang->budget->{$program->budgetUnit};?>
+ +
+

+ noData;?> +

+
+ +
+
+ diff --git a/module/budget/view/view.html.php b/module/budget/view/view.html.php new file mode 100644 index 0000000000..304fd2c851 --- /dev/null +++ b/module/budget/view/view.html.php @@ -0,0 +1,77 @@ + + * @package bug + * @version $Id: view.html.php 4728 2013-05-03 06:14:34Z chencongzhi520@gmail.com $ + * @link http://www.zentao.net + */ +?> + + + +
+
+
+
+
budget->desc;?>
+
+ desc; ?> +
+
+
+
+
+
+
+
+
budget->basicInfo;?>
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
budget->stage;?>stage);?>
budget->subject;?>subject);?>
budget->amount;?>amount;?>
budget->createdBy;?>createdBy);?>
budget->createdDate;?>createdDate;?>
budget->lastEditedBy;?>lastEditedBy);?>
budget->lastEditedDate;?>lastEditedDate;?>
+
+
+
+
+ diff --git a/module/common/lang/zh-cn.php b/module/common/lang/zh-cn.php index c89fae431e..2beb0bfa9a 100755 --- a/module/common/lang/zh-cn.php +++ b/module/common/lang/zh-cn.php @@ -1121,7 +1121,7 @@ $lang->cmmi = new stdclass(); $lang->cmmi->subMenu = new stdclass(); $lang->cmmi->subMenu->list = new stdclass(); $lang->cmmi->subMenu->list->workestimation = array('link' => '估算|workestimation|index|program=%s', 'subModule' => 'durationestimation,budget'); -$lang->cmmi->subMenu->list->program = '项目|||'; +$lang->cmmi->subMenu->list->program = '项目|program|edit|'; $lang->cmmiproduct = new stdclass(); $lang->workestimation = new stdclass(); diff --git a/module/durationestimation/config.php b/module/durationestimation/config.php new file mode 100644 index 0000000000..75689ab17f --- /dev/null +++ b/module/durationestimation/config.php @@ -0,0 +1,4 @@ +durationestimation = new stdclass; +$config->durationestimation->index = new stdclass; +$config->durationestimation->index->requiredFields = 'scale,productivity,scale,duration,unitLaborCost,totalLaborCost'; diff --git a/module/durationestimation/control.php b/module/durationestimation/control.php new file mode 100644 index 0000000000..9f2b55a3a4 --- /dev/null +++ b/module/durationestimation/control.php @@ -0,0 +1,117 @@ + + * @package durationestimation + * @version $Id$ + * @link http://www.chanzhi.org + */ +class durationestimation extends control +{ + public function index($programID) + { + $workestimation = $this->loadModel('workestimation')->getBudget($programID); + if(!$workestimation) + { + echo js::alert($this->lang->durationestimation->setWorkestimation); + die(js::locate($this->createLink('workestimation', 'index', "currentProgram=$programID"))); + } + + $this->loadModel('programplan'); + $program = $this->loadModel('project')->getById($programID); + $stages = $this->loadModel('stage')->getStages(); + $title = $this->lang->durationestimation->common . $this->lang->colon . $program->name; + + $this->view->estimationList = $this->durationestimation->getListByProgram($programID); + if(empty($this->view->estimationList)) $this->locate(inlink('create', "currentProgram=$programID")); + $this->view->workestimation = $workestimation; + + $this->view->title = $title; + $this->view->program = $program; + $this->view->stages = $stages; + + $this->display(); + } + + public function create($programID = 0) + { + $workestimation = $this->loadModel('workestimation')->getBudget($programID); + if(!$workestimation) + { + echo js::alert($this->lang->durationestimation->setWorkestimation); + die(js::locate($this->createLink('workestimation', 'index', "currentProgram=$programID"))); + } + + $this->loadModel('programplan'); + if(!empty($_POST)) + { + $total = 0; + foreach($this->post->workload as $value) $total += $value; + if($total != 100) $this->send(array('result' => 'fail', 'message' => $this->lang->durationestimation->workloadError)); + $this->durationestimation->save($programID); + if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError())); + $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('index', "currentProgram={$programID}"))); + } + + $this->view->estimationList = $this->durationestimation->getListByProgram($programID); + $this->view->workestimation = $workestimation; + + $program = $this->loadModel('project')->getById($programID); + $title = $this->lang->durationestimation->common . $this->lang->colon . $program->name; + + $this->view->title = $title; + $this->view->program = $program; + $this->view->stages = $this->loadModel('stage')->getStages(); + + $this->display(); + } + + /** + * ajaxGetDuration + * + * @param int $program + * @param int $workload + * @param int $worktimeRate + * @param int $people + * @access public + * @return void + */ + public function ajaxGetDuration($program, $stage, $workload, $worktimeRate, $people, $startDate) + { + $startDate = str_replace('_', '-', $startDate); + if($startDate == '0000-00-00') $this->send(array('result' => 'success', 'endDate' => '0000-00-00')); + + $estimation = $this->loadModel('workestimation')->getBudget($program); + $duration = $estimation->duration * $workload / 100; + $divisor = ($people == 0 || $estimation->dayHour == 0) ? 0 : $worktimeRate / 100 * $people / $estimation->dayHour; + $duration = !$divisor ? 0 : $duration / $divisor; + if(!$divisor) $this->send(array('result' => 'fail')); + + $holidays = array(); + $workDays = array(); + $i = 0; + $this->loadModel('project'); + + $startedTime = strtotime($startDate); + $days = 0; + for($i = 0; $days < $duration; $i ++) + { + $day = date('N', strtotime("+ $i days", $startedTime)); + if($this->config->project->weekend == 2) + { + if($day > 5) continue; + } + if($this->config->project->weekend == 1) + { + if($day > 6) continue; + } + $lastDay = date('Y-m-d', strtotime("+ $i days", $startedTime)); + $days ++; + } + + $this->send(array('result' => 'success', 'endDate' => $lastDay)); + } +} diff --git a/module/durationestimation/js/create.js b/module/durationestimation/js/create.js new file mode 100644 index 0000000000..46374d3915 --- /dev/null +++ b/module/durationestimation/js/create.js @@ -0,0 +1,55 @@ +$().ready(function() +{ + $(':input[name*=people]').change(function() + { + var peopleNumber = 0; + $(':input[name*=people]').each(function() + { + var people = $(this).val(); + if(people) peopleNumber += parseInt(people); + }); + $('#totalStaff').html(peopleNumber); + }); + + $(':input[name*=workload]').change(function() + { + rate = parseFloat($(this).val()); + workload = estimation.scale * rate / 100; + $(this).parents('td').next().find(':input').val(workload); + totalWorkload = 0; + $(':input[name*=workload]').each(function() + { + rate = parseFloat($(this).val()); + workload = estimation.scale * rate / 100; + totalWorkload += workload; + }); + $('#totalWorkload').html(totalWorkload.toFixed(2)); + }); + + + $(':input').change(function() + { + var that = $(this); + programID = program.id; + stage = $(this).parents('tr').find('[name*=stage]').val(); + workload = $(this).parents('tr').find('[name*=workload]').val(); + worktimeRate = $(this).parents('tr').find('[name*=worktimeRate]').val(); + people = $(this).parents('tr').find('[name*=people]').val(); + startDate = $(this).parents('tr').find('[name*=startDate]').val(); + if(startDate) startDate = startDate.replace(/-/g, '_'); + + if(isNaN(workload) || isNaN(worktimeRate) || isNaN(people) || startDate == '') return false; + url = createLink('durationestimation', 'ajaxGetDuration', 'program=' + programID + '&stage=' + stage + '&workload=' + workload + '&worktimeRate=' + worktimeRate + '&people=' + people + '&startDate=' + startDate), + $.getJSON( + url, + function(response) + { + if(response.result == 'success') + { + that.parents('tr').find('[name*=endDate]').val(response.endDate); + } + } + ); + }); + $(':input').change(); +}) diff --git a/module/durationestimation/lang/zh-cn.php b/module/durationestimation/lang/zh-cn.php new file mode 100644 index 0000000000..84fda83577 --- /dev/null +++ b/module/durationestimation/lang/zh-cn.php @@ -0,0 +1,23 @@ +durationestimation->index = '工期估算首页'; +$lang->durationestimation->create = '工期估算设置'; +$lang->durationestimation->common = '项目工期估算'; +$lang->durationestimation->stage = '阶段'; +$lang->durationestimation->workloadRate = '工作量占比'; +$lang->durationestimation->workload = '工作量'; +$lang->durationestimation->worktimeRate = '全时率'; +$lang->durationestimation->people = '投入人数'; +$lang->durationestimation->startDate = '开始日期'; +$lang->durationestimation->endDate = '结束日期'; +$lang->durationestimation->setting = '设置'; + +$lang->durationestimation->setWorkestimation = "请先录入工作量估算信息"; +$lang->durationestimation->summary = "项目规模: %s {$lang->hourCommon}, 估算工作量: 0, 总投入人数: 0"; +$lang->durationestimation->workloadError = "工作量占比之和必须是100%"; + +$lang->durationestimation->placeholder = new stdclass(); +$lang->durationestimation->placeholder->scale = ''; +$lang->durationestimation->placeholder->productivity = ''; +$lang->durationestimation->placeholder->duration = ''; +$lang->durationestimation->placeholder->unitLaborCost = ''; +$lang->durationestimation->placeholder->totalLaborCost = ''; diff --git a/module/durationestimation/model.php b/module/durationestimation/model.php new file mode 100644 index 0000000000..09cd7f4f59 --- /dev/null +++ b/module/durationestimation/model.php @@ -0,0 +1,37 @@ + + * @package durationestimation + * @version $Id$ + * @link http://www.chanzhi.org + */ +class durationestimationModel extends model +{ + public function getListByProgram($program) + { + return $this->dao->select('*')->from(TABLE_DURATIONESTIMATION)->where('program')->eq($program)->fetchAll('stage'); + } + + public function save($program) + { + $this->dao->delete()->from(TABLE_DURATIONESTIMATION)->where('program')->eq($program); + foreach($this->post->stage as $i => $stage) + { + $estimation = new stdclass; + $estimation->program = $program; + $estimation->stage = $stage; + $estimation->workload = $this->post->workload[$i]; + $estimation->worktimeRate = $this->post->worktimeRate[$i]; + $estimation->people = $this->post->people[$i]; + $estimation->startDate = $this->post->startDate[$i]; + $estimation->endDate = $this->post->endDate[$i]; + $this->dao->insert(TABLE_DURATIONESTIMATION)->data($estimation)->exec(); + } + + return !dao::isError(); + } +} diff --git a/module/durationestimation/view/create.html.php b/module/durationestimation/view/create.html.php new file mode 100644 index 0000000000..0fd12e4eb0 --- /dev/null +++ b/module/durationestimation/view/create.html.php @@ -0,0 +1,66 @@ + + + +
+
+ + + + + + + + + + + + + + + + + id, array());?> + + + + + + + + + + + + + + + + + + + + + +
durationestimation->stage;?>durationestimation->workloadRate;?>durationestimation->workload;?>durationestimation->worktimeRate;?>durationestimation->people;?>durationestimation->startDate;?>durationestimation->endDate;?>
+ name;?> + id);?> + +
+ percent); ?>' class='form-control' /> + % +
+
+
+ + hourCommon;?> +
+
+
+ ' class='form-control' /> + % +
+
' class='form-control' />' class='form-control form-date' />' class='form-control form-date' />
durationestimation->summary, zget($workestimation, 'scale', ''));?>
+ +
+
+ diff --git a/module/durationestimation/view/index.html.php b/module/durationestimation/view/index.html.php new file mode 100644 index 0000000000..15e94d80fa --- /dev/null +++ b/module/durationestimation/view/index.html.php @@ -0,0 +1,48 @@ + + + +
+
+ + + + + + + + + + + + + + + id, 0);?> + + + + + + + + + + + + + + + + +
durationestimation->stage;?>durationestimation->workload;?>durationestimation->worktimeRate;?>durationestimation->people;?>durationestimation->startDate;?>durationestimation->endDate;?>
+ name;?> + id);?> + % %
+ id}"), $lang->durationestimation->setting, '', "class='btn btn-primary'");?> +
+ + + +
+
+ diff --git a/module/issue/config.php b/module/issue/config.php new file mode 100644 index 0000000000..7ed6ebfba3 --- /dev/null +++ b/module/issue/config.php @@ -0,0 +1,6 @@ +issue->create = new stdclass(); +$config->issue->create->requiredFields = 'title,type,severity'; + +$config->issue->editor = new stdclass(); +$config->issue->editor->create = array('id' => 'desc', 'tools' => 'simpleTools'); diff --git a/module/issue/control.php b/module/issue/control.php new file mode 100644 index 0000000000..d6c4231c56 --- /dev/null +++ b/module/issue/control.php @@ -0,0 +1,56 @@ + + * @package issue + * @version $Id: control.php 5145 2013-07-15 06:47:26Z chencongzhi520@gmail.com $ + * @link http://www.zentao.net + */ +class issue extends control +{ + /** + * Get issue list data. + * + * @param string $browseType + * @param string orderBy + * @param int recTotal + * @param int recPerPage + * @param int pageID + * @access public + * @return void + */ + public function browse($browseType = 'all', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) + { + $this->view->title = $this->lang->issue->common . $this->lang->colon . $this->lang->issue->browse; + $this->view->position[] = $this->lang->issue->browse; + + $this->display(); + } + + /** + * Create a issue. + * + * @access public + * @return void + */ + public function create() + { + if($_POST) + { + $result = $this->issue->create(); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inLink('browse', 'browseType=all'))); + } + + $this->view->title = $this->lang->issue->common . $this->lang->colon . $this->lang->issue->create; + $this->view->position[] = $this->lang->issue->common; + $this->view->position[] = $this->lang->issue->create; + + $this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted'); + + $this->display(); + } +} diff --git a/module/issue/lang/zh-cn.php b/module/issue/lang/zh-cn.php new file mode 100644 index 0000000000..fda597551e --- /dev/null +++ b/module/issue/lang/zh-cn.php @@ -0,0 +1,75 @@ +issue->common = '项目问题'; +$lang->issue->browse = '问题列表'; +$lang->issue->resolvedBy = '解决者'; +$lang->issue->program = '所属项目'; +$lang->issue->title = '标题'; +$lang->issue->desc = '描述'; +$lang->issue->pri = '优先级'; +$lang->issue->severity = '严重程度'; +$lang->issue->type = '类别'; +$lang->issue->effectedArea = '受影响的活动'; +$lang->issue->activity = '活动列表'; +$lang->issue->deadline = '计划解决日期'; +$lang->issue->resolution = '解决方式'; +$lang->issue->resolutionComment = '解决方案'; +$lang->issue->resolvedDate = '实际解决日期'; +$lang->issue->status = '结果'; +$lang->issue->createdBy = '由谁创建'; +$lang->issue->createdDate = '创建日期'; +$lang->issue->owner = '提出人'; +$lang->issue->editedBy = '由谁编辑'; +$lang->issue->editedDate = '编辑日期'; +$lang->issue->activateBy = '由谁激活'; +$lang->issue->activateDate = '激活日期'; +$lang->issue->closeBy = '由谁关闭'; +$lang->issue->closedDate = '关闭日期'; +$lang->issue->assignedTo = '指派给'; +$lang->issue->assignedBy = '由谁指派'; +$lang->issue->assignedDate = '指派时间'; +$lang->issue->resolved = '解决'; + +$lang->issue->create = '新建'; +$lang->issue->batchCreate = '批量新建'; + +$lang->issue->labelList['open'] = '开放'; +$lang->issue->labelList['assignTo'] = '指派给我'; +$lang->issue->labelList['closed'] = '已关闭'; +$lang->issue->labelList['suspended'] = '已挂起'; +$lang->issue->labelList['cancelled'] = '已取消'; + +$lang->issue->priList[''] = ''; +$lang->issue->priList['1'] = 1; +$lang->issue->priList['2'] = 2; +$lang->issue->priList['3'] = 3; +$lang->issue->priList['4'] = 4; + +$lang->issue->serverityList[''] = ''; +$lang->issue->serverityList['1'] = '严重'; +$lang->issue->serverityList['2'] = '较严重'; +$lang->issue->serverityList['3'] = '较小'; +$lang->issue->serverityList['4'] = '建议'; + +$lang->issue->typeList[''] = ''; +$lang->issue->typeList['design'] = '设计问题'; +$lang->issue->typeList['code'] = '程序缺陷'; +$lang->issue->typeList['performance'] = '性能问题'; +$lang->issue->typeList['version'] = '版本控制'; +$lang->issue->typeList['storyadd'] = '需求新增'; +$lang->issue->typeList['storychanged'] = '需求修改'; +$lang->issue->typeList['storyremoved'] = '需求删除'; +$lang->issue->typeList['data'] = '数据问题'; + +$lang->issue->resolutionList['resolved'] = '已解决'; +$lang->issue->resolutionList['tostory'] = '转需求'; +$lang->issue->resolutionList['tobug'] = '转BUG'; +$lang->issue->resolutionList['torisk'] = '转风险'; +$lang->issue->resolutionList['totask'] = '转任务'; + +$lang->issue->statusList['unconfirmed'] = '待确认'; +$lang->issue->statusList['confirmed'] = '已确认'; +$lang->issue->statusList['unresolved'] = '正解决'; +$lang->issue->statusList['resolved'] = '已解决'; +$lang->issue->statusList['canceled'] = '取消'; +$lang->issue->statusList['closed'] = '已关闭'; + diff --git a/module/issue/model.php b/module/issue/model.php new file mode 100644 index 0000000000..7e2e8cc72c --- /dev/null +++ b/module/issue/model.php @@ -0,0 +1,48 @@ + + * @package issue + * @version $Id: model.php 5145 2013-07-15 06:47:26Z chencongzhi520@gmail.com $ + * @link http://www.zentao.net + */ +?> +add('createdBy', $this->app->user->account) + ->add('createdDate', $now) + ->addIF($this->post->assignedTo, 'assignedBy', $this->app->user->account) + ->addIF($this->post->assignedTo, 'assignedDate', $now) + ->stripTags($this->config->issue->editor->create['id'], $this->config->allowedTags) + ->get(); + + if(strpos($this->config->issue->create->requiredFields, 'type') !== false and !$this->post->type) + { + dao::$errors[] = sprintf($this->lang->error->notempty, $this->lang->issue->type); + return false; + } + + if(strpos($this->config->issue->create->requiredFields, 'title') !== false and !$this->post->title) + { + dao::$errors[] = sprintf($this->lang->error->notempty, $this->lang->issue->title); + return false; + } + + if(strpos($this->config->issue->create->requiredFields, 'severity') !== false and !$this->post->severity) + { + dao::$errors[] = sprintf($this->lang->error->notempty, $this->lang->issue->severity); + return false; + } + + $this->dao->insert(TABLE_ISSUE)->data($data)->exec(); + return true; + } +} diff --git a/module/issue/view/browse.html.php b/module/issue/view/browse.html.php new file mode 100644 index 0000000000..20b13a2d71 --- /dev/null +++ b/module/issue/view/browse.html.php @@ -0,0 +1,24 @@ + + * @package story + * @version $Id$ + * @link http://www.zentao.net + */ +?> + +
+
+ createLink('issue', 'browse', 'browseType=all'), '' . $lang->issue->browse . '', '', 'class="btn btn-link btn-active-text"');?> +
+
+ " . $lang->issue->create, '', "class='btn btn-primary'");?> + " . $lang->issue->batchCreate, '', "class='btn btn-primary'");?> +
+
+ + diff --git a/module/issue/view/create.html.php b/module/issue/view/create.html.php new file mode 100644 index 0000000000..b812d21526 --- /dev/null +++ b/module/issue/view/create.html.php @@ -0,0 +1,71 @@ + + * @package story + * @version $Id$ + * @link http://www.zentao.net + */ +?> + + +
+
+
+

issue->create;?>

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
issue->type;?>issue->typeList, '', 'class="form-control chosen"');?>
issue->title;?>
issue->severity;?>issue->serverityList, '', 'class="form-control chosen"');?>
issue->pri;?>issue->priList, '', 'class="form-control chosen"');?>
issue->deadline;?>
issue->assignedTo;?>
issue->desc;?>
+
+
+ diff --git a/module/product/model.php b/module/product/model.php index f21371a9db..c906becbb9 100644 --- a/module/product/model.php +++ b/module/product/model.php @@ -28,72 +28,99 @@ class productModel extends model * @return void */ public function setMenu($products, $productID, $branch = 0, $module = 0, $moduleType = '', $extra = '') - { - /* Has access privilege?. */ - if($products and !isset($products[$productID]) and !$this->checkPriv($productID)) $this->accessDenied(); + { + $product = $this->getByID($productID); + if($product) + { + $project = $this->loadModel('project')->getByID($product->program); + if(isset($project->id)) $this->loadModel('project')->setMenu($products, $project->id); + + $this->lang->modulePageNav = $this->getModuleNav($products, $project, $product, $extra, $branch, $module, $moduleType); + } + + $pageActions = ''; + if($this->app->moduleName == 'release') + { + $pageActions = html::a(helper::createLink('release', 'create', "productID=$productID&branch=$branch"), " {$this->lang->release->create}", '', "class='btn btn-primary'"); + + foreach($this->lang->release->moduleMenus as $key => $menu) + { + $replace = array(); + $replace['productID'] = $productID; + $replace['branch'] = $branch; + + common::setMenuVars($this->lang->release->moduleMenus, $key, $replace); + } + $this->lang->moduleMenus['release'] = $this->lang->release->moduleMenus; + } + if($this->app->moduleName == 'programplan' and isset($product->program)) + { + $pageActions .= html::a(helper::createLink('programplan', 'create', "program=$product->program&productID=$productID"), " {$this->lang->programplan->create}", '', "class='btn btn-primary'"); + } + + $this->lang->modulePageActions = $pageActions; + + foreach($this->lang->product->menu as $key => $menu) + { + $replace = array(); + $replace['productID'] = $productID; + $replace['branch'] = $branch; + common::setMenuVars($this->lang->product->menu, $key, $replace); + } + } + + /** + * Get product module menu. + * + * @param array $products + * @param int $productID + * @param string $currentModule + * @param string $currentMethod + * @param string $extra + * + * @access public + * @return string + */ + public function getModuleNav($products, $project, $product, $extra, $branch, $module, $moduleType) + { $currentModule = $this->app->getModuleName(); $currentMethod = $this->app->getMethodName(); /* init currentModule and currentMethod for report and story. */ if($currentModule == 'story') - { - if($currentMethod != 'create' and $currentMethod != 'batchcreate') $currentModule = 'product'; - if($currentMethod == 'view' || $currentMethod == 'change' || $currentMethod == 'review') $currentMethod = 'browse'; + { + if($currentMethod != 'track' and $currentMethod != 'create' and $currentMethod != 'batchcreate') $currentModule = 'product'; + if($currentMethod == 'view') $currentMethod = 'browse'; } if($currentMethod == 'report') $currentMethod = 'browse'; - $selectHtml = $this->select($products, $productID, $currentModule, $currentMethod, $extra, $branch, $module, $moduleType); - $label = $this->lang->product->index; - if($this->config->global->flow != 'full') $label = $this->lang->product->all; - if($currentModule == 'product' && $currentMethod == 'all') $label = $this->lang->product->all; - if($currentModule == 'product' && $currentMethod == 'create') $label = $this->lang->product->create; + $selectHtml = $this->select($products, $product->id, $currentModule, $currentMethod, $extra, $branch, $module, $moduleType); $pageNav = ''; $isMobile = $this->app->viewType == 'mhtml'; if($isMobile) - { + { $pageNav = html::a(helper::createLink('product', 'index'), $this->lang->product->index) . $this->lang->colon; $pageNav .= $selectHtml; } else - { - $pageNav = '
'; - $pageNav .= '
'; - $pageNav .= $selectHtml; + { + if(isset($project->category) and $project->category == 'multiple') $pageNav = $selectHtml; } $pageActions = ''; if($this->config->global->flow != 'full') - { + { if($currentMethod == 'build' && common::hasPriv('build', 'create')) - { + { $this->app->loadLang('build'); $pageActions .= html::a(helper::createLink('build', 'create', "productID=$productID"), " {$this->lang->build->create}", '', "class='btn btn-primary'"); } } - $this->lang->modulePageNav = $pageNav; - $this->lang->modulePageActions = $pageActions; - foreach($this->lang->product->menu as $key => $menu) - { - $replace = $productID; - common::setMenuVars($this->lang->product->menu, $key, $replace); - } + return $pageNav; } /** @@ -330,6 +357,20 @@ class productModel extends model ->fetchPairs(); } + /** + * Get product id by project. + * + * @param int $projectID + * @access public + * @return array + */ + public function getProductIDByProject($projectID) + { + $products = $this->dao->select('product')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($projectID)->fetchPairs(); + + return empty($products) ? 0 : current($products); + } + /** * Get grouped products. * diff --git a/module/program/control.php b/module/program/control.php index e5cd49828c..d39645dc8e 100644 --- a/module/program/control.php +++ b/module/program/control.php @@ -11,7 +11,7 @@ class program extends control public function index($status = 'doing', $orderBy = 'order_desc', $recTotal = 0, $recPerPage = 10, $pageID = 1) { - if(common::hasPriv('program', 'create')) $this->lang->pageActions = html::a($this->createLink('program', 'create'), " " . $this->lang->program->create, '', "class='btn btn-primary'"); + if(common::hasPriv('program', 'createGuide')) $this->lang->pageActions = html::a($this->createLink('program', 'createGuide'), " " . $this->lang->program->create, '', "class='btn btn-primary' data-toggle=modal"); $programType = $this->cookie->programType ? $this->cookie->programType : 'bylist'; diff --git a/module/program/model.php b/module/program/model.php index 0b66a78a52..bfd688e70d 100644 --- a/module/program/model.php +++ b/module/program/model.php @@ -164,7 +164,8 @@ class programModel extends model $dropMenuLink = helper::createLink('program', 'ajaxGetDropMenu', "objectID=$programID&module=$currentModule&method=$currentMethod&extra=$extra"); $output = "
"; + $output .= ''; + $output .= ""; //if($isMobile) $output = "{$currentProjectName} "; return $output; diff --git a/module/program/view/ajaxgetdropmenu.html.php b/module/program/view/ajaxgetdropmenu.html.php index d5f9bfc82a..70b05c12af 100644 --- a/module/program/view/ajaxgetdropmenu.html.php +++ b/module/program/view/ajaxgetdropmenu.html.php @@ -49,7 +49,7 @@ foreach($programs as $program) ?>