Files
EasySoft-ZenTaoPMS/module/weekly/model.php
2020-08-20 15:06:08 +08:00

358 lines
14 KiB
PHP

<?php
/**
* The model file of weekly module of ChanzhiEPS.
*
* @copyright Copyright 2009-2010 QingDao Nature Easy Soft Network Technology Co,LTD (www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv11.html)
* @author Xiying Guan <guanxiying@xirangit.com>
* @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 = "<div class='btn-group angle-btn'>";
$selectHtml .= html::a('###', $this->lang->weekly->common . $this->lang->colon . $program->name, '', "class='btn'");
$selectHtml .= '</div>';
$selectHtml .= "<div class='btn-group angle-btn'>";
$selectHtml .= "<div class='btn-group'>";
$selectHtml .= "<a data-toggle='dropdown' class='btn' title=$current>" . $current . " <span class='caret'></span></a>";
$selectHtml .= "<ul class='dropdown-menu'>";
foreach($weeks as $day => $title)
{
$selectHtml .= '<li>' . html::a(helper::createLink('weekly', 'index', "program={$program->id}&date=$day"), $title) . '</li>';
}
$selectHtml .='</ul></div></div>';
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 t1.account) as count')
->from(TABLE_TASKESTIMATE)->alias('t1')
->leftJoin(TABLE_TASK)->alias('t2')->on('t1.task=t2.id')
->where('t2.project')->in($projectIdList)
->andWhere('t1.date')->ge($monday)
->andWhere('t1.date')->lt($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(t1.consumed) as consumed')
->from(TABLE_TASKESTIMATE)->alias('t1')
->leftJoin(TABLE_TASK)->alias('t2')->on('t1.task=t2.id')
->where('t2.project')->in($projectIdList)
->andWhere('t1.date')->ge($monday)
->andWhere('t1.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 '';
}
}