<?php
class milestoneModel extends model
{
    public function getPageNav($programID, $projectID, $productID)
    {
        $milestones       = $this->loadModel('programplan')->getMilestones($programID);
        if(empty($milestones)) return false;
        $current          = zget($milestones, $projectID) ? zget($milestones, $projectID) : current($milestones);
        $currentProjectID = $projectID ? $projectID : key($milestones);
        $program          = $this->loadModel('project')->getByID($programID);

        $selectHtml = '';
        if($program->category == 'multiple')
        {   
            $products         = $this->loadModel('product')->getPairs($programID);
            $currentProductID = $productID ? $productID : $this->product->getProductIDByProject($projectID);
            if(!$currentProductID) $currentProductID = key($products);
            $productName      = $this->dao->findByID($currentProductID)->from(TABLE_PRODUCT)->fetch('name');
            $pinYin           = common::convert2Pinyin($products);

            $selectHtml    .= "<div class='btn-group angle-btn'>";
            $selectHtml    .= "<a data-toggle='dropdown' class='btn' title=$productName>" . $productName . " <span class='caret'></span></a>";
            $selectHtml    .= '<div id="dropMenu" class="dropdown-menu search-list load-indicator" data-ride="searchList">';
            $selectHtml    .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';  
            $selectHtml    .= '<div class="list-group"><div class="table-row"><div class="table-col col-left"><div class="list-group">';
            foreach($products as $id => $name)
            {   
                $selectHtml .= html::a(helper::createLink('milestone', 'index', "program={$programID}&project=0&productID=$id"), "<i class='icon icon-folder-outline'></i> " . $name, '', "title='{$name}' data-key='" . zget($pinYin, $name, '') . "'");
            }   
            $selectHtml .='</div></div></div></div></div></div>';

            $milestones = $this->loadModel('programplan')->getMilestoneByProduct($currentProductID);
            $current    = zget($milestones, $projectID) ? zget($milestones, $projectID) : current($milestones);
            $currentProjectID = $projectID ? $projectID : key($milestones);
            if(!$current) $current = $this->lang->noData;
        }

        $pinYin = common::convert2Pinyin($milestones);

        $selectHtml    .= "<div class='btn-group angle-btn'>";
        $selectHtml    .= "<a data-toggle='dropdown' class='btn' title=$current>" . $current . " <span class='caret'></span></a>";
        $selectHtml    .= '<div id="dropMenu" class="dropdown-menu search-list load-indicator" data-ride="searchList">';
        $selectHtml    .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';  
        $selectHtml    .= '<div class="list-group"><div class="table-row"><div class="table-col col-left"><div class="list-group">';
        foreach($milestones as $id => $name)
        {   
            $selectHtml .= html::a(helper::createLink('milestone', 'index', "program={$programID}&project=$id"), "<i class='icon icon-folder-outline'></i> " . $name, '', "title='{$name}' data-key='" . zget($pinYin, $name, '') . "'");
        }   
        $selectHtml .='</div></div></div></div></div></div>';
        return array($selectHtml, $currentProjectID);
    }

    public function getBasicInfo($programID, $projectID)
    {
        $program = $this->loadModel('project')->getByID($programID);
        $project = $this->loadModel('project')->getByID($projectID);
        /* Get startedWeeks and finishedWeeks.*/
        $project->startedWeeks  = $project->realStarted == '0000-00-00' ? 0 : ceil((strtotime(helper::today()) - strtotime($project->realStarted )) / 3600 / 24 / 7);
        $project->finishedWeeks = $project->realFinished == '0000-00-00' ? 0 : ceil((strtotime(helper::today()) - strtotime($project->realFinished)) / 3600 / 24 / 7);
        $project->offset        = $project->realFinished == '0000-00-00' ? 0 : helper::diffDate($project->end, $project->realFinished);

        $basicInfo = new stdclass();
        $basicInfo->program = $program;
        $basicInfo->project = $project;
        return $basicInfo;
    }

