From de3c53ec94222426cb621f8ff56b8f2e4318dc8c Mon Sep 17 00:00:00 2001 From: Yagami <976204163@qq.com> Date: Thu, 20 Aug 2020 11:09:23 +0800 Subject: [PATCH 1/4] * Add blocks. --- config/zentaopms.php | 3 +- db/update20.0.sql | 28 +- module/block/control.php | 36 +- module/block/lang/zh-cn.php | 8 + module/block/view/cmmiestimateblock.html.php | 19 + module/block/view/cmmiissueblock.html.php | 49 +++ module/block/view/cmmireportblock.html.php | 36 +- module/durationestimation/lang/zh-cn.php | 3 +- module/issue/model.php | 12 + module/program/lang/zh-cn.php | 1 + module/weekly/control.php | 47 +++ module/weekly/lang/zh-cn.php | 29 ++ module/weekly/model.php | 356 +++++++++++++++++++ module/weekly/view/index.html.php | 186 ++++++++++ module/workestimation/lang/zh-cn.php | 2 + 15 files changed, 799 insertions(+), 16 deletions(-) create mode 100644 module/weekly/control.php create mode 100644 module/weekly/lang/zh-cn.php create mode 100644 module/weekly/model.php create mode 100644 module/weekly/view/index.html.php diff --git a/config/zentaopms.php b/config/zentaopms.php index 8b9c05222d..527d4c87fa 100644 --- a/config/zentaopms.php +++ b/config/zentaopms.php @@ -191,13 +191,14 @@ if(!defined('TABLE_LANG')) define('TABLE_LANG', '`' . $config->db- 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_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`'); if(!defined('TABLE_HOLIDAY')) define('TABLE_HOLIDAY', '`' . $config->db->prefix . 'holiday`'); +if(!defined('TABLE_WEEKLYREPORT')) define('TABLE_WEEKLYREPORT', '`' . $config->db->prefix . 'weeklyreport`'); $config->objectTables['product'] = TABLE_PRODUCT; $config->objectTables['story'] = TABLE_STORY; diff --git a/db/update20.0.sql b/db/update20.0.sql index 6024f6404c..5e06cbc15a 100644 --- a/db/update20.0.sql +++ b/db/update20.0.sql @@ -262,10 +262,26 @@ ADD `product` mediumint(8) unsigned NOT NULL DEFAULT '0' AFTER `project`; -- DROP TABLE IF EXISTS `zt_taskspec`; CREATE TABLE `zt_taskspec` ( - `task` mediumint(8) NOT NULL, - `version` smallint(6) NOT NULL, - `name` varchar(255) NOT NULL, - `estStarted` date NOT NULL, - `deadline` date NOT NULL, - UNIQUE KEY `task` (`task`,`version`) + `task` mediumint(8) NOT NULL, + `version` smallint(6) NOT NULL, + `name` varchar(255) NOT NULL, + `estStarted` date NOT NULL, + `deadline` date NOT NULL, + UNIQUE KEY `task` (`task`,`version`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +CREATE TABLE `zt_weeklyreport`( + `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, + `program` mediumint(8) unsigned NOT NULL, + `weekStart` date NOT NULL, + `pv` float(9,2) NOT NULL, + `ev` float(9,2) NOT NULL, + `ac` float(9,2) NOT NULL, + `sv` float(9,2) NOT NULL, + `cv` float(9,2) NOT NULL, + `staff` smallint(5) unsigned NOT NULL, + `progress` varchar(255) NOT NULL, + `workload` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `week` (`program`,`weekStart`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/module/block/control.php b/module/block/control.php index e778970060..c0a463d030 100644 --- a/module/block/control.php +++ b/module/block/control.php @@ -990,7 +990,26 @@ class block extends control */ public function printCmmiReportBlock() { - $this->view->program = $this->loadModel('project')->getByID($this->session->program); + $program = $this->loadModel('project')->getByID($this->session->program); + $today = date('Y-m-d', strtotime(helper::today())); + $date = date('Ymd', strtotime($this->loadModel('weekly')->getThisMonday($today))); + $begin = $program->begin; + $weeks = $this->weekly->getWeekPairs($begin); + $current = zget($weeks, $date, ''); + $task = $this->dao->select("sum(consumed) as totalConsumed, sum(if(status != 'cancel' and status != 'closed', `left`, 0)) as totalLeft")->from(TABLE_TASK)->where('program')->eq($this->session->program) + ->andWhere('deleted')->eq(0) + ->andWhere('parent')->lt(1) + ->fetch(); + + + $this->view->pv = $this->weekly->getPV($this->session->program, $today); + $this->view->ev = $this->weekly->getEV($this->session->program, $today); + $this->view->ac = $this->weekly->getAC($this->session->program, $today); + $this->view->sv = $this->weekly->getSV($this->view->ev, $this->view->pv); + $this->view->cv = $this->weekly->getCV($this->view->ev, $this->view->ac); + + $this->view->current = $current; + $this->view->progress = ($task->totalConsumed || $task->totalLeft) ? round($task->totalConsumed / ($task->totalConsumed + $task->totalLeft), 2) * 100 : 0; } /** @@ -1012,7 +1031,10 @@ class block extends control */ public function printCmmiIssueBlock() { - $this->view->program = $this->loadModel('project')->getByID($this->session->program); + $uri = $this->app->getURI(true); + $this->session->set('riskList', $uri); + if(preg_match('/[^a-zA-Z0-9_]/', $this->params->type)) die(); + $this->view->issues = $this->loadModel('issue')->getBlockIssues($this->params->type, $this->viewType == 'json' ? 0 : (int)$this->params->num, null, $this->params->orderBy); } /** @@ -1034,7 +1056,15 @@ class block extends control */ public function printCmmiEstimateBlock() { - $this->view->program = $this->loadModel('project')->getByID($this->session->program); + $this->app->loadLang('durationestimation'); + $programID = $this->session->program; + $members = $this->loadModel('project')->getTeamMemberPairs($programID); + $budget = $this->loadModel('workestimation')->getBudget($programID); + if(empty($budget)) $budget = new stdclass(); + + $this->view->people = $this->dao->select('sum(people) as people')->from(TABLE_DURATIONESTIMATION)->where('program')->eq($this->session->program)->fetch('people'); + $this->view->members = count($members) ? count($members) : ''; + $this->view->budget = $budget; } /** diff --git a/module/block/lang/zh-cn.php b/module/block/lang/zh-cn.php index 73eb0241cf..f23dba8fde 100644 --- a/module/block/lang/zh-cn.php +++ b/module/block/lang/zh-cn.php @@ -84,6 +84,10 @@ $lang->block->default['cmmi']['program']['5']['title'] = '项目问题'; $lang->block->default['cmmi']['program']['5']['block'] = 'cmmiissue'; $lang->block->default['cmmi']['program']['5']['grid'] = 8; +$lang->block->default['cmmi']['program']['5']['params']['type'] = 'all'; +$lang->block->default['cmmi']['program']['5']['params']['num'] = '15'; +$lang->block->default['cmmi']['program']['5']['params']['orderBy'] = 'id_desc'; + $lang->block->default['cmmi']['program']['6']['title'] = '最新动态'; $lang->block->default['cmmi']['program']['6']['block'] = 'dynamic'; $lang->block->default['cmmi']['program']['6']['grid'] = 4; @@ -93,6 +97,10 @@ $lang->block->default['cmmi']['program']['7']['title'] = '项目风险'; $lang->block->default['cmmi']['program']['7']['block'] = 'cmmirisk'; $lang->block->default['cmmi']['program']['7']['grid'] = 8; +$lang->block->default['cmmi']['program']['7']['params']['type'] = 'all'; +$lang->block->default['cmmi']['program']['7']['params']['num'] = '15'; +$lang->block->default['cmmi']['program']['7']['params']['orderBy'] = 'id_desc'; + $lang->block->default['product']['1']['title'] = $lang->productCommon . '统计'; $lang->block->default['product']['1']['block'] = 'statistic'; $lang->block->default['product']['1']['grid'] = 8; diff --git a/module/block/view/cmmiestimateblock.html.php b/module/block/view/cmmiestimateblock.html.php index e69de29bb2..162bbd283b 100644 --- a/module/block/view/cmmiestimateblock.html.php +++ b/module/block/view/cmmiestimateblock.html.php @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + +
durationestimation->people;?>durationestimation->members;?>
workestimation->duration;?>workestimation->hour;?>workestimation->consumed;?>workestimation->hour;?>
workestimation->totalLaborCost;?>
diff --git a/module/block/view/cmmiissueblock.html.php b/module/block/view/cmmiissueblock.html.php index e69de29bb2..2c3494926e 100644 --- a/module/block/view/cmmiissueblock.html.php +++ b/module/block/view/cmmiissueblock.html.php @@ -0,0 +1,49 @@ + +
block->emptyTip;?>
+ + +
+ '> + + + + + + + + + + + + + + + + createLink('issue', 'view', "issueID={$issue->id}"); + ?> + + + + + + + + + + + + + +
idAB;?>issue->type;?> issue->name;?>issue->severity;?>issue->pri;?>issue->assignedTo;?>issue->status;?>
id);?>issue->typeList, $issue->type);?>name?>issue->severityList, $issue->severity, $issue->severity)?>issue->priList, $issue->pri, $issue->pri)?>assignedTo, $issue->assignedTo)?> + issue->statusList, $issue->status);?> +
+
+ diff --git a/module/block/view/cmmireportblock.html.php b/module/block/view/cmmireportblock.html.php index 26004dbdec..087f3e0de8 100644 --- a/module/block/view/cmmireportblock.html.php +++ b/module/block/view/cmmireportblock.html.php @@ -3,22 +3,48 @@ .block-cmmireport .col-right{width: 75%;} .block-cmmireport .panel-body{padding-top: 0px;} .block-cmmireport .table-row{margin-bottom: 20px;} -.progress {position: absolute; left: 22px; top: 90px; right: 8px;} +.block-cmmireport .stage{position: absolute; top: 14px; left: 90px;} +.block-cmmireport .col-right .tiles { padding: 10px 0 0 16px; } +.block-cmmireport .col-right .tile { width: 20%;} +.block-cmmireport .col-right .tile .tile-title{font-weight: 700;} +.progress {position: absolute; left: 45px; top: 90px; right: 40px;} .progress-num{font-size: 34px; font-weight: 700} -
+
-

项目进度

- 70% +

program->progress;?>

+
-
+
+
+
+
PV
+
+
+
+
EV
+
+
+
+
AC
+
+
+
+
SV%
+
+
+
+
CV%
+
+
+
diff --git a/module/durationestimation/lang/zh-cn.php b/module/durationestimation/lang/zh-cn.php index 84fda83577..ca14a4ac9c 100644 --- a/module/durationestimation/lang/zh-cn.php +++ b/module/durationestimation/lang/zh-cn.php @@ -6,7 +6,8 @@ $lang->durationestimation->stage = '阶段'; $lang->durationestimation->workloadRate = '工作量占比'; $lang->durationestimation->workload = '工作量'; $lang->durationestimation->worktimeRate = '全时率'; -$lang->durationestimation->people = '投入人数'; +$lang->durationestimation->people = '估算人数'; +$lang->durationestimation->members = '投入人数'; $lang->durationestimation->startDate = '开始日期'; $lang->durationestimation->endDate = '结束日期'; $lang->durationestimation->setting = '设置'; diff --git a/module/issue/model.php b/module/issue/model.php index 932b1aca98..1a4f56ebac 100644 --- a/module/issue/model.php +++ b/module/issue/model.php @@ -83,6 +83,18 @@ class issueModel extends model return $issueList; } + public function getBlockIssues($browseType = 'all', $limit = 15, $orderBy = 'id_desc') + { + $issueList = $this->dao->select('*')->from(TABLE_ISSUE) + ->where('program')->eq($this->session->program) + ->andWhere('deleted')->eq('0') + ->orderBy($orderBy) + ->limit($limit) + ->fetchAll(); + + return $issueList; + } + /** * Delete a question. * diff --git a/module/program/lang/zh-cn.php b/module/program/lang/zh-cn.php index 4104d58604..dce172f3dc 100644 --- a/module/program/lang/zh-cn.php +++ b/module/program/lang/zh-cn.php @@ -46,6 +46,7 @@ $lang->program->mine = '我参与的'; $lang->program->setPlanduration = '设置工期'; $lang->program->privway = '权限控制'; $lang->program->durationEstimation = '工作量估算'; +$lang->program->progress = '项目进度'; $lang->program->unitList[''] = ''; $lang->program->unitList['yuan'] = '元'; diff --git a/module/weekly/control.php b/module/weekly/control.php new file mode 100644 index 0000000000..cd392a4b39 --- /dev/null +++ b/module/weekly/control.php @@ -0,0 +1,47 @@ + + * @package weekly + * @version $Id$ + * @link http://www.chanzhi.org + */ +class weekly extends control +{ + public function __construct() + { + parent::__construct(); + $this->view->users = $this->loadModel('user')->getPairs('noletter'); + } + + public function index($program, $date = '') + { + if(!$date) $date = helper::today(); + $date = date('Y-m-d', strtotime($date)); + + $this->view->title = $this->lang->weekly->common; + + $this->view->pv = $this->weekly->getPV($program, $date); + $this->view->ev = $this->weekly->getEV($program, $date); + $this->view->ac = $this->weekly->getAC($program, $date); + $this->view->sv = $this->weekly->getSV($this->view->ev, $this->view->pv); + $this->view->cv = $this->weekly->getCV($this->view->ev, $this->view->ac); + + $this->view->program = $this->loadModel('project')->getByID($program); + $this->view->weekSN = $this->weekly->getWeekSN($this->view->program->begin, $date); + $this->view->monday = $this->weekly->getThisMonday($date); + $this->view->lastDay = $this->weekly->getLastDay($date); + $this->view->staff = $this->weekly->getStaff($program); + $this->view->finished = $this->weekly->getFinished($program); + $this->view->postponed = $this->weekly->getPostponed($program); + $this->view->nextWeek = $this->weekly->getTasksOfNextWeek($program, $date); + $this->view->workload = $this->weekly->getWorkloadByType($program, $date); + $this->weekly->save($program, $this->view, $date); + + $this->lang->modulePageNav = $this->weekly->getPageNav($this->view->program, $date); + $this->display(); + } +} diff --git a/module/weekly/lang/zh-cn.php b/module/weekly/lang/zh-cn.php new file mode 100644 index 0000000000..b21a2a2fd0 --- /dev/null +++ b/module/weekly/lang/zh-cn.php @@ -0,0 +1,29 @@ +weekly->common = '项目周报'; +$lang->weekly->index = '周报总览'; +$lang->weekly->progress = '完成百分比'; +$lang->weekly->workload = '工作量'; +$lang->weekly->total = '合计'; + +$lang->weekly->reportTtitle = '项目: %s 周报(第 %s 周)'; +$lang->weekly->summary = '项目进展状况'; +$lang->weekly->finished = '本周工作完成情况(100%完成的工作)'; +$lang->weekly->postponed = '本周未完成工作'; +$lang->weekly->nextWeek = '下周工作计划'; +$lang->weekly->workloadByType = '工作量统计'; + +$lang->weekly->term = '报告周期'; +$lang->weekly->program = '项目名称'; +$lang->weekly->master = '项目经理 '; +$lang->weekly->staff = '本周投入人数'; + +$lang->weekly->weekDesc = '第 %s 周( %s ~ %s)'; +$lang->weekly->progress = '项目当前进展状况'; +$lang->weekly->analysisResult = '分析结果'; +$lang->weekly->cost = '项目成本'; + +$lang->weekly->pv = '计划完成的工作(PV)'; +$lang->weekly->ev = '实际完成的工作(EV)'; +$lang->weekly->ac = '实际花费的成本(AC)'; +$lang->weekly->sv = '进度偏差率(SV%)'; +$lang->weekly->cv = '成本偏差率(CV%)'; diff --git a/module/weekly/model.php b/module/weekly/model.php new file mode 100644 index 0000000000..4f8a7df181 --- /dev/null +++ b/module/weekly/model.php @@ -0,0 +1,356 @@ + + * @package weekly + * @version $Id$ + * @link http://www.chanzhi.org + */ +class weeklyModel extends model +{ + public function getPageNav($program, $date) + { + $date = date('Ymd', strtotime($this->getThisMonday($date))); + $begin = $program->begin; + $weeks = $this->getWeekPairs($begin); + $current = zget($weeks, $date, ''); + $selectHtml = "
"; + $selectHtml .= html::a('###', $this->lang->weekly->common . $this->lang->colon . $program->name, '', "class='btn'"); + $selectHtml .= '
'; + + $selectHtml .= "
"; + $selectHtml .= "
"; + $selectHtml .= "" . $current . " "; + $selectHtml .= "
'; + return $selectHtml; + + } + + public function getWeekPairs($begin) + { + $sn = $this->getWeekSN($begin, date('Y-m-d')); + $weeks = array(); + for($i = 0; $i <= $sn; $i++) + { + $monday = $this->getThisMonday($begin); + $sunday = $this->getThisSunday($begin); + $begin = date('Y-m-d', strtotime("$begin +7 days")); + $key = date('Ymd', strtotime($monday)); + $weeks[$key] = sprintf($this->lang->weekly->weekDesc, $i + 1, $monday, $sunday); + } + krsort($weeks); + return $weeks; + } + + public function getFromDB($program, $date) + { + $monday = $this->getThisMonday($date); + return $this->dao->select('*') + ->from(TABLE_WEEKLYREPORT) + ->where('weekStart')->eq($monday) + ->andWhere('program')->eq($program) + ->fetch(); + } + + public function save($program, $data, $date) + { + $report = new stdclass; + $report->pv = zget($data, 'pv', ''); + $report->ev = zget($data, 'ev', ''); + $report->ac = zget($data, 'ac', ''); + $report->sv = zget($data, 'sv', ''); + $report->cv = zget($data, 'cv', ''); + $report->program = $program; + $report->weekStart = $this->getThisMonday($date); + $report->staff = zget($data, 'staff', ''); + $report->progress = zget($data, 'progress', ''); + $report->workload = json_encode(zget($data, 'workload', '')); + $this->dao->replace(TABLE_WEEKLYREPORT)->data($report)->exec(); + } + + public function getWeekSN($begin, $date) + { + return ceil((strtotime($date) - strtotime($begin)) / 7 / 86400); + } + + public function getThisMonday($date) + { + $day = date('w', strtotime($date)); + if($day == 0) $day = 7; + $days = $day - 1; + return date('Y-m-d', strtotime("$date - $days days")); + } + + public function getThisSunday($date) + { + $monday = $this->getThisMonday($date); + return date('Y-m-d', strtotime("$monday +6 days")); + } + + public function getLastDay($date) + { + $this->loadModel('project'); + $weekend = zget($this->config->project, 'weekend', 2); + $monday = $this->getThisMonday($date); + $sunday = $this->getThisSunday($date); + $workdays = $this->loadModel('holiday')->getActualWorkingDays($monday, $sunday); + return end($workdays); + } + + public function getStaff($program, $date = '') + { + if(!$date) $date = date('Y-m-d'); + $monday = $this->getThisMonday($date); + $sunday = $this->getThisSunday($date); + $projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $type = 'project', $program); + $projectIdList = array_keys($projects); + return $this->dao->select('count(distinct account) as count') + ->from(TABLE_EFFORT) + ->where('objectType')->eq('task') + ->andWhere('project')->in($projectIdList) + ->andWhere('date')->ge($monday) + ->andWhere('date')->le($sunday) + ->fetch('count'); + } + + public function getFinished($program, $date = '', $pager = null) + { + if(!$date) $date = date('Y-m-d'); + $monday = $this->getThisMonday($date); + $sunday = $this->getThisSunday($date); + + $projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $type = 'project', $program); + $projectIdList = array_keys($projects); + + $tasks = $this->dao->select('*') + ->from(TABLE_TASK) + ->where('project')->in($projectIdList) + ->andWhere("(status='done' or closedReason= 'done')") + ->andWhere('finishedDate')->ge($monday) + ->andWhere('finishedDate')->le($sunday) + ->fetchAll(); + return $this->loadModel('task')->processTasks($tasks); + } + + public function getPostponed($program, $date = '') + { + if(!$date) $date = date('Y-m-d'); + $monday = $this->getThisMonday($date); + $sunday = $this->getThisSunday($date); + $nextMonday = date('Y-m-d', strtotime("$sunday +1 days")); + + $projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $type = 'project', $program); + $projectIdList = array_keys($projects); + $unFinished = $this->dao->select('*') + ->from(TABLE_TASK) + ->where('project')->in($projectIdList) + ->andWhere('status')->in('wait,doing,pause') + ->andWhere('deadline')->ge($monday) + ->andWhere('deadline')->le($sunday) + ->fetchAll('id'); + + $postponed = $this->dao->select('*') + ->from(TABLE_TASK) + ->where('project')->in($projectIdList) + ->andWhere('finishedDate')->gt($nextMonday) + ->andWhere('deadline')->ge($monday) + ->andWhere('deadline')->lt($nextMonday) + ->fetchAll('id'); + + $tasks = array_merge($unFinished, $postponed); + return $this->loadModel('task')->processTasks($tasks); + } + + public function getTasksOfNextWeek($program, $date = '') + { + if(!$date) $date = date('Y-m-d'); + $sunday = $this->getThisSunday($date); + $nextMonday = date('Y-m-d', strtotime("$sunday +1 days")); + $sencondMondy = date('Y-m-d', strtotime("$sunday +8 days")); + + $projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $type = 'project', $program); + $projectIdList = array_keys($projects); + + $tasks = $this->dao->select('*') + ->from(TABLE_TASK) + ->where('project')->in($projectIdList) + ->andWhere("((deadline > '$nextMonday' and deadline < '$sencondMondy') or (estStarted > '$nextMonday' and estStarted < '$sencondMondy'))") + ->fetchAll('id'); + + return $this->loadModel('task')->processTasks($tasks); + } + + public function getWorkloadByType($program, $date = '') + { + if(!$date) $date = date('Y-m-d'); + + $sunday = $this->getThisSunday($date); + $nextMonday = date('Y-m-d', strtotime("$sunday +1 days")); + $sencondMondy = date('Y-m-d', strtotime("$sunday +8 days")); + + $projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $type = 'project', $program); + $projectIdList = array_keys($projects); + + return $this->dao->select('type, sum(cast(estimate as decimal(10,2))) as workload') + ->from(TABLE_TASK) + ->where('project')->in($projectIdList) + ->groupBy('type') + ->fetchPairs(); + } + + public function getPlanedTaskByWeek($program, $date = '') + { + if(!$date) $date = date('Y-m-d'); + $monday = $this->getThisMonday($date); + $nextMonday = date('Y-m-d', strtotime("$monday +7 days")); + + $projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $type = 'project', $program); + $projectIdList = array_keys($projects); + + return $this->dao->select('*') + ->from(TABLE_TASK) + ->where('project')->in($projectIdList) + ->andWhere('deadline')->ge($monday) + ->fetchAll('id'); + } + + public function getPV($program, $date = '') + { + $report = $this->getFromDB($program, $date); + if(!empty($report)) return $report->pv; + + $program = $this->loadModel('project')->getByID($program); + + if(!$date) $date = date('Y-m-d'); + $monday = $this->getThisMonday($date); + $sunday = $this->getThisSunday($date); + $lastDay = $this->getLastDay($date); + $nextMonday = date('Y-m-d', strtotime("$sunday +1 days")); + $workdays = $this->loadModel('holiday')->getActualWorkingDays($monday, $sunday); + + $projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $type = 'project', $program->id); + $projectIdList = array_keys($projects); + + $tasks = $this->dao->select('*')->from(TABLE_TASK) + ->where('project')->in($projectIdList) + ->andWhere("(estStarted < '$nextMonday' or estStarted='0000-00-00')") + ->fetchAll('id'); + + $PV = 0; + foreach($tasks as $task) + { + if($task->estStarted == '0000-00-00') $task->estStarted = date('Y-m-d', strtotime($task->openedDate)); + if($task->deadline < $nextMonday) + { + $PV += $task->estimate; + continue; + } + + $fullDays = $this->loadModel('holiday')->getActualWorkingDays($task->estStarted, $task->deadline); + $passedDays = $this->loadModel('holiday')->getActualWorkingDays($task->estStarted, $sunday); + + $PV += count($passedDays) * $task->estimate / count($fullDays); + } + + return round($PV, 2); + } + + public function getEV($program, $date = '') + { + $report = $this->getFromDB($program, $date); + if(!empty($report)) return $report->ev; + + $projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $type = 'project', $program); + $projectIdList = array_keys($projects); + + if(!$date) $date = date('Y-m-d'); + $monday = $this->getThisMonday($date); + $sunday = $this->getThisSunday($date); + $lastDay = $this->getLastDay($date); + $nextMonday = date('Y-m-d', strtotime("$sunday +1 days")); + + $tasks = $this->dao->select('*') + ->from(TABLE_TASK) + ->where('project')->in($projectIdList) + ->andWhere('consumed')->gt(0) + ->andWhere('status')->ne('cancel') + ->fetchAll('id'); + + $EV = 0; + foreach($tasks as $task) + { + if($task->status == 'done' or $task->closedReason == 'done') + { + $EV += $task->estimate; + } + else + { + $task->progress = round($task->consumed / ($task->consumed + $task->left), 2) * 100; + $EV += $task->estimate * $task->progress / 100; + } + } + return round($EV, 2); + } + + public function getAC($program, $date = '') + { + $report = $this->getFromDB($program, $date); + if(!empty($report)) return $report->ac; + + if(!$date) $date = date('Y-m-d'); + + $monday = $this->getThisMonday($date); + $nextMonday = date('Y-m-d', strtotime("$monday +7 days")); + $projects = $this->loadModel('project')->getList($status = 'all', $limit = 0, $productID = 0, $branch = 0, $type = 'project', $program); + $projectIdList = array_keys($projects); + + $AC = $this->dao->select('sum(consumed) as consumed') + ->from(TABLE_EFFORT) + ->where('objectType')->eq('task') + ->andWhere('project')->in($projectIdList) + ->andWhere('date')->ge($monday) + ->andWhere('date')->lt($nextMonday) + ->fetch('consumed'); + + return round($AC, 2); + } + + public function getSV($ev, $pv) + { + if($pv == 0) return 0; + $sv = -1 * (1- ($ev / $pv)); + return number_format($sv * 100, 2); + } + + public function getCV($ev, $ac) + { + if($ac == 0) return 0; + $cv = -1 * (1 - ($ev / $ac)); + return number_format($cv * 100, 2); + } + + public function getTips($type = 'progress', $data = 0) + { + $this->app->loadConfig('custom'); + if($type == 'progress') $tipsConfig = isset($this->config->custom->SV->progressTip) ? $this->config->custom->SV->progressTip : ''; + if($type == 'cost') $tipsConfig = isset($this->config->custom->CV->costTip) ? $this->config->custom->CV->costTip : ''; + + if(empty($tipsConfig)) return ''; + + $tipsConfig = json_decode($tipsConfig); + foreach($tipsConfig as $tipConfig) + { + if($tipConfig->min <= $data and $tipConfig->max >= $data) return $tipConfig->tip; + } + + return ''; + } +} diff --git a/module/weekly/view/index.html.php b/module/weekly/view/index.html.php new file mode 100644 index 0000000000..f745dbd3b2 --- /dev/null +++ b/module/weekly/view/index.html.php @@ -0,0 +1,186 @@ + + * @package ZenTaoPMS + * @version $Id: index.html.php 5094 2013-07-10 08:46:15Z chencongzhi520@gmail.com $ + */ +?> + +