/** * Saves/modifies/deletes notifications * * @param int $subjectType Notification subject type * @param array $settings Array of notifications to create/modify * @param string $projectId optional Projects id. * @throws \Scalr\Exception\ModelException */ protected function saveNotifications($subjectType, $settings, $projectId = null) { $uuids = []; foreach ($settings['items'] as $item) { $notification = new NotificationEntity(); if ($item['uuid']) { $notification->findPk($item['uuid']); if (!$notification->hasAccessPermissions($this->getUser())) { continue; } } $notification->subjectType = $subjectType; $notification->subjectId = $item['subjectId'] ? $item['subjectId'] : null; $notification->notificationType = $item['notificationType']; $notification->threshold = $item['threshold']; $notification->recipientType = $item['recipientType']; $notification->emails = $item['emails']; $notification->status = $item['status']; $notification->save(); $uuids[] = $notification->uuid; } $criteria = [['subjectType' => $subjectType], ['accountId' => null]]; if ($projectId) { $criteria[] = ['subjectId' => $projectId]; } foreach (NotificationEntity::find($criteria) as $notification) { /* @var $notification NotificationEntity */ if (!in_array($notification->uuid, $uuids) && $notification->hasAccessPermissions($this->getUser())) { $notification->delete(); } } }
private function saveNotifications($id, $subjectType, $settings) { SettingEntity::setValue($id, $settings['enabled']); $uuids = array(); foreach ($settings['items'] as $item) { $notification = new NotificationEntity(); if ($item['uuid']) { $notification->findPk($item['uuid']); } $notification->subjectType = $subjectType; $notification->notificationType = $item['notificationType']; $notification->threshold = $item['threshold']; $notification->recipientType = $item['recipientType']; $notification->emails = $item['emails']; $notification->save(); $uuids[] = $notification->uuid; } foreach (NotificationEntity::findBySubjectType($subjectType) as $notification) { if (!in_array($notification->uuid, $uuids)) { $notification->delete(); } } }
/** * @param JsonData $notifications */ public function xSaveAction(JsonData $notifications) { $data = []; foreach ($notifications as $id => $settings) { if ($id == 'reports') { $this->saveReports($settings); $data[$id] = ReportEntity::find([['accountId' => null]])->getArrayCopy(); } elseif ($id == 'notifications.ccs') { $this->saveNotifications(NotificationEntity::SUBJECT_TYPE_CC, $settings); $data[$id] = NotificationEntity::findBySubjectType(NotificationEntity::SUBJECT_TYPE_CC)->getArrayCopy(); } elseif ($id == 'notifications.projects') { $this->saveNotifications(NotificationEntity::SUBJECT_TYPE_PROJECT, $settings); $data[$id] = NotificationEntity::find([['accountId' => null], ['subjectType' => NotificationEntity::SUBJECT_TYPE_PROJECT]])->getArrayCopy(); } } $this->response->data($data); $this->response->success('Notifications successfully saved'); }
/** * @param JsonData $notifications */ public function xSaveAction(JsonData $notifications) { $data = []; $projects = []; foreach ($this->getContainer()->analytics->projects->getAccountProjects($this->user->getAccountId()) as $project) { /* @var $project ProjectEntity */ if (!$project->archived && $project->shared === ProjectEntity::SHARED_WITHIN_ACCOUNT) { $projects[$project->projectId] = $project->name; } } foreach ($notifications as $id => $settings) { if ($id == 'reports') { $this->saveReports($settings); $data[$id] = ReportEntity::find([['subjectType' => ReportEntity::SUBJECT_TYPE_PROJECT], ['$or' => [['subjectId' => ['$in' => array_keys($projects)]], ['subjectId' => null]]]])->getArrayCopy(); } elseif ($id == 'notifications.projects') { $this->saveNotifications(NotificationEntity::SUBJECT_TYPE_PROJECT, $settings); $data[$id] = NotificationEntity::find([['subjectType' => NotificationEntity::SUBJECT_TYPE_PROJECT], ['$or' => [['subjectId' => ['$in' => array_keys($projects)]], ['subjectId' => null]]]])->getArrayCopy(); } } $this->response->data($data); $this->response->success('Notifications successfully saved'); }
/** * @param string $ccId * @param string $subjectType * @param array $settings * @throws \Scalr\Exception\ModelException */ private function saveNotifications($ccId, $subjectType, $settings) { $uuids = array(); foreach ($settings['items'] as $item) { $notification = new NotificationEntity(); if ($item['uuid']) { $notification->findPk($item['uuid']); } $notification->subjectType = $subjectType; $notification->subjectId = $ccId; $notification->notificationType = $item['notificationType']; $notification->threshold = $item['threshold']; $notification->recipientType = $item['recipientType']; $notification->emails = $item['emails']; $notification->status = $item['status']; $notification->save(); $uuids[] = $notification->uuid; } foreach (NotificationEntity::find([['subjectType' => NotificationEntity::SUBJECT_TYPE_CC], ['subjectId' => $ccId]]) as $notification) { if (!in_array($notification->uuid, $uuids)) { $notification->delete(); } } }
public function delete() { parent::delete(); ReportEntity::deleteByAccountId($this->id); NotificationEntity::deleteByAccountId($this->id); }
/** * {@inheritdoc} * @see \Scalr\Model\AbstractEntity::delete() */ public function delete() { if ($this->checkRemoval()) { //Completely remove it parent::delete(); ReportEntity::deleteBy([['subjectId' => $this->projectId], ['subjectType' => ReportEntity::SUBJECT_TYPE_PROJECT]]); NotificationEntity::deleteBy([['subjectId' => $this->projectId], ['subjectType' => NotificationEntity::SUBJECT_TYPE_PROJECT]]); } else { //Archive it $this->archived = true; $this->save(); } }
/** * {@inheritdoc} * @see \Scalr\System\Zmq\Cron\TaskInterface::enqueue() */ 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'; } } if (!empty($notification->subjectId)) { $subject = call_user_func($subjectEntityName . 'Entity::findPk', $notification->subjectId); $this->saveNotificationData($subject, $notification); } else { $subjects = call_user_func($subjectEntityName . 'Entity::find'); foreach ($subjects as $subject) { if ($subject->archived) { continue; } $this->saveNotificationData($subject, $notification); } } } $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()); $currentQuarter = $quarters->getQuarterForDate(new \DateTime('yesterday', new \DateTimeZone('UTC'))); $currentYear = (new \DateTime('yesterday', new \DateTimeZone('UTC')))->format('Y'); 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; $startForecast = $currentYear . '-01-01'; $endForecast = $currentYear . '-12-31'; $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()); $currentQuarter = $quarters->getQuarterForDate(new \DateTime($start, new \DateTimeZone('UTC'))); $currentYear = (new \DateTime($start, new \DateTimeZone('UTC')))->format('Y'); $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 . '#/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); 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); } else { if (!empty($report->subjectType)) { $subjects = call_user_func($subjectEntityName . 'Entity::find'); foreach ($subjects as $subject) { if ($subject->archived) { 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); } } } } $this->getLogger()->info('Done'); return new ArrayObject(); }
/** * {@inheritdoc} * @see Scalr_Model::delete() */ public function delete($id = null) { $servers = \DBServer::listByFilter(['clientId' => $this->id]); foreach ($servers as $server) { /* @var $server \DBServer */ $server->Remove(); } try { $this->db->StartTrans(); //TODO: Use models $this->db->Execute("\n DELETE account_team_users FROM account_team_users, account_teams\n WHERE account_teams.account_id = ?\n AND account_team_users.team_id = account_teams.id\n ", array($this->id)); $this->db->Execute("DELETE FROM account_users WHERE account_id=?", array($this->id)); $this->db->Execute("DELETE FROM account_teams WHERE account_id=?", array($this->id)); $this->db->Execute("DELETE FROM account_limits WHERE account_id=?", array($this->id)); /* @var $environment Environment */ foreach (Environment::findByAccountId($this->id) as $environment) { $environment->delete(true); } CloudCredentials::deleteByAccountId($this->id); $this->db->Execute("\n DELETE account_team_user_acls FROM account_team_user_acls, acl_account_roles\n WHERE acl_account_roles.account_id = ?\n AND account_team_user_acls.account_role_id = acl_account_roles.account_role_id\n ", array($this->id)); $this->db->Execute("DELETE FROM acl_account_roles WHERE account_id=?", array($this->id)); $this->db->Execute("DELETE FROM ec2_ebs WHERE client_id=?", array($this->id)); $this->db->Execute("DELETE FROM apache_vhosts WHERE client_id=?", array($this->id)); $this->db->Execute("DELETE FROM scheduler WHERE account_id=?", array($this->id)); foreach ($this->db->Execute("SELECT id FROM farms WHERE clientid=?", [$this->id]) as $farm) { $this->db->Execute("DELETE FROM farms WHERE id=?", array($farm["id"])); $this->db->Execute("DELETE FROM farm_roles WHERE farmid=?", array($farm["id"])); $this->db->Execute("DELETE FROM elastic_ips WHERE farmid=?", array($farm["id"])); } $roles = $this->db->GetAll("SELECT id FROM roles WHERE client_id = '{$this->id}'"); foreach ($roles as $role) { $this->db->Execute("DELETE FROM roles WHERE id = ?", array($role['id'])); $this->db->Execute("DELETE FROM role_behaviors WHERE role_id = ?", array($role['id'])); $this->db->Execute("DELETE FROM role_images WHERE role_id = ?", array($role['id'])); $this->db->Execute("DELETE FROM role_properties WHERE role_id = ?", array($role['id'])); $this->db->Execute("DELETE FROM role_security_rules WHERE role_id = ?", array($role['id'])); } //Removing cost centres and projects which are set up from this account $this->db->Execute("\n DELETE project_properties FROM project_properties, projects\n WHERE projects.project_id = project_properties.project_id\n AND projects.account_id = ?\n ", [$this->id]); $this->db->Execute("DELETE FROM projects WHERE account_id = ?", [$this->id]); $this->db->Execute("\n DELETE cc_properties FROM cc_properties, ccs\n WHERE ccs.cc_id = cc_properties.cc_id\n AND ccs.account_id = ?\n ", [$this->id]); $this->db->Execute("DELETE FROM ccs WHERE account_id = ?", [$this->id]); parent::delete(); ReportEntity::deleteByAccountId($this->id); NotificationEntity::deleteByAccountId($this->id); $this->db->CompleteTrans(); } catch (\Exception $e) { $this->db->RollbackTrans(); throw $e; } }
/** * @param string $projectId * @param JsonData $notifications * @throws Scalr_Exception_InsufficientPermissions */ public function xSaveNotificationsAction($projectId, JsonData $notifications) { $this->request->restrictAccess(Acl::RESOURCE_ANALYTICS_PROJECTS_ACCOUNT); $project = ProjectEntity::findPk($projectId); /* @var $project ProjectEntity */ if (!$project->hasAccessPermissions($this->getUser())) { throw new Scalr_Exception_InsufficientPermissions(); } $data = []; foreach ($notifications as $id => $settings) { if ($id == 'reports') { $this->saveReports($settings, $projectId); $data[$id] = ReportEntity::find([['subjectType' => ReportEntity::SUBJECT_TYPE_PROJECT], ['subjectId' => $projectId]])->getArrayCopy(); } elseif ($id == 'notifications.projects') { $this->saveNotifications(NotificationEntity::SUBJECT_TYPE_PROJECT, $settings, $projectId); $data[$id] = NotificationEntity::find([['subjectType' => NotificationEntity::SUBJECT_TYPE_PROJECT], ['subjectId' => $projectId]])->getArrayCopy(); } } $this->response->data($data); $this->response->success('Notifications successfully saved'); }
/** * {@inheritdoc} * @see \Scalr\System\Pcntl\ProcessInterface::OnStartForking() */ public function OnStartForking() { if (!\Scalr::getContainer()->analytics->enabled) { die("Terminating the process as Cost analytics is disabled in the config.\n"); } $this->console->out("%s (UTC) Start Analytics Notifications process", gmdate('Y-m-d')); if (SettingEntity::getValue(SettingEntity::ID_NOTIFICATIONS_CCS_ENABLED) || SettingEntity::getValue(SettingEntity::ID_NOTIFICATIONS_PROJECTS_ENABLED)) { $this->console->out('Calculating data for projects notifications'); $quarters = new Quarters(SettingEntity::getQuarters()); $date = $quarters->getPeriodForDate('yesterday'); $formatedTitle = 'Q' . $quarters->getQuarterForDate('now') . ' budget (' . (new \DateTime('now', new \DateTimeZone('UTC')))->format('M j, Y') . ')'; $projects = ProjectEntity::find(); foreach ($projects as $project) { $periodProjectData = \Scalr::getContainer()->analytics->usage->getProjectPeriodData($project->projectId, 'quarter', $date->start->format('Y-m-d'), $date->end->format('Y-m-d')); $projectAnalytics[$project->projectId] = ['budget' => $periodProjectData['totals']['budget'], 'name' => $project->name, 'trends' => $periodProjectData['totals']['trends'], 'forecastCost' => $periodProjectData['totals']['forecastCost'], 'interval' => $periodProjectData['interval'], 'jsonVersion' => '1.0.0', 'farms' => []]; if (!empty($periodProjectData['totals']['farms'])) { foreach ($periodProjectData['totals']['farms'] as $farm) { $projectAnalytics[$project->projectId]['farms'][] = ['id' => $farm['id'], 'name' => $farm['name'], 'median' => $farm['median'] / 7, 'cost' => $farm['cost'], 'costPct' => $farm['costPct']]; } if (count($projectAnalytics[$project->projectId]['farms'] > 1)) { usort($projectAnalytics[$project->projectId]['farms'], array($this, 'sortItems')); if (count($projectAnalytics[$project->projectId]['farms'] > 6)) { array_splice($projectAnalytics[$project->projectId]['farms'], 6, count($projectAnalytics[$project->projectId]['farms'])); } } } $projectAnalytics[$project->projectId]['date'] = $formatedTitle; if ($project->archived) { continue; } if (SettingEntity::getValue(SettingEntity::ID_NOTIFICATIONS_PROJECTS_ENABLED)) { $projectNotifications = NotificationEntity::findBySubjectType(NotificationEntity::SUBJECT_TYPE_PROJECT); foreach ($projectNotifications as $notification) { $this->saveNotificationData('project', $notification, $project->projectId, $projectAnalytics); } } } } if (SettingEntity::getValue(SettingEntity::ID_NOTIFICATIONS_CCS_ENABLED)) { $this->console->out('Calculating data for cost center notifications'); $ccs = CostCentreEntity::find(); foreach ($ccs as $cc) { if ($cc->archived) { continue; } $periodCostCenterData = \Scalr::getContainer()->analytics->usage->getCostCenterPeriodData($cc->ccId, 'quarter', $date->start->format('Y-m-d'), $date->end->format('Y-m-d')); $ccAnalytics[$cc->ccId] = ['budget' => $periodCostCenterData['totals']['budget'], 'name' => $cc->name, 'trends' => $periodCostCenterData['totals']['trends'], 'forecastCost' => $periodCostCenterData['totals']['forecastCost'], 'interval' => $periodCostCenterData['interval'], 'jsonVersion' => '1.0.0', 'projects' => []]; if (!empty($periodCostCenterData['totals']['projects'])) { foreach ($periodCostCenterData['totals']['projects'] as $key => $project) { if (!empty($project['id'])) { $projectBudget = $projectAnalytics[$project['id']]['budget']; $projectBudget['name'] = $project['name']; $projectBudget['id'] = $project['id']; $projectBudget['median'] = $project['median'] / 7; $ccAnalytics[$cc->ccId]['projects'][] = $projectBudget; } else { $otherProjectsKey = $key; } } if (isset($otherProjectsKey)) { $ccAnalytics[$cc->ccId]['projects'][] = ['id' => '', 'budgetSpent' => $periodCostCenterData['totals']['projects'][$otherProjectsKey]['cost'], 'median' => $periodCostCenterData['totals']['projects'][$otherProjectsKey]['median'] / 7, 'name' => $periodCostCenterData['totals']['projects'][$otherProjectsKey]['name'], 'estimateOverspend' => null]; unset($otherProjectsKey); } if (count($ccAnalytics[$cc->ccId]['projects'] > 1)) { usort($ccAnalytics[$cc->ccId]['projects'], array($this, 'sortItems')); if (count($ccAnalytics[$cc->ccId]['projects'] > 6)) { array_splice($ccAnalytics[$cc->ccId]['projects'], 6, count($ccAnalytics[$cc->ccId]['projects'])); } } } $ccAnalytics[$cc->ccId]['date'] = $formatedTitle; $ccsNotifications = NotificationEntity::findBySubjectType(NotificationEntity::SUBJECT_TYPE_CC); foreach ($ccsNotifications as $notification) { $this->saveNotificationData('cc', $notification, $cc->ccId, $ccAnalytics); } } } if (SettingEntity::getValue(SettingEntity::ID_REPORTS_ENABLED)) { $this->console->out('Calculating data for reports'); $reports = ReportEntity::find(); foreach ($reports as $report) { 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'); 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'); $quarters = new Quarters(SettingEntity::getQuarters()); $currentQuarter = $quarters->getQuarterForDate(new \DateTime($start, new \DateTimeZone('UTC'))); $currentYear = (new \DateTime($start, new \DateTimeZone('UTC')))->format('Y'); $date = $quarters->getPeriodForQuarter($currentQuarter, $currentYear); $formatedTitle = (new \DateTime($start, new \DateTimeZone('UTC')))->format('M Y'); $startForecast = $date->start->format('Y-m-d'); $endForecast = $date->end->format('Y-m-d'); $periodForecast = 'quarter'; break; case ReportEntity::PERIOD_QUARTELY: $period = 'quarter'; $quarters = new Quarters(SettingEntity::getQuarters()); $currentQuarter = $quarters->getQuarterForDate(new \DateTime('yesterday', new \DateTimeZone('UTC'))); $currentYear = (new \DateTime('yesterday', new \DateTimeZone('UTC')))->format('Y'); 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; $startForecast = $currentYear . '-01-01'; $endForecast = $currentYear . '-12-31'; $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'); $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'; break; } 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 { $periodData = \Scalr::getContainer()->analytics->usage->getDashboardPeriodData($period, $start, $end); $periodDataForecast = \Scalr::getContainer()->analytics->usage->getDashboardPeriodData($periodForecast, $startForecast, $endForecast); $periodData['period'] = $period; $periodData['forecastPeriod'] = $periodForecast; $periodData['totals']['forecastCost'] = $periodDataForecast['totals']['forecastCost']; $periodData['totals']['trends'] = $periodDataForecast['totals']['trends']; $periodData['name'] = 'Cloud Cost Report'; $periodData['jsonVersion'] = '1.0.0'; $periodData['totals']['clouds'] = $this->changeCloudNames($periodData['totals']['clouds']); $periodData['date'] = $formatedTitle; $periodData['totals']['budget']['budget'] = null; 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->console->out('Summary report email has been sent'); $payload['date'] = $entity->created->format('Y-m-d'); $entity->payload = json_encode($payload); $entity->save(); } } } unset($currentQuarter, $currentYear); 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); } else { if (!empty($report->subjectType)) { $subjects = call_user_func($subjectEntityName . 'Entity::find'); foreach ($subjects as $subject) { if ($subject->archived) { continue; } $this->saveReportData($getPeriodicSubjectData, $subjectEntityName, ['period' => $period, 'start' => $start, 'end' => $end], ['period' => $periodForecast, 'start' => $startForecast, 'end' => $endForecast], $subject->{$subjectId}, $report->subjectType, $report->emails, $formatedTitle); } } } } } $this->console->out('Done'); exit; }