    public function getProcess($programID, $projectID)
    {
        $process = new stdclass();
        $program = $this->loadModel('project')->getByID($programID);
        $project = $this->loadModel('project')->getByID($projectID);
        $productID     = $this->loadModel('product')->getProductIDByProject($projectID);
        $projectIdList = $this->loadModel('programplan')->getProjectsByProduct($productID);
        $projectBegin  = $project->begin;
        $projectEnd    = $project->end;
        $programBegin  = $program->begin;
        $today         = helper::today();

        $process->milestonePV = $this->getPV($projectID, $projectBegin, $projectEnd);
        $process->nowPV       = $this->getPV($projectIdList, $programBegin, $projectEnd);

        $process->milestoneEV = $this->getEV($projectID, $projectBegin, $projectEnd);
        $process->nowEV       = $this->getEV($projectIdList, $programBegin, $projectEnd);

        $process->milestoneAC = $this->getAC($projectID, $projectBegin, $projectEnd);
        $process->nowAC       = $this->getAC($projectIdList, $projectBegin, $projectEnd);

        $process->milestoneSPI = $process->milestonePV == 0 ? 0 : round($process->milestoneEV / $process->milestonePV, 2);
        $process->nowSPI       = $process->nowPV == 0 ? 0 : round($process->nowEV / $process->nowPV, 2);

        $process->milestoneCPI = $process->milestoneAC == 0 ? 0 : round($process->milestoneEV / $process->milestoneAC, 2);
        $process->nowCPI       = $process->nowAC == 0 ? 0 : round($process->nowEV / $process->nowAC, 2);

        $process->milestoneSV  = $process->milestonePV == 0 ? 0 : round(($process->milestoneEV - $process->milestonePV) / $process->milestonePV, 2) * 100;
        $process->nowSV        = $process->nowPV == 0 ? 0 : round(($process->nowEV - $process->nowPV) / $process->nowPV, 2) * 100;

        $process->milestoneCV  = $process->milestoneAC == 0 ? 0 : round(($process->milestoneEV - $process->milestoneAC) / $process->milestoneAC, 2) * 100;
        $process->nowCV        = $process->nowAC == 0 ? 0 : round(($process->nowEV - $process->nowAC) / $process->nowAC, 2) * 100;

        $process->spiMin = '';
        $process->spiMax = '';
        $process->svMin  = '';
        $process->svMax  = '';
        $process->cpiMin = '';
        $process->cpiMax = '';
        $process->cvMin  = '';
        $process->cvMax  = '';
        $process->cvMax  = '';
        $process->cvMax  = '';
        $process->cvMax  = '';
        $process->nowSpiTip       = '';
        $process->nowCpiTip       = '';
        $process->milestoneSpiTip = '';
        $process->milestoneCpiTip = '';
        $spiTip = isset($this->config->custom->SPI) ? json_decode($this->config->custom->SPI->progressTip) : new stdclass();
        $svTip  = isset($this->config->custom->SV)  ? json_decode($this->config->custom->SV->progressTip) : new stdclass();
        $cpiTip = isset($this->config->custom->CPI) ? json_decode($this->config->custom->CPI->costTip) : new stdclass();
        $cvTip  = isset($this->config->custom->CV)  ? json_decode($this->config->custom->CV->costTip) : new stdclass();
        
        foreach($spiTip as $tip)
        {
            if($tip->min <= $process->milestoneSPI and $process->milestoneSPI < $tip->max) $process->milestoneSpiTip = $tip->tip;
            if($tip->min <= $process->nowSPI and $process->nowSPI < $tip->max) $process->nowSpiTip = $tip->tip;
            if($tip->range)
            {
                $process->spiMin = $tip->min;
                $process->spiMax = $tip->max;
            }
        }

        foreach($svTip as $tip)
        {
            if($tip->range) 
            {
                $process->svMin = $tip->min;
                $process->svMax = $tip->max;
            }
        }

        foreach($cpiTip as $tip)
        {
            if($tip->min <= $process->milestoneCPI and $process->milestoneCPI < $tip->max) $process->milestoneCpiTip = $tip->tip;
            if($tip->min <= $process->nowCPI and $process->nowCPI < $tip->max) $process->nowCpiTip = $tip->tip;
            if($tip->range)
            {
                $process->cpiMin = $tip->min;
                $process->cpiMax = $tip->max;
            }
        }

        foreach($cvTip as $tip)
        {
            if($tip->range) 
            {
                $process->cvMin = $tip->min;
                $process->cvMax = $tip->max;
            }
        }

        return $process;
    }

