public function getProjectMovingAverageToDate($projectId, $mode, $date, $startDate, $endDate, $ccId = null)
{
$projectId = empty($projectId) ? null : $projectId;
if (!preg_match('/^[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:00$/', $date)) {
throw new InvalidArgumentException(sprintf("Invalid date:%s. 'YYYY-MM-DD HH:00' is expected.", strip_tags($date)));
}
if (!preg_match('/^[[:xdigit:]-]{36}$/', $projectId)) {
throw new InvalidArgumentException(sprintf("Invalid identifier of the Project:%s. UUID is expected.", strip_tags($projectId)));
}
$iterator = ChartPeriodIterator::create($mode, $startDate, $endDate ?: null, 'UTC');
//Interval which is used in the database query for grouping
$queryInterval = preg_replace('/^1 /', '', $iterator->getInterval());
if ($projectId !== null) {
$project = ProjectEntity::findPk($projectId);
if ($project === null) {
if (empty($ccId)) {
throw new AnalyticsException(sprintf("Project %s does not exist. Please provide ccId.", $projectId));
}
} else {
$ccId = $project->ccId;
}
}
$data = $this->getRollingAvg(['projectId' => $projectId], $queryInterval, $date);
$data['budgetUseToDate'] = null;
$data['budgetUseToDatePct'] = null;
//Does not calculate budget use to date for those cases
if ($mode != 'custom' && $mode != 'year') {
$pointPosition = $iterator->searchPoint($date);
if ($pointPosition !== false) {
$chartPoint = $iterator->current();
//Gets the end date of the selected interval
$end = clone $chartPoint->dt;
if ($chartPoint->interval != '1 day') {
$end->modify("+" . $chartPoint->interval . " -1 day");
}
//Gets quarters config
$quarters = new Quarters(SettingEntity::getQuarters());
//Gets start and end of the quarter for the end date of the current interval
$period = $quarters->getPeriodForDate($end);
$data['year'] = $period->year;
$data['quarter'] = $period->quarter;
$data['quarterStartDate'] = $period->start->format('Y-m-d');
$data['quarterEndDate'] = $period->end->format('Y-m-d');
//Gets budgeted cost
$budget = current(QuarterlyBudgetEntity::getProjectBudget($period->year, $projectId)->filterByQuarter($period->quarter));
//If budget has not been set we should not calculate anything
if ($budget instanceof QuarterlyBudgetEntity && round($budget->budget) > 0) {
$data['budget'] = round($budget->budget);
//Calculates usage from the start date of the quarter to date
$usage = $this->get(['projectId' => $projectId], $period->start, $end);
$data['budgetUseToDate'] = $usage['cost'];
$data['budgetUseToDatePct'] = $data['budget'] == 0 ? null : min(100, round($usage['cost'] / $data['budget'] * 100));
}
}
}
return ['data' => $data];
}