public function enqueue()
{
if (!\Scalr::getContainer()->analytics->enabled) {
$this->getLogger()->info("Terminating the process as Cost analytics is disabled in the config.\n");
return new ArrayObject();
}
$this->getLogger()->info("%s (UTC) Start Analytics Notifications process", gmdate('Y-m-d'));
$notifications = NotificationEntity::find();
$this->getLogger()->info('Calculating data for projects and cost centers notifications');
foreach ($notifications as $notification) {
/* @var $notification NotificationEntity */
if ($notification->status === NotificationEntity::STATUS_DISABLED) {
continue;
}
if ($notification->subjectType === NotificationEntity::SUBJECT_TYPE_CC) {
$subjectEntityName = 'Scalr\\Stats\\CostAnalytics\\Entity\\CostCentre';
} else {
if ($notification->subjectType === NotificationEntity::SUBJECT_TYPE_PROJECT) {
$subjectEntityName = 'Scalr\\Stats\\CostAnalytics\\Entity\\Project';
}
}
$ifAccountLevel = !empty($notification->accountId) && $notification->subjectType === NotificationEntity::SUBJECT_TYPE_PROJECT;
if (!empty($notification->subjectId)) {
$subject = call_user_func($subjectEntityName . 'Entity::findPk', $notification->subjectId);
$this->saveNotificationData($subject, $notification, $ifAccountLevel);
} else {
if ($ifAccountLevel) {
$subjects = \Scalr::getContainer()->analytics->projects->getAccountProjects($notification->accountId);
} else {
$subjects = call_user_func($subjectEntityName . 'Entity::find');
}
foreach ($subjects as $subject) {
if ($subject->archived || $ifAccountLevel && $subject->shared !== ProjectEntity::SHARED_WITHIN_ACCOUNT) {
continue;
}
$this->saveNotificationData($subject, $notification, $ifAccountLevel);
}
}
}
$this->getLogger()->info('Calculating data for reports');
$reports = ReportEntity::find();
foreach ($reports as $report) {
/* @var $report ReportEntity */
if ($report->status === ReportEntity::STATUS_DISABLED) {
continue;
}
switch ($report->period) {
case ReportEntity::PERIOD_DAILY:
$period = 'custom';
$start = (new \DateTime('yesterday', new \DateTimeZone('UTC')))->format('Y-m-d');
$end = $start;
$startForecast = (new \DateTime('first day of this month', new \DateTimeZone('UTC')))->format('Y-m-d');
$endForecast = (new \DateTime('last day of this month', new \DateTimeZone('UTC')))->format('Y-m-d');
if ($startForecast == (new \DateTime('now', new \DateTimeZone('UTC')))->format('Y-m-d')) {
$startForecast = (new \DateTime('first day of last month', new \DateTimeZone('UTC')))->format('Y-m-d');
$endForecast = (new \DateTime('last day of last month', new \DateTimeZone('UTC')))->format('Y-m-d');
}
$periodForecast = 'month';
$formatedTitle = (new \DateTime($start, new \DateTimeZone('UTC')))->format('M j');
$formatedForecastDate = (new \DateTime($start, new \DateTimeZone('UTC')))->format('F');
break;
case ReportEntity::PERIOD_MONTHLY:
$period = 'month';
$start = (new \DateTime('first day of last month', new \DateTimeZone('UTC')))->format('Y-m-d');
$end = (new \DateTime('last day of last month', new \DateTimeZone('UTC')))->format('Y-m-d');
$formatedTitle = (new \DateTime($start, new \DateTimeZone('UTC')))->format('M Y');
break;
case ReportEntity::PERIOD_QUARTELY:
$period = 'quarter';
$quarters = new Quarters(SettingEntity::getQuarters());
$currentPeriod = $quarters->getPeriodForDate(new \DateTime('yesterday', new \DateTimeZone('UTC')));
$currentQuarter = $currentPeriod->quarter;
$currentYear = $currentPeriod->year;
if ($currentQuarter === 1) {
$quarter = 4;
$year = $currentYear - 1;
} else {
$quarter = $currentQuarter - 1;
$year = $currentYear;
}
$date = $quarters->getPeriodForQuarter($quarter, $year);
$start = $date->start->format('Y-m-d');
$end = $date->end->format('Y-m-d');
$formatedTitle = 'Q' . $quarter . ' ' . $year;
$formatedForecastDate = 'End of ' . $currentYear;
$forecastPeriod = $quarters->getPeriodForYear($year);
$startForecast = $forecastPeriod->start->format('Y-m-d');
$endForecast = $forecastPeriod->end->format('Y-m-d');
$periodForecast = 'year';
break;
case ReportEntity::PERIOD_WEEKLY:
$period = 'week';
$end = (new \DateTime('yesterday', new \DateTimeZone('UTC')))->modify('last saturday')->format('Y-m-d');
$start = (new \DateTime($end, new \DateTimeZone('UTC')))->modify('last sunday')->format('Y-m-d');
$formatedTitle = (new \DateTime($start, new \DateTimeZone('UTC')))->format('M j') . ' - ' . (new \DateTime($end, new \DateTimeZone('UTC')))->format('M j');
break;
}
if ($report->period !== ReportEntity::PERIOD_DAILY && $report->period !== ReportEntity::PERIOD_QUARTELY) {
$quarters = new Quarters(SettingEntity::getQuarters());
$currentPeriod = $quarters->getPeriodForDate(new \DateTime($start, new \DateTimeZone('UTC')));
$currentQuarter = $currentPeriod->quarter;
$currentYear = $currentPeriod->year;
$date = $quarters->getPeriodForQuarter($currentQuarter, $currentYear);
$formatedForecastDate = 'End of Q' . $currentQuarter;
$startForecast = $date->start->format('Y-m-d');
$endForecast = $date->end->format('Y-m-d');
$periodForecast = 'quarter';
}
if ($report->subjectType === ReportEntity::SUBJECT_TYPE_CC) {
$getPeriodicSubjectData = 'getCostCenterPeriodData';
$subjectEntityName = 'Scalr\\Stats\\CostAnalytics\\Entity\\CostCentre';
$subjectId = 'ccId';
} else {
if ($report->subjectType === ReportEntity::SUBJECT_TYPE_PROJECT) {
$getPeriodicSubjectData = 'getProjectPeriodData';
$subjectEntityName = 'Scalr\\Stats\\CostAnalytics\\Entity\\Project';
$subjectId = 'projectId';
} else {
$baseUrl = rtrim(\Scalr::getContainer()->config('scalr.endpoint.scheme') . "://" . \Scalr::getContainer()->config('scalr.endpoint.host'), '/');
$periodData = \Scalr::getContainer()->analytics->usage->getDashboardPeriodData($period, $start, $end);
$periodDataForecast = \Scalr::getContainer()->analytics->usage->getDashboardPeriodData($periodForecast, $startForecast, $endForecast);
$periodData['period'] = $period;
$periodData['forecastPeriod'] = $formatedForecastDate;
$periodData['totals']['forecastCost'] = $periodDataForecast['totals']['forecastCost'];
$periodData['name'] = 'Cloud Cost Report';
$periodData['jsonVersion'] = '1.0.0';
$periodData['detailsUrl'] = $baseUrl . '#/admin/analytics/dashboard';
$periodData['totals']['clouds'] = $this->changeCloudNames($periodData['totals']['clouds']);
$periodData['date'] = $formatedTitle;
$periodData['totals']['budget']['budget'] = null;
if ($period !== 'custom') {
$periodData['totals']['prevPeriodDate'] = (new \DateTime($periodData['previousStartDate'], new \DateTimeZone('UTC')))->format('M d') . " - " . (new \DateTime($periodData['previousEndDate'], new \DateTimeZone('UTC')))->format('M d');
} else {
$periodData['totals']['prevPeriodDate'] = (new \DateTime($periodData['previousEndDate'], new \DateTimeZone('UTC')))->format('M d');
}
if ($period == 'quarter') {
$periodData['totals']['budget'] = ['quarter' => $quarter, 'year' => $year, 'quarterStartDate' => $start, 'quarterEndDate' => $end];
} else {
if ($period == 'month') {
$periodData['totals']['budget'] = ['quarter' => $currentQuarter];
}
}
unset($periodData['projects'], $periodData['budget']['projects']);
if (count($periodData['costcenters'] > 1)) {
uasort($periodData['costcenters'], array($this, 'sortItems'));
if (count($periodData['costcenters'] > 6)) {
array_splice($periodData['costcenters'], 6, count($periodData['costcenters']));
}
}
if (count($periodData['totals']['clouds'] > 1)) {
usort($periodData['totals']['clouds'], array($this, 'sortItems'));
}
$entity = ReportPayloadEntity::init([$report->subjectType, $report->subjectId, $period], $periodData, $start);
if (!ReportPayloadEntity::findPk($entity->uuid)) {
$payload = json_decode($entity->payload, true);
\Scalr::getContainer()->mailer->setSubject('Summary report.')->setContentType('text/html')->sendTemplate(SCALR_TEMPLATES_PATH . '/emails/report_summary.html.php', $payload, $report->emails);
$this->getLogger()->info('Summary report email has been sent');
$payload['date'] = $entity->created->format('Y-m-d');
$entity->payload = json_encode($payload);
$entity->save();
}
}
}
unset($currentQuarter, $currentYear);
$ifAccountLevel = !empty($report->accountId) && $report->subjectType === ReportEntity::SUBJECT_TYPE_PROJECT;
if (!empty($report->subjectType) && !empty($report->subjectId)) {
$subject = call_user_func($subjectEntityName . 'Entity::findPk', $report->subjectId);
if ($subject->archived) {
continue;
}
$this->saveReportData($getPeriodicSubjectData, $subjectEntityName, ['period' => $period, 'start' => $start, 'end' => $end], ['period' => $periodForecast, 'start' => $startForecast, 'end' => $endForecast], $report->subjectId, $report->subjectType, $report->emails, $formatedTitle, $formatedForecastDate, $ifAccountLevel);
} else {
if (!empty($report->subjectType)) {
if ($ifAccountLevel) {
$subjects = \Scalr::getContainer()->analytics->projects->getAccountProjects($report->accountId);
} else {
$subjects = call_user_func($subjectEntityName . 'Entity::find');
}
foreach ($subjects as $subject) {
if ($subject->archived || $ifAccountLevel && $subject->shared !== ProjectEntity::SHARED_WITHIN_ACCOUNT) {
continue;
}
$this->saveReportData($getPeriodicSubjectData, $subjectEntityName, ['period' => $period, 'start' => $start, 'end' => $end], ['period' => $periodForecast, 'start' => $startForecast, 'end' => $endForecast], $subject->{$subjectId}, $report->subjectType, $report->emails, $formatedTitle, $formatedForecastDate, $ifAccountLevel);
}
}
}
}
$this->getLogger()->info('Done');
return new ArrayObject();
}