    public function getCharts($programID, $projectID)
    {
        $this->loadModel('weekly');
        $charts        = array(); 
        $program       = $this->loadModel('project')->getByID($programID);
        $project       = $this->loadModel('project')->getByID($projectID);
        $productID     = $this->loadModel('product')->getProductIDByProject($projectID);
        $projectIdList = $this->loadModel('programplan')->getProjectsByProduct($productID);
        $today         = helper::today();
        $begin         = $program->begin;
        $projectEnd    = $project->end;
        $end           = $today > $projectEnd ? $projectEnd : date('Y-m-d', strtotime("$today + 7 days"));

        $charts['PV'] = '[';
        $charts['EV'] = '[';
        $charts['AC'] = '[';
        $i = 1;
        $start = $begin;
        while($start < $end)
        {
            $charts['labels'][] = $this->lang->milestone->chart->time . $i . $this->lang->milestone->chart->week;
            $sunday             = $this->weekly->getThisSunday($start);
            $charts['PV']      .= $this->getPV($projectIdList, $begin, $sunday) . ',';
            $charts['EV']      .= $this->getEV($projectIdList, $begin, $sunday) . ',';
            $charts['AC']      .= $this->getAC($projectIdList, $begin, $sunday) . ',';
            $start              = date('Y-m-d', strtotime("$start + 7 days"));
            $i ++;
        }

        $charts['PV'] .= ']';
        $charts['EV'] .= ']';
        $charts['AC'] .= ']';

        return $charts;
    }

    public function getPV($projectID, $begin, $end)
    {
        $tasks = $this->dao->select('*')->from(TABLE_TASK)
            ->where('project')->in($projectID)
            ->andWhere('estStarted')->ge($begin)
            ->andWhere("(estStarted < '$end' or estStarted='0000-00-00')")
            ->andWhere('deleted')->eq(0)
            ->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 < $end)
            {   
                $PV += $task->estimate;
                continue;
            }   

            $fullDays   = $this->loadModel('holiday')->getActualWorkingDays($task->estStarted, $task->deadline);
            $passedDays = $this->loadModel('holiday')->getActualWorkingDays($task->estStarted, $end);

            $PV += round(count($passedDays) * $task->estimate / count($fullDays), 2);
        }

        return $PV;
    }

    public function getEV($projectID, $begin, $end)
    {
        $tasks = $this->dao->select('*')->from(TABLE_TASK)
            ->where('estStarted')->ge($begin)
            ->andWhere('estStarted')->lt($end)
            ->andWhere('consumed')->gt(0)
            ->andWhere('status')->ne('cancel')
            ->andWhere('project')->in($projectID)
            ->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 += round($task->estimate * $task->progress / 100, 2);
            }   
        }   
        return $EV; 
    }

    public function getAC($projectID, $begin, $end)
    {
        $consumed = $this->dao->select('sum(t1.consumed) as consumed')
            ->from(TABLE_TASKESTIMATE)->alias('t1')
            ->leftJoin(TABLE_TASK)->alias('t2')->on('t1.task=t2.id')
            ->where('t1.date')->ge($begin)
            ->andWhere('t1.date')->lt($end)
            ->andWhere('t2.project')->in($projectID)
            ->fetch('consumed');
        if(!$consumed) $consumed = 0;

        return round($consumed, 2);
    }

    public function getProductQuality($programID, $projectID)
    {
        $productID = $this->loadModel('product')->getProductIDByProject($projectID);
        $stages    = $this->loadModel('programplan')->getPairs($programID, $productID);
        $reviews   = $this->loadModel('review')->getPairs($programID, $productID);
        unset($stages[0]);
        foreach($reviews as $reviewID => $review)
        {
            foreach($stages as $stageID => $stageName)
            {
                $productQuality['stages'][$stageID]['total'] = 0;
                $bugs = $this->dao->select("count(*) as bugs")->from(TABLE_BUG)
                    ->where('project')->eq($stageID)
                    ->andWhere('identify')->eq($reviewID)
                    ->andWhere('resolution')->notin('bydesign,duplicate,notrepro,willnotfix')
                    ->andWhere('deleted')->eq(0)
                    ->fetch('bugs');

                $issues = $this->dao->select("count(*) as issues")->from(TABLE_REVIEWISSUE)
                    ->where('injection')->eq($stageID)
                    ->andWhere('review')->eq($reviewID)
                    ->andWhere('resolution')->notin('bydesign,duplicate,notrepro,willnotfix')
                    ->andWhere('deleted')->eq(0)
                    ->fetch('issues');

                $productQuality['stages'][$stageID]['name']   = $stageName;
                $productQuality['stages'][$stageID][$reviewID]['counts'] = ($bugs + $issues)  == 0 ? '' : (int)($bugs + $issues);
                //$productQuality['stages'][$stageID]['estimate'] = $this->dao->select('estimate')->from(TABLE_PROJECT)->where('id')->eq($stageID)->fetch('estimate');
            }
        }

        if(isset($productQuality['stages']))
            foreach($productQuality['stages'] as $stageID => $stages)
            {
                $total = 0;
                foreach($stages as $reviewID => $stage) $total += (int) zget($stage, 'counts', 0);
                $productQuality['stages'][$stageID]['total'] = $total;
            }

        $productQuality['reviews'] = $reviews;
        return $productQuality;
    }

    public function getWorkhours($programID, $projectID)
    {   
        $productID = $this->loadModel('product')->getProductIDByProject($projectID);
        $stages    = $this->loadModel('programplan')->getPairs($programID, $productID);
        unset($stages[0]);
        $dev    = 0;
        $to     = 0;
        $review = 0;
        $qa     = 0;
        foreach($stages as $stageID => $stageName)
        {
            $workhours[$stageID]['name']     = $stageName;    
            $workhours[$stageID]['dev']      = $this->getWorkhourByType($stageID, 'devel');    
            $workhours[$stageID]['to']       = $this->getTo($stageID);    
            $workhours[$stageID]['review']   = $this->getReviewHours($stageID, $projectID);
            $workhours[$stageID]['qa']       = $this->getWorkhourByType($stageID, 'test');;    
            $workhours[$stageID]['count']    = $workhours[$stageID]['dev'] + $workhours[$stageID]['to'] + $workhours[$stageID]['review'] + $workhours[$stageID]['qa'];  
            $workhours[$stageID]['qaToDev']  = ($workhours[$stageID]['dev'] + $workhours[$stageID]['to']) == 0 ? 0 : round($workhours[$stageID]['qa'] / ($workhours[$stageID]['dev'] + $workhours[$stageID]['to']), 2);

            $dev    += $workhours[$stageID]['dev'];
            $to     += $workhours[$stageID]['to'];
            $review += $workhours[$stageID]['review'];
            $qa     += $workhours[$stageID]['qa'];
        }

        $workhours['count']['dev']    = $dev;
        $workhours['count']['to']     = $to;
        $workhours['count']['review'] = $review;
        $workhours['count']['qa']     = $qa;
        $workhours['count']['total']  = $dev + $to + $review + $qa;

        return $workhours;
    }

    public function getWorkhourByType($stageID, $type)
    {
        $consumed = $this->dao->select('sum(consumed) as consumed')->from(TABLE_TASK)->where('project')->eq($stageID)->andWhere('type')->eq($type)->fetch('consumed'); 
        return round($consumed, 2);
    }

    public function getReviewHours($stageID, $projectID = 0)
    {
        $productID = $this->loadModel('product')->getProductIDByProject($projectID);
        $stage     = $this->loadModel('programplan')->getByID($stageID);
        $consumed  = 0;
        $consumed += $this->getWorkhourByType($stageID, 'review');
        $attribute = isset($this->config->milestone->{$stage->attribute}) ? $this->config->milestone->{$stage->attribute} : '';

        $reviewConsumed = $this->dao->select('sum(t1.consumed) as consumed')->from(TABLE_REVIEWRESULT)->alias('t1')
            ->leftJoin(TABLE_REVIEW)->alias('t2')->on('t1.review=t2.id')
            ->leftJoin(TABLE_OBJECT)->alias('t3')->on('t2.object=t3.id')
            ->where('t3.category')->in($attribute)
            ->andWhere('t3.product')->eq($productID)
            ->fetch('consumed');

        $consumed += $reviewConsumed;
        return round($consumed, 2);
    }

    public function getTo($stageID)
    {
        $tasks = $this->dao->select('id, activatedDate')->from(TABLE_TASK)->where('project')->eq($stageID)->andWhere('activatedDate')->ne('0000-00-00')->fetchPairs(); 
        $to = 0;
        foreach($tasks as $taskID => $activatedDate)
        {
            $consumed = $this->dao->select('sum(consumed) as consumed')->from(TABLE_TASKESTIMATE)
                ->where('task')->eq($taskID) 
                ->andWhere('date')->ge($activatedDate) 
                ->fetch('consumed');
            $to += $consumed;
        }

        return round($to, 2);
    }

    public function getProjectRisk($programID)
    {
        return $this->dao->select('*,riskindex * 1 as riskindex')->from(TABLE_RISK)
            ->where('status')->eq('active')
            ->andWhere('program')->eq($programID)
            ->andWhere('deleted')->eq(0)
            ->orderBy('riskindex_desc')
            ->limit(5)
            ->fetchAll();
    }

    public function getStageDemand($programID, $projectID, $productID, $stageList = array())
    {
        $productList = array();
        foreach($stageList as $stageID => $name) $productList[$stageID] = $productID;
        $stages = $this->loadModel('programplan')->getPlans($programID, $productID);

        $originStory = array();
        $afterStory  = array();
        $changeStory = array();

        foreach($stages as $id => $stage)
        {
            $productID = $productList[$id];
            if($productID === 0) continue;

            $originStory[$id] = $this->dao->select('count(id) as total')->from(TABLE_STORY)
                ->where('product')->eq($productID)
                ->andWhere('type')->eq('requirement')
                ->andWhere('openedDate')->between($stage->begin, $stage->end)
                ->fetch('total');

            $afterStory[$id] = $this->dao->select('count(id) as total')->from(TABLE_STORY)
                ->where('product')->eq($productID)
                ->andWhere('type')->eq('requirement')
                ->andWhere('openedDate')->between($stage->begin, $stage->end)
                ->andWhere('deleted')->eq(0)
                ->fetch('total');

            $sql  = 'select count(id) as total from ' . TABLE_STORY;
            $sql .= ' where (product = ' . $productID . ' and type = "requirement" and openedDate between "' . $stage->begin . '" and "' . $stage->end . '" and deleted = "1")';
            $sql .= ' or (product = ' . $productID . ' and type = "requirement" and openedDate between "' . $stage->begin . '" and "' . $stage->end . '" and version > 1)';
            $changeStory[$id] = $this->dao->query($sql)->fetch();

            foreach($stage->children as $stage)
            {
                $id        = $stage->id;
                $productID = $productList[$id];
                if($productID === 0) continue;

                $originStory[$id] = $this->dao->select('count(id) as total')->from(TABLE_STORY)
                    ->where('product')->eq($productID)
                    ->andWhere('type')->eq('requirement')
                    ->andWhere('openedDate')->between($stage->begin, $stage->end)
                    ->fetch('total');

                $afterStory[$id] = $this->dao->select('count(id) as total')->from(TABLE_STORY)
                    ->where('product')->eq($productID)
                    ->andWhere('type')->eq('requirement')
                    ->andWhere('openedDate')->between($stage->begin, $stage->end)
                    ->andWhere('deleted')->eq(0)
                    ->fetch('total');

                $sql  = 'select count(id) as total from ' . TABLE_STORY;
                $sql .= ' where (product = ' . $productID . ' and type = "requirement" and openedDate between "' . $stage->begin . '" and "' . $stage->end . '" and deleted = "1")';
                $sql .= ' or (product = ' . $productID . ' and type = "requirement" and openedDate between "' . $stage->begin . '" and "' . $stage->end . '" and version > 1)';
                $changeStory[$id] = $this->dao->query($sql)->fetch();
            }
        }

        $stageInfo = array('origin' => array(), 'after' => array(), 'change' => array());
        $beginID   = 0;

        foreach($stageList as $key => $stage)
        {
            $beginID === 0 ? $stageInfo['origin'][$key] = $originStory[$key] :  $stageInfo['origin'][$key] = $afterStory[$beginID];
            $stageInfo['after'][$key]  = $afterStory[$key];
            $stageInfo['change'][$key] = $changeStory[$key]->total;
            $beginID = $key;
        }

        return $stageInfo;
    }

    public function getMeasures($programID, $projectID)
    {
        if(empty($projectID)) return array();
        return $this->dao->select('id,contents')->from(TABLE_SOLUTIONS)
            ->where('program')->eq($programID)
            ->andWhere('project')->eq($projectID)
            ->andWhere('type')->eq('measures')
            ->andWhere('deleted')->eq(0)
            ->fetchPairs('id', 'contents');
    }

    public function ajaxAddMeasures($data)
    {
        $this->dao->update(TABLE_SOLUTIONS)
            ->set('deleted')->eq(1)
            ->where('program')->eq($data->programID)
            ->andWhere('project')->eq($data->projectID)
            ->andWhere('type')->eq('measures')
            ->exec();

        foreach($data->measures as $item)
        {
            $item = trim($item);
            if(empty($item)) continue;

            $addData = new stdClass();
            $addData->program   = $data->programID;
            $addData->project   = $data->projectID;
            $addData->contents  = $item;
            $addData->type      = 'measures';
            $addData->addedBy   = $this->app->user->account;
            $addData->addedDate = helper::now();
            $addData->deleted   = 0;

            $this->dao->insert(TABLE_SOLUTIONS)->data($addData)->autoCheck()->exec();
        }
        return 1;
    }

    public function saveOtherProblem()
    {
        $data = fixer::input('post')->get();

        $this->dao->update(TABLE_SOLUTIONS)
            ->set('deleted')->eq(1)
            ->where('program')->eq($data->programID)
            ->andWhere('project')->eq($data->projectID)
            ->andWhere('type')->eq('otherproblem')
            ->exec();

        foreach($data->contents as $key => $contents){
            $addData = new stdClass();
            $addData->program   = $data->programID;
            $addData->project   = $data->projectID;
            $addData->contents  = $contents;
            $addData->support   = $data->support[$key];
            $addData->measures  = $data->measures[$key];
            $addData->type      = 'otherproblem';
            $addData->addedBy   = $this->app->user->account;
            $addData->addedDate = helper::now();
            $addData->deleted   = 0;

            $this->dao->insert(TABLE_SOLUTIONS)->data($addData)->autoCheck()->exec();   
        }  
    }

    public function otherProblemsList($programID,$projectID)
    {
        $list = $this->dao->select('*')
            ->from(TABLE_SOLUTIONS)
            ->where('program')->eq($programID)
            ->andWhere('project')->eq($projectID)
            ->andWhere('type')->eq('otherproblem')
            ->andWhere('deleted')->eq(0)
            ->fetchAll();

        return $list;
   }

    public function getNextMilestone($programID, $projectID, $stageList)
    {
        $nextID = $this->dao->select('min(id) as id')->from(TABLE_PROJECT)
            ->where('id')->gt($projectID)
            ->andWhere('program')->eq($programID)
            ->andWhere('milestone')->eq(1)
            ->fetch('id');

        $stageID = array_keys($stageList);
        $nextID  = in_array($nextID, $stageID) ? $nextID : 0;

        $totalDays = $this->dao->select('sum(days) as days')->from(TABLE_PROJECT)
            ->where('id')->in($stageID)
            ->andWhere('program')->eq($programID)
            ->andWhere('deleted')->eq(0)
            ->fetch('days');

        $totalHours = $this->dao->select('sum(days * hours) as totalHours')->from(TABLE_TEAM)
            ->where('root')->in($stageID)
            ->fetch('totalHours');

        $nextHours = 0;
        $nextDays  = 0;
        if($nextID)
        {
            $nextDays = $this->dao->select('days')->from(TABLE_PROJECT)
                ->where('id')->eq($nextID)
                ->andWhere('program')->eq($programID)
                ->andWhere('deleted')->eq(0)
                ->fetch('days');

            $nextHours = $this->dao->select('sum(days * hours) as totalHours')->from(TABLE_TEAM)
                ->where('root')->eq($nextID)
                ->fetch('totalHours');
        }

        $result             = new stdClass();
        $result->nextDays   = empty($nextDays)   ? 0 : $nextDays;
        $result->nextHours  = empty($nextHours)  ? 0 : $nextHours;
        $result->totalDays  = empty($totalDays)  ? 0 : $totalDays;
        $result->totalHours = empty($totalHours) ? 0 : $totalHours;
        return $result;
    }

    public function ajaxSaveEstimate($taskID,$estimate)
    {
        $this->dao->update(TABLE_PROJECT)
            ->set('estimate')
            ->eq($estimate)
            ->where('id')->eq($taskID)
            ->exec();

        if(dao::isError())
        {
            echo js::error(dao::getError());
        }
    }
}
