Пример #1
0
 /**
  * Gets a list of environments by key
  *
  * @param  string $query Search query
  * @return array  Returns array of environments
  */
 private function getEnvironmentsList($query = null)
 {
     $envs = [];
     $environments = $this->user->getEnvironments($query);
     if (count($environments) > 0) {
         $iterator = ChartPeriodIterator::create('month', gmdate('Y-m-01'), null, 'UTC');
         //It calculates usage for all provided enviroments
         $usage = $this->getContainer()->analytics->usage->getFarmData($this->user->getAccountId(), [], $iterator->getStart(), $iterator->getEnd(), [TagEntity::TAG_ID_ENVIRONMENT, TagEntity::TAG_ID_FARM]);
         //It calculates usage for previous period same days
         $prevusage = $this->getContainer()->analytics->usage->getFarmData($this->user->getAccountId(), [], $iterator->getPreviousStart(), $iterator->getPreviousEnd(), [TagEntity::TAG_ID_ENVIRONMENT, TagEntity::TAG_ID_FARM]);
         foreach ($environments as $env) {
             if (isset($usage['data'][$env['id']]['data'])) {
                 $envs[$env['id']]['topSpender'] = $this->getFarmTopSpender($usage['data'][$env['id']]['data']);
             } else {
                 $envs[$env['id']]['topSpender'] = null;
             }
             $envs[$env['id']]['name'] = $env['name'];
             $envs[$env['id']]['envId'] = $env['id'];
             $ccId = \Scalr_Environment::init()->loadById($env['id'])->getPlatformConfigValue(\Scalr_Environment::SETTING_CC_ID);
             if (!empty($ccId)) {
                 $envs[$env['id']]['ccId'] = $ccId;
                 $envs[$env['id']]['ccName'] = CostCentreEntity::findPk($ccId)->name;
             }
             $totalCost = round(isset($usage['data'][$env['id']]) ? $usage['data'][$env['id']]['cost'] : 0, 2);
             $prevCost = round(isset($prevusage['data'][$env['id']]) ? $prevusage['data'][$env['id']]['cost'] : 0, 2);
             $envs[$env['id']] = $this->getWrappedUsageData(['iterator' => $iterator, 'usage' => $totalCost, 'prevusage' => $prevCost]) + $envs[$env['id']];
         }
     }
     return array_values($envs);
 }
Пример #2
0
 /**
  * Gets specified Script taking into account both scope and authentication token
  *
  * @param   string  $ccId  Unique identifier of the Cost-Center
  *
  * @return CostCentreEntity Returns the Project Entity on success
  *
  * @throws ApiErrorException
  *
  */
 public function getCostCenter($ccId)
 {
     /* @var $cc CostCentreEntity */
     $cc = CostCentreEntity::findPk($ccId);
     if (!$cc) {
         throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, "Requested Cost Center either does not exist or is not owned by your environment.");
     }
     if (!$this->hasPermissions($cc)) {
         //Checks entity level write access permissions
         throw new ApiErrorException(403, ErrorMessage::ERR_PERMISSION_VIOLATION, "Insufficient permissions");
     }
     return $cc;
 }
Пример #3
0
 /**
  * @test
  */
 public function textComplex()
 {
     $ccs = $this->listCostCenters();
     $adapter = $this->getAdapter('costCenter');
     foreach ($ccs as $cc) {
         foreach ($adapter->getRules()[ApiEntityAdapter::RULE_TYPE_FILTERABLE] as $property) {
             foreach ($this->listCostCenters([$property => $cc->{$property}]) as $filteredProject) {
                 $this->assertEquals($cc->{$property}, $filteredProject->{$property});
             }
         }
         $response = $this->getCostCenter($cc->id);
         $this->assertEquals(200, $response->status, $this->printResponseError($response));
         $dbProject = CostCentreEntity::findPk($cc->id);
         $this->assertObjectEqualsEntity($response->getBody()->data, $dbProject, $adapter);
     }
 }
Пример #4
0
 /**
  * Edit project action
  *
  * @param string $projectId
  * @throws Scalr_UI_Exception_NotFound
  */
 public function editAction($projectId = null)
 {
     $scope = $this->request->getScope();
     $this->request->restrictAccess(Acl::RESOURCE_ANALYTICS_ACCOUNT, Acl::PERM_ANALYTICS_ACCOUNT_MANAGE_PROJECTS);
     if (!empty($projectId)) {
         $project = $this->getContainer()->analytics->projects->get($projectId);
         if ($project->shared != ProjectEntity::SHARED_WITHIN_ACCOUNT || $project->accountId != $this->user->getAccountId()) {
             throw new Scalr_Exception_InsufficientPermissions();
         }
         $cc = $project->getCostCenter();
         $projectData = $this->getProjectData($project, true);
         //Check whether it can be removed
         try {
             $projectData['removable'] = $project->checkRemoval();
         } catch (AnalyticsException $e) {
             $projectData['removable'] = false;
             $projectData['warning'] = $e->getMessage();
         }
     } else {
         if ($scope == 'environment') {
             $cc = $this->getContainer()->analytics->ccs->get($this->getEnvironment()->getPlatformConfigValue(\Scalr_Environment::SETTING_CC_ID));
         }
         $projectData = [];
     }
     $ccs = [];
     if ($scope == 'environment') {
         $accountCcs = AccountCostCenterEntity::findOne([['accountId' => $this->user->getAccountId()], ['ccId' => $cc->ccId]]);
         if ($accountCcs instanceof AccountCostCenterEntity) {
             $ccs[$cc->ccId] = ['ccId' => $cc->ccId, 'name' => $cc->name, 'billingCode' => $cc->getProperty(CostCentrePropertyEntity::NAME_BILLING_CODE)];
         }
     } elseif ($scope == 'account') {
         foreach ($this->user->getEnvironments() as $row) {
             $env = \Scalr_Environment::init()->loadById($row['id']);
             $ccEntity = CostCentreEntity::findPk($env->getPlatformConfigValue(\Scalr_Environment::SETTING_CC_ID));
             /* @var $ccEntity \Scalr\Stats\CostAnalytics\Entity\CostCentreEntity */
             if ($ccEntity) {
                 $accountCcs = AccountCostCenterEntity::findOne([['accountId' => $env->clientId], ['ccId' => $ccEntity->ccId]]);
                 if ($accountCcs instanceof AccountCostCenterEntity) {
                     $ccs[$ccEntity->ccId] = ['ccId' => $ccEntity->ccId, 'name' => $ccEntity->name, 'billingCode' => $ccEntity->getProperty(CostCentrePropertyEntity::NAME_BILLING_CODE)];
                 }
             }
         }
     }
     $this->response->page('ui/admin/analytics/projects/edit.js', array('project' => $projectData, 'ccs' => $ccs, 'scope' => 'account'));
 }
Пример #5
0
 /**
  * Gets specified Script taking into account both scope and authentication token
  *
  * @param   string  $ccId  Unique identifier of the Cost-Center
  *
  * @return CostCentreEntity Returns the Project Entity on success
  *
  * @throws ApiErrorException
  *
  */
 public function getCostCenter($ccId)
 {
     //TODO: correct ACL resource
     $this->checkPermissions(Acl::RESOURCE_ANALYTICS_PROJECTS);
     if ($ccId != $this->getEnvironmentCostCenterId()) {
         throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, "Requested Cost Center either does not exist or is not owned by your environment.");
     }
     /* @var $cc CostCentreEntity */
     $cc = CostCentreEntity::findPk($ccId);
     if (!$cc) {
         throw new ApiErrorException(404, ErrorMessage::ERR_OBJECT_NOT_FOUND, "Requested Cost Center either does not exist or is not owned by your environment.");
     }
     if (!$this->hasPermissions($cc)) {
         //Checks entity level write access permissions
         throw new ApiErrorException(403, ErrorMessage::ERR_PERMISSION_VIOLATION, "Insufficient permissions");
     }
     return $cc;
 }
Пример #6
0
 public function applyGlobalVarsToValue($value)
 {
     if (empty($this->globalVariablesCache)) {
         $formats = \Scalr::config("scalr.system.global_variables.format");
         $at = new Entity\Account\Team();
         $ft = new Entity\FarmTeam();
         $teams = Entity\Account\Team::find([\Scalr\Model\AbstractEntity::STMT_FROM => "{$at->table()} JOIN {$ft->table()} ON {$ft->columnTeamId} = {$at->columnId}", \Scalr\Model\AbstractEntity::STMT_WHERE => "{$ft->columnFarmId} = '{$this->ID}'"])->map(function ($t) {
             return $t->name;
         });
         $systemVars = array('env_id' => $this->EnvID, 'env_name' => $this->GetEnvironmentObject()->name, 'farm_team' => join(",", $teams), 'farm_id' => $this->ID, 'farm_name' => $this->Name, 'farm_hash' => $this->Hash, 'farm_owner_email' => $this->createdByUserEmail);
         if (\Scalr::getContainer()->analytics->enabled) {
             $projectId = $this->GetSetting(Entity\FarmSetting::PROJECT_ID);
             if ($projectId) {
                 $project = ProjectEntity::findPk($projectId);
                 /* @var $project ProjectEntity */
                 $systemVars['project_id'] = $projectId;
                 $systemVars['project_bc'] = $project->getProperty(ProjectPropertyEntity::NAME_BILLING_CODE);
                 $systemVars['project_name'] = $project->name;
                 $ccId = $project->ccId;
             }
             if ($ccId) {
                 $cc = CostCentreEntity::findPk($ccId);
                 if ($cc) {
                     /* @var $cc CostCentreEntity */
                     $systemVars['cost_center_id'] = $ccId;
                     $systemVars['cost_center_bc'] = $cc->getProperty(CostCentrePropertyEntity::NAME_BILLING_CODE);
                     $systemVars['cost_center_name'] = $cc->name;
                 } else {
                     throw new Exception("Cost center {$ccId} not found");
                 }
             }
         }
         // Get list of Server system vars
         foreach ($systemVars as $name => $val) {
             $name = "SCALR_" . strtoupper($name);
             $val = trim($val);
             if (isset($formats[$name])) {
                 $val = @sprintf($formats[$name], $val);
             }
             $this->globalVariablesCache[$name] = $val;
         }
         // Add custom variables
         $gv = new Scalr_Scripting_GlobalVariables($this->ClientID, $this->EnvID, ScopeInterface::SCOPE_FARM);
         $vars = $gv->listVariables(0, $this->ID);
         foreach ($vars as $v) {
             $this->globalVariablesCache[$v['name']] = $v['value'];
         }
     }
     //Parse variable
     $keys = array_keys($this->globalVariablesCache);
     $keys = array_map(function ($item) {
         return '{' . $item . '}';
     }, $keys);
     $values = array_values($this->globalVariablesCache);
     $retval = str_replace($keys, $values, $value);
     // Strip undefined variables & return value
     return preg_replace("/{[A-Za-z0-9_-]+}/", "", $retval);
 }
Пример #7
0
 /**
  *
  * @return array
  */
 public function GetScriptingVars()
 {
     $dbFarmRole = $this->GetFarmRoleObject();
     $roleId = $dbFarmRole->RoleID;
     $dbRole = DBRole::loadById($roleId);
     $isDbMsr = $dbRole->getDbMsrBehavior();
     if ($isDbMsr) {
         $isMaster = $this->GetProperty(Scalr_Db_Msr::REPLICATION_MASTER);
     } else {
         $isMaster = $this->GetProperty(\SERVER_PROPERTIES::DB_MYSQL_MASTER);
     }
     $retval = array('image_id' => $dbRole->__getNewRoleObject()->getImage($this->platform, $dbFarmRole->CloudLocation)->imageId, 'external_ip' => $this->remoteIp, 'internal_ip' => $this->localIp, 'role_name' => $dbRole->name, 'isdbmaster' => $isMaster, 'instance_index' => $this->index, 'instance_farm_index' => $this->farmIndex, 'server_type' => $this->type, 'server_hostname' => $this->GetProperty(Scalr_Role_Behavior::SERVER_BASE_HOSTNAME), 'server_id' => $this->serverId, 'farm_id' => $this->farmId, 'farm_role_id' => $this->farmRoleId, 'farm_role_alias' => $this->GetFarmRoleObject()->Alias, 'farm_name' => $this->GetFarmObject()->Name, 'farm_hash' => $this->GetFarmObject()->Hash, 'farm_owner_email' => $this->GetFarmObject()->createdByUserEmail, 'farm_team' => $this->GetFarmObject()->teamId ? (new Scalr_Account_Team())->loadById($this->GetFarmObject()->teamId)->name : '', 'behaviors' => implode(",", $dbRole->getBehaviors()), 'env_id' => $this->GetEnvironmentObject()->id, 'env_name' => $this->GetEnvironmentObject()->name, 'cloud_location' => $this->GetCloudLocation(), 'cloud_server_id' => $this->GetCloudServerID());
     if ($this->cloudLocationZone) {
         $retval['cloud_location_zone'] = $this->cloudLocationZone;
     }
     if ($this->platform == SERVER_PLATFORMS::EC2) {
         $retval['instance_id'] = $this->GetProperty(EC2_SERVER_PROPERTIES::INSTANCE_ID);
         $retval['ami_id'] = $this->GetProperty(EC2_SERVER_PROPERTIES::AMIID);
         $retval['region'] = $this->GetProperty(EC2_SERVER_PROPERTIES::REGION);
         $retval['avail_zone'] = $this->GetProperty(EC2_SERVER_PROPERTIES::AVAIL_ZONE);
         if ($dbFarmRole->GetSetting(Entity\FarmRoleSetting::AWS_ELB_ENABLED)) {
             $elbId = $dbFarmRole->GetSetting(Entity\FarmRoleSetting::AWS_ELB_ID);
             $retval['aws_elb_name'] = $elbId;
         }
     }
     if (\Scalr::getContainer()->analytics->enabled) {
         $ccId = $this->GetProperty(\SERVER_PROPERTIES::ENV_CC_ID);
         if ($ccId) {
             $cc = CostCentreEntity::findPk($ccId);
             if ($cc) {
                 /* @var $cc CostCentreEntity */
                 $retval['cost_center_id'] = $ccId;
                 $retval['cost_center_bc'] = $cc->getProperty(CostCentrePropertyEntity::NAME_BILLING_CODE);
                 $retval['cost_center_name'] = $cc->name;
             } else {
                 throw new Exception("Cost center {$ccId} not found");
             }
         }
         $projectId = $this->GetProperty(\SERVER_PROPERTIES::FARM_PROJECT_ID);
         if ($projectId) {
             $project = ProjectEntity::findPk($projectId);
             /* @var $project ProjectEntity */
             $retval['project_id'] = $projectId;
             $retval['project_bc'] = $project->getProperty(ProjectPropertyEntity::NAME_BILLING_CODE);
             $retval['project_name'] = $project->name;
         }
     }
     return $retval;
 }
Пример #8
0
 /**
  * Checks if user has access to project or cost center
  *
  * @param   string $projectId optional Id of the project
  * @param   string $ccId      optional Id of the cost center
  * @return  boolean           Returns false if user is not lead of the subject
  */
 public function isSubjectLead($projectId = null, $ccId = null)
 {
     if (!empty($projectId)) {
         $project = ProjectEntity::findPk($projectId);
         if (empty($project) || $project->getProperty(ProjectPropertyEntity::NAME_LEAD_EMAIL) !== $this->getEmail()) {
             return false;
         }
     } else {
         if (!empty($ccId)) {
             $ccs = CostCentreEntity::findPk($ccId);
             if (empty($ccs) || $ccs->getProperty(CostCentrePropertyEntity::NAME_LEAD_EMAIL) !== $this->getEmail()) {
                 return false;
             }
         }
     }
     return true;
 }
Пример #9
0
 /**
  * Gets parent Cost Center
  *
  * @return CostCentreEntity Returns cost centre entity
  */
 public function getCostCenter()
 {
     if ($this->_cc === null || $this->_cc->ccId != $this->ccId) {
         $this->_cc = CostCentreEntity::findPk($this->ccId);
     }
     return $this->_cc;
 }
Пример #10
0
 public function applyGlobalVarsToValue($value)
 {
     if (empty($this->globalVariablesCache)) {
         $formats = \Scalr::config("scalr.system.global_variables.format");
         $systemVars = array('env_id' => $this->EnvID, 'env_name' => $this->GetEnvironmentObject()->name, 'farm_id' => $this->ID, 'farm_name' => $this->Name, 'farm_hash' => $this->Hash, 'farm_owner_email' => $this->createdByUserEmail);
         if (\Scalr::getContainer()->analytics->enabled) {
             $projectId = $this->GetSetting(DBFarm::SETTING_PROJECT_ID);
             if ($projectId) {
                 $project = ProjectEntity::findPk($projectId);
                 /* @var $project ProjectEntity */
                 $systemVars['project_id'] = $projectId;
                 $systemVars['project_bc'] = $project->getProperty(ProjectPropertyEntity::NAME_BILLING_CODE);
                 $systemVars['project_name'] = $project->name;
                 $ccId = $project->ccId;
             }
             if ($ccId) {
                 $cc = CostCentreEntity::findPk($ccId);
                 if ($cc) {
                     /* @var $cc CostCentreEntity */
                     $systemVars['cost_center_id'] = $ccId;
                     $systemVars['cost_center_bc'] = $cc->getProperty(CostCentrePropertyEntity::NAME_BILLING_CODE);
                     $systemVars['cost_center_name'] = $cc->name;
                 } else {
                     throw new Exception("Cost center {$ccId} not found");
                 }
             }
         }
         // Get list of Server system vars
         foreach ($systemVars as $name => $val) {
             $name = "SCALR_" . strtoupper($name);
             $val = trim($val);
             if (isset($formats[$name])) {
                 $val = @sprintf($formats[$name], $val);
             }
             $this->globalVariablesCache[$name] = $val;
         }
         // Add custom variables
         $gv = new Scalr_Scripting_GlobalVariables($this->ClientID, $this->EnvID, Scalr_Scripting_GlobalVariables::SCOPE_FARM);
         $vars = $gv->listVariables(0, $this->ID);
         foreach ($vars as $v) {
             $this->globalVariablesCache[$v['name']] = $v['value'];
         }
     }
     //Parse variable
     $keys = array_keys($this->globalVariablesCache);
     $f = create_function('$item', 'return "{".$item."}";');
     $keys = array_map($f, $keys);
     $values = array_values($this->globalVariablesCache);
     $retval = str_replace($keys, $values, $value);
     // Strip undefined variables & return value
     return preg_replace("/{[A-Za-z0-9_-]+}/", "", $retval);
 }
Пример #11
0
 public function xSaveAction()
 {
     $this->request->defineParams(array('ccId' => ['type' => 'string'], 'projectId' => ['type' => 'string'], 'year' => ['type' => 'int'], 'quarters' => ['type' => 'json'], 'selectedQuarter' => ['type' => 'string']));
     $year = $this->getParam('year');
     $selectedQuarter = $this->getParam('selectedQuarter');
     if ($selectedQuarter !== 'year' && ($selectedQuarter < 1 || $selectedQuarter > 4)) {
         throw new OutOfBoundsException(sprintf("Invalid selectedQuarter number."));
     }
     $quarterReq = [];
     foreach ($this->getParam('quarters') as $q) {
         if (!isset($q['quarter'])) {
             throw new InvalidArgumentException(sprintf("Missing quarter property for quarters data set in the request."));
         }
         if ($q['quarter'] < 1 || $q['quarter'] > 4) {
             throw new OutOfRangeException(sprintf("Quarter value should be between 1 and 4."));
         }
         if (!isset($q['budget'])) {
             throw new InvalidArgumentException(sprintf("Missing budget property for quarters data set in the request."));
         }
         $quarterReq[$q['quarter']] = $q;
     }
     if ($this->getParam('projectId')) {
         $subjectType = QuarterlyBudgetEntity::SUBJECT_TYPE_PROJECT;
         $subjectId = $this->getParam('projectId');
     } else {
         if ($this->getParam('ccId')) {
             $subjectType = QuarterlyBudgetEntity::SUBJECT_TYPE_CC;
             $subjectId = $this->getParam('ccId');
         } else {
             throw new InvalidArgumentException(sprintf('Either ccId or projectId must be provided with the request.'));
         }
     }
     if (!preg_match("/^[[:xdigit:]-]{36}\$/", $subjectId)) {
         throw new InvalidArgumentException(sprintf("Invalid UUID has been passed."));
     }
     if (!preg_match('/^\\d{4}$/', $year)) {
         throw new InvalidArgumentException(sprintf("Invalid year has been passed."));
     }
     //Fetches the previous state of the entities from database
     if ($subjectType == QuarterlyBudgetEntity::SUBJECT_TYPE_CC) {
         $collection = QuarterlyBudgetEntity::getCcBudget($year, $subjectId);
     } else {
         $collection = QuarterlyBudgetEntity::getProjectBudget($year, $subjectId);
     }
     $quarters = new Quarters(SettingEntity::getQuarters(true));
     //Updates|creates entities
     for ($quarter = 1; $quarter <= 4; ++$quarter) {
         if (!isset($quarterReq[$quarter])) {
             continue;
         }
         $period = $quarters->getPeriodForQuarter($quarter, $year);
         //Checks if period has already been closed and forbids update
         if ($period->end->format('Y-m-d') < gmdate('Y-m-d')) {
             continue;
         }
         $entity = current($collection->filterByQuarter($quarter));
         if ($entity instanceof QuarterlyBudgetEntity) {
             //We should update an entity
             $entity->budget = abs((double) $quarterReq[$quarter]['budget']);
         } else {
             //We should create a new one.
             $entity = new QuarterlyBudgetEntity($year, $quarter);
             $entity->subjectType = $subjectType;
             $entity->subjectId = $subjectId;
             $entity->budget = abs((double) $quarterReq[$quarter]['budget']);
         }
         $entity->save();
     }
     if ($selectedQuarter == 'year') {
         $selectedPeriod = $quarters->getPeriodForYear($year);
     } else {
         $selectedPeriod = $quarters->getPeriodForQuarter($selectedQuarter, $year);
     }
     if ($subjectType == QuarterlyBudgetEntity::SUBJECT_TYPE_PROJECT) {
         $data = $this->getProjectData(ProjectEntity::findPk($subjectId), $selectedPeriod, true);
         $budgetInfo = $this->getBudgetInfo($year, $data['ccId'], $data['projectId']);
     } else {
         $data = $this->getCostCenterData(CostCentreEntity::findPk($subjectId), $selectedPeriod);
         $budgetInfo = $this->getBudgetInfo($year, $subjectId);
     }
     $this->response->data(['data' => $data, 'budgetInfo' => $budgetInfo]);
     $this->response->success('Budget changes have been saved');
 }
Пример #12
0
 public function xSaveAction()
 {
     if (!$this->user->isAccountSuperAdmin() && !$this->request->isAllowed(Acl::RESOURCE_ENV_CLOUDS_ENVIRONMENT)) {
         throw new Scalr_Exception_InsufficientPermissions();
     }
     $params = array('envId' => array('type' => 'int'), 'teams' => array('type' => 'json'));
     if ($this->user->isAccountOwner() || $this->user->isAccountSuperAdmin()) {
         $params['name'] = array('type' => 'string', 'validator' => array(Scalr_Validator::REQUIRED => true, Scalr_Validator::NOHTML => true));
     }
     $this->request->defineParams($params);
     $this->request->validate();
     if ($this->getContainer()->analytics->enabled) {
         if ($this->getParam('ccId')) {
             if (!$this->getContainer()->analytics->ccs->get($this->getParam('ccId'))) {
                 $this->request->addValidationErrors('ccId', 'Invalid cost center ID');
             }
         } else {
             $this->request->addValidationErrors('ccId', 'Cost center is required field');
         }
     }
     if ($this->request->isValid()) {
         $isNew = false;
         if (!$this->getParam('envId')) {
             //create new environment
             if (!$this->user->isAccountOwner() && !$this->user->isAccountSuperAdmin()) {
                 throw new Scalr_Exception_InsufficientPermissions();
             }
             $this->user->getAccount()->validateLimit(Scalr_Limits::ACCOUNT_ENVIRONMENTS, 1);
             $env = $this->user->getAccount()->createEnvironment($this->getParam('name'));
             $isNew = true;
         } else {
             $env = Scalr_Environment::init()->loadById($this->getParam('envId'));
         }
         $this->user->getPermissions()->validate($env);
         if (!$this->user->isAccountSuperAdmin() && !$this->user->getAclRolesByEnvironment($env->id)->isAllowed(Acl::RESOURCE_ENV_CLOUDS_ENVIRONMENT)) {
             throw new Scalr_Exception_InsufficientPermissions();
         }
         //set name, status and defaultPriority
         if ($this->user->isAccountOwner() || $this->user->isAccountSuperAdmin()) {
             $env->name = $this->getParam('name');
         }
         if ($this->user->canManageAcl()) {
             $env->status = $this->getParam('status') == Scalr_Environment::STATUS_ACTIVE ? Scalr_Environment::STATUS_ACTIVE : Scalr_Environment::STATUS_INACTIVE;
             $env->defaultPriority = $this->getParam('defaultPriority');
         }
         $env->save();
         if ($this->user->canManageAcl()) {
             if ($this->getContainer()->analytics->enabled && $this->getParam('ccId')) {
                 $oldCcId = $env->getPlatformConfigValue(Scalr_Environment::SETTING_CC_ID);
                 $env->setPlatformConfig(array(Scalr_Environment::SETTING_CC_ID => $this->getParam('ccId')));
                 if ($isNew || $oldCcId != $this->getParam('ccId')) {
                     $cc = CostCentreEntity::findPk($this->getParam('ccId'));
                     $email = $cc->getProperty(CostCentrePropertyEntity::NAME_LEAD_EMAIL);
                     $emailData = ['envName' => $env->name, 'ccName' => $cc->name];
                     if (!empty($email)) {
                         \Scalr::getContainer()->mailer->sendTemplate(SCALR_TEMPLATES_PATH . '/emails/analytics_on_cc_add.eml.php', $emailData, $email);
                     }
                 }
                 if ($isNew || empty($oldCcId)) {
                     $this->getContainer()->analytics->events->fireAssignCostCenterEvent($env, $this->getParam('ccId'));
                 } elseif ($oldCcId != $this->getParam('ccId')) {
                     $this->getContainer()->analytics->events->fireReplaceCostCenterEvent($env, $this->getParam('ccId'), $oldCcId);
                 }
             }
             //set teams
             if ($this->getContainer()->config->get('scalr.auth_mode') == 'ldap') {
                 $teams = array_map('trim', $this->getParam('teams'));
                 $ldapGroups = null;
                 if ($this->getContainer()->config->get('scalr.connections.ldap.user')) {
                     $ldap = $this->getContainer()->ldap(null, null);
                     $ldapGroups = $ldap->getGroupsDetails($teams);
                     foreach ($teams as $team) {
                         if (!isset($ldapGroups[$team])) {
                             throw new \Exception(sprintf("Team '%s' is not found on the directory server", $team));
                         }
                     }
                 }
                 $env->clearTeams();
                 foreach ($teams as $name) {
                     $name = trim($name);
                     if ($name) {
                         $id = $this->db->GetOne('SELECT id FROM account_teams WHERE name = ? AND account_id = ? LIMIT 1', array($name, $this->user->getAccountId()));
                         if (!$id) {
                             $team = new Scalr_Account_Team();
                             $team->name = $name;
                             $team->accountId = $this->user->getAccountId();
                             if ($ldapGroups !== null && $ldapGroups[$name] != $name) {
                                 $team->description = $ldapGroups[$name];
                             }
                             $team->save();
                             $id = $team->id;
                         } elseif ($ldapGroups !== null) {
                             // Update team description
                             $team = new Scalr_Account_Team();
                             $team->loadById($id);
                             if ($team->description != $ldapGroups[$name] && $ldapGroups[$name] != $name) {
                                 $team->description = $ldapGroups[$name];
                                 $team->save();
                             }
                         }
                         $env->addTeam($id);
                     }
                 }
                 if ($this->getContainer()->config->get('scalr.connections.ldap.user')) {
                     $user = strtok($this->user->getEmail(), '@');
                     $ldap = $this->getContainer()->ldap($user, null);
                     if ($ldap->isValidUsername()) {
                         $this->user->applyLdapGroups($ldap->getUserGroups());
                     }
                 }
             } else {
                 $env->clearTeams();
                 foreach ($this->getParam('teams') as $id) {
                     $env->addTeam($id);
                 }
             }
         }
         $this->response->success($isNew ? 'Environment successfully created' : 'Environment saved');
         $env = Scalr_Environment::init()->loadById($env->id);
         //reload env to be sure we have actual params
         $teams = array();
         foreach ($env->getTeams() as $teamId) {
             if ($this->getContainer()->config->get('scalr.auth_mode') == 'ldap') {
                 $team = new Scalr_Account_Team();
                 $team->loadById($teamId);
                 $teams[] = $team->name;
             } else {
                 $teams[] = $teamId;
             }
         }
         $this->response->data(array('env' => array('id' => $env->id, 'name' => $env->name, 'status' => $env->status, 'defaultPriority' => $env->defaultPriority, 'platforms' => $env->getEnabledPlatforms(), 'teams' => $teams, 'ccId' => $env->getPlatformConfigValue(Scalr_Environment::SETTING_CC_ID))));
     } else {
         $this->response->failure($this->request->getValidationErrorsMessage(), true);
     }
 }
Пример #13
0
 /**
  * @test
  */
 public function textAccountComplex()
 {
     $ccsArch = $this->createCostCenter(['name' => $this->getTestName(), 'archived' => CostCentreEntity::ARCHIVED]);
     $ccs = $this->listCostCenters([], false);
     $adapter = $this->getAdapter('costCenter');
     $filterable = $adapter->getRules()[ApiEntityAdapter::RULE_TYPE_FILTERABLE];
     foreach ($ccs as $cc) {
         foreach ($filterable as $property) {
             $filterValue = $cc->{$property};
             $listResult = $this->listCostCenters([$property => $filterValue], false);
             if (!static::isRecursivelyEmpty($filterValue)) {
                 foreach ($listResult as $filtered) {
                     $this->assertEquals($filterValue, $filtered->{$property}, "Property '{$property}' mismatch");
                 }
             }
         }
         $response = $this->getCostCenter($cc->id, false);
         $this->assertEquals(200, $response->status, $this->printResponseError($response));
         /* @var $dbCc CostCentreEntity */
         $dbCc = CostCentreEntity::findPk($cc->id);
         /* @var $acCs AccountCostCenterEntity */
         $acCs = AccountCostCenterEntity::findOne([['ccId' => $dbCc->ccId]]);
         $this->assertFalse($dbCc->archived);
         $this->assertEquals($this->getUser()->accountId, $acCs->accountId);
         $this->assertObjectEqualsEntity($response->getBody()->data, $dbCc, $adapter);
     }
     $filterByName = $this->listCostCenters(['name' => $ccsArch->name], false);
     $this->assertNotEmpty($filterByName);
     foreach ($filterByName as $cc) {
         $this->assertObjectEqualsEntity($cc, $ccsArch, $adapter);
         $this->assertNotContains($cc, $ccs, "List of Cost Centers shouldn't  have an archived project", false, false);
     }
     $filterByBillingCode = $this->listCostCenters(['billingCode' => $ccsArch->getProperty(CostCentrePropertyEntity::NAME_BILLING_CODE)], false);
     $this->assertNotEmpty($filterByBillingCode);
     foreach ($filterByBillingCode as $cc) {
         $this->assertObjectEqualsEntity($cc, $ccsArch, $adapter);
         $this->assertNotContains($cc, $ccs, "List of Cost Centers shouldn't  have an archived project", false, false);
     }
 }
Пример #14
0
 protected function isApplied1($stage)
 {
     return CostCentreEntity::findPk(Usage::DEFAULT_CC_ID) !== null && ProjectEntity::findPk(Usage::DEFAULT_PROJECT_ID) !== null;
 }
Пример #15
0
 /**
  * xMoveProjectsAction
  *
  * @param JsonData $projects Projects that should be moved
  * @throws AnalyticsException
  * @throws Exception
  * @throws \Scalr\Exception\ModelException
  */
 public function xMoveProjectsAction(JsonData $projects = null)
 {
     $envChange = [];
     $accountChange = [];
     $projectChange = [];
     $ccEntityCache = [];
     $collisions = [];
     foreach ($projects as $project) {
         $projectEntity = ProjectEntity::findPk($project['projectId']);
         /* @var $projectEntity ProjectEntity */
         if (empty($ccEntity)) {
             $ccEntity = $projectEntity->getCostCenter();
         }
         if ($ccEntity->ccId == $project['ccId']) {
             continue;
         }
         if (empty($ccEntityCache[$project['ccId']])) {
             $newCcEntity = CostCentreEntity::findPk($project['ccId']);
             /* @var $newCcEntity CostCentreEntity */
             if (!$newCcEntity) {
                 throw new Exception(sprintf("Cost center with id %s has not been found.", $project['ccId']), 404);
             }
             $ccEntityCache[$project['ccId']] = $newCcEntity->ccId;
         }
         $farms[$projectEntity->projectId] = $projectEntity->getFarmsList();
         foreach ($farms[$projectEntity->projectId] as $farmId => $farmName) {
             $farmEntity = Farm::findPk($farmId);
             /* @var $farmEntity Farm */
             if (empty($accountChange[$farmEntity->accountId])) {
                 $accountCss = AccountCostCenterEntity::findOne([['accountId' => $farmEntity->accountId], ['ccId' => $newCcEntity->ccId]]);
                 if (!$accountCss) {
                     $accountChange[$farmEntity->accountId] = $newCcEntity->ccId;
                 }
             }
             if (empty($envChange[$farmEntity->envId])) {
                 $project['name'] = $projectEntity->name;
                 $envChange[$farmEntity->envId] = $project;
             } else {
                 if ($envChange[$farmEntity->envId]['ccId'] != $project['ccId']) {
                     if (!in_array($projectEntity->name, $collisions)) {
                         $collisions[] = $projectEntity->name;
                     }
                     if (!in_array($envChange[$farmEntity->envId]['name'], $collisions)) {
                         $collisions[] = $envChange[$farmEntity->envId]['name'];
                     }
                     continue;
                 }
             }
         }
         $projectEntity->ccId = $project['ccId'];
         $projectChange[$projectEntity->projectId] = $projectEntity;
     }
     $remainningEnvs = [];
     $projectsCount = count($projectChange);
     if ($projectsCount) {
         if (isset($ccEntity)) {
             $envList = $ccEntity->getEnvironmentsList();
             foreach ($envList as $envId => $name) {
                 if (isset($envChange[$envId])) {
                     $ccProjects = $this->getContainer()->analytics->projects->getUsedInEnvironment($envId);
                     foreach ($ccProjects as $project) {
                         /* @var $project ProjectEntity */
                         if (!isset($farms[$project->projectId])) {
                             $farms[$project->projectId] = $project->getFarmsList();
                         }
                         if (count($farms[$project->projectId]) > 0 && !isset($projectChange[$project->projectId])) {
                             if (!in_array($envId, $remainningEnvs)) {
                                 $remainningEnvs[] = $envId;
                             }
                         }
                     }
                 }
             }
         }
         $this->db->BeginTrans();
         try {
             foreach ($accountChange as $accountId => $ccId) {
                 $accountCss = new AccountCostCenterEntity($accountId, $ccId);
                 $accountCss->save();
             }
             if (empty($remainningEnvs) && empty($collisions)) {
                 foreach ($envChange as $envId => $data) {
                     $envProp = EnvironmentProperty::findOne([['envId' => $envId], ['name' => EnvironmentProperty::SETTING_CC_ID]]);
                     /* @var $envProp EnvironmentProperty */
                     $envProp->value = $data['ccId'];
                     $envProp->save();
                 }
             }
             foreach ($projectChange as $project) {
                 /* @var $project ProjectEntity */
                 $project->save();
             }
             $this->db->CommitTrans();
         } catch (Exception $e) {
             $this->db->RollbackTrans();
             throw $e;
         }
     }
     if (count($collisions) > 0) {
         $this->response->warning(sprintf("%d Project%s %s been moved however collision occurred. Projects '%s' are used in the Farms from the same Environment however they have been moved to different Cost Centers.", $projectsCount, $projectsCount > 1 ? 's' : '', $projectsCount > 1 ? 'have' : 'has', implode("', '", $collisions)));
     } else {
         if (count($remainningEnvs) > 0) {
             $this->response->warning(sprintf("%d Project%s %s been moved however some Projects don't correspond to Cost Centers assigned to Environments '%s'.", $projectsCount, $projectsCount > 1 ? 's' : '', $projectsCount > 1 ? 'have' : 'has', implode("', '", $remainningEnvs)));
         } else {
             $this->response->success(sprintf("%d Project%s %s been moved to other Cost Center.", $projectsCount, $projectsCount > 1 ? 's' : '', $projectsCount > 1 ? 'have' : 'has'));
         }
     }
 }
Пример #16
0
 /**
  * Creates default Cost Center and Project from the fixture
  */
 public function createDefaultCostCenter()
 {
     $fixture = $this->fixture();
     foreach ($fixture as $i => $c) {
         $ccId = key($c);
         $cc = CostCentreEntity::findPk($ccId);
         if (!$cc) {
             $cc = new CostCentreEntity();
             $cc->ccId = $ccId;
             $cc->name = sprintf('Cost center %02d', $i + 1);
             $cc->save();
             $cc->saveProperty(CostCentrePropertyEntity::NAME_DESCRIPTION, 'This Cost Center was added automatically.');
             $cc->saveProperty(CostCentrePropertyEntity::NAME_BILLING_CODE, sprintf('CC-%02d', $i));
             $cc->saveProperty(CostCentrePropertyEntity::NAME_LEAD_EMAIL, '');
             $this->cadb->Execute("\n                    INSERT IGNORE `account_tag_values` (`account_id`, `tag_id`, `value_id`, `value_name`)\n                    VALUES (0, ?, ?, ?)\n                ", [TagEntity::TAG_ID_COST_CENTRE, $cc->ccId, $cc->name]);
         }
         foreach ($fixture[$i][$ccId] as $j => $projectId) {
             $pr = ProjectEntity::findPk($projectId);
             if (!$pr) {
                 $pr = new ProjectEntity();
                 $pr->projectId = $projectId;
                 $pr->ccId = $ccId;
                 $pr->name = sprintf('Project %d%d', $i, $j + 1);
                 $pr->save();
                 $pr->saveProperty(ProjectPropertyEntity::NAME_DESCRIPTION, 'This Project was added automatically.');
                 $pr->saveProperty(ProjectPropertyEntity::NAME_BILLING_CODE, sprintf('PR-%02d-%02d', $i, $j));
                 $pr->saveProperty(ProjectPropertyEntity::NAME_LEAD_EMAIL, '');
                 $this->cadb->Execute("\n                        INSERT IGNORE `account_tag_values` (`account_id`, `tag_id`, `value_id`, `value_name`)\n                        VALUES (0, ?, ?, ?)\n                    ", [TagEntity::TAG_ID_PROJECT, $pr->projectId, $pr->name]);
             }
         }
     }
 }
Пример #17
0
 /**
  * xGetPeriodLogAction
  *
  * @param   string    $mode      The mode (week, month, quarter, year)
  * @param   string    $startDate The start date of the period in UTC ('Y-m-d')
  * @param   string    $endDate   The end date of the period in UTC ('Y-m-d')
  * @param   string    $type      Type of the data gathered in log file (farms, clouds, projects)
  * @param   string    $ccId      optional The identifier of the cost center
  * @param   string    $projectId optional The identifier of the project
  */
 public function xGetPeriodCsvAction($mode, $startDate, $endDate, $type, $ccId = null, $projectId = null)
 {
     $name = 'Cloud';
     if (!empty($ccId) && empty($projectId)) {
         $data = $this->getContainer()->analytics->usage->getCostCenterPeriodData($ccId, $mode, $startDate, $endDate);
         $entity = CostCentreEntity::findPk($ccId);
         if ($type !== 'clouds') {
             $name = 'Project';
             $extraFields = 'Cost Center name;Billing code;Lead email address;';
         }
     } else {
         if (!empty($projectId)) {
             $data = $this->getContainer()->analytics->usage->getProjectPeriodData($projectId, $mode, $startDate, $endDate);
             $entity = ProjectEntity::findPk($projectId);
             if ($type !== 'clouds') {
                 $name = 'Farm';
                 $extraFields = 'Project name;Billing code;Lead email address;';
             }
         } else {
             throw new \InvalidArgumentException(sprintf("Method %s requires both ccId or projectId to be specified.", __METHOD__));
         }
     }
     $extraData = [$entity->name, $entity->getProperty('billing.code'), $entity->getProperty('lead.email')];
     $head[] = $name;
     $end[] = "Total spent";
     if (isset($extraFields)) {
         $head = array_merge($head, $extraData);
         $end = array_merge($end, $extraData);
     }
     $totals = 0;
     foreach ($data['timeline'] as $timeline) {
         $totals += $timeline['cost'];
         $head[] = $timeline['label'];
         $end[] = $timeline['cost'];
     }
     $head[] = 'Total';
     $end[] = $totals;
     $temp = tmpfile();
     fputcsv($temp, $head);
     foreach ($data[$type] as $item) {
         $row = [];
         $row[] = $item['name'];
         $dataCost = [];
         foreach ($data['timeline'] as $key => $value) {
             $dataCost[] = isset($item['data'][$key]['cost']) ? $item['data'][$key]['cost'] : 0;
         }
         $itemTotal = array_sum($dataCost);
         if (isset($extraFields)) {
             $row = array_merge($row, $extraData);
         }
         $row = array_merge($row, $dataCost);
         $row[] = $itemTotal;
         fputcsv($temp, $row);
     }
     fputcsv($temp, $end);
     $metadata = stream_get_meta_data($temp);
     $label = Scalr_Util_DateTime::convertTz(time(), 'M_j_Y_H:i:s');
     $fileName = $entity->name . '.' . $entity->getProperty('billing.code') . '.' . $type . '.' . $label;
     $bad = array_merge(array_map('chr', range(0, 31)), ["<", ">", ":", '"', "/", "\\", "|", "?", "*"]);
     $fileName = str_replace($bad, "", $fileName);
     $this->response->setHeader('Content-Encoding', 'utf-8');
     $this->response->setHeader('Content-Type', 'text/csv', true);
     $this->response->setHeader('Expires', 'Mon, 10 Jan 1997 08:00:00 GMT');
     $this->response->setHeader('Pragma', 'no-cache');
     $this->response->setHeader('Cache-Control', 'no-store, no-cache, must-revalidate');
     $this->response->setHeader('Cache-Control', 'post-check=0, pre-check=0');
     $this->response->setHeader('Content-Disposition', 'attachment; filename=' . $fileName . ".csv");
     $this->response->setResponse(file_get_contents($metadata['uri']));
     fclose($temp);
 }
Пример #18
0
 /**
  * Initializes default cost centres and projects according to fixtures
  *
  * @return void
  */
 public function initDefault()
 {
     $fixture = $this->fixture();
     foreach ($fixture as $i => $c) {
         $ccId = key($c);
         $cc = CostCentreEntity::findPk($ccId);
         if (!$cc) {
             $cc = new CostCentreEntity();
             $cc->ccId = $ccId;
             $cc->name = sprintf('Cost center %02d', $i + 1);
             $cc->save();
             $cc->saveProperty(CostCentrePropertyEntity::NAME_DESCRIPTION, 'This is the automatically added cost center');
             $cc->saveProperty(CostCentrePropertyEntity::NAME_BILLING_CODE, sprintf('CC-%02d', $i));
             $cc->saveProperty(CostCentrePropertyEntity::NAME_LEAD_EMAIL, '');
             $this->cadb->Execute("\n                    INSERT IGNORE `account_tag_values` (`account_id`, `tag_id`, `value_id`, `value_name`)\n                    VALUES (0, ?, ?, ?)\n                ", [TagEntity::TAG_ID_COST_CENTRE, $cc->ccId, $cc->name]);
         }
         foreach ($fixture[$i][$ccId] as $j => $projectId) {
             $pr = ProjectEntity::findPk($projectId);
             if (!$pr) {
                 $pr = new ProjectEntity();
                 $pr->projectId = $projectId;
                 $pr->ccId = $ccId;
                 $pr->name = sprintf('Project %d%d', $i, $j + 1);
                 $pr->save();
                 $pr->saveProperty(ProjectPropertyEntity::NAME_DESCRIPTION, 'This is the automatically generated project');
                 $pr->saveProperty(ProjectPropertyEntity::NAME_BILLING_CODE, sprintf('PR-%02d-%02d', $i, $j));
                 $pr->saveProperty(ProjectPropertyEntity::NAME_LEAD_EMAIL, '');
                 $this->cadb->Execute("\n                        INSERT IGNORE `account_tag_values` (`account_id`, `tag_id`, `value_id`, `value_name`)\n                        VALUES (0, ?, ?, ?)\n                    ", [TagEntity::TAG_ID_PROJECT, $pr->projectId, $pr->name]);
             }
         }
     }
     //Assigns cost centre to each environment
     $res = $this->db->Execute("SELECT id FROM client_environments");
     while ($rec = $res->FetchRow()) {
         try {
             $environment = \Scalr_Environment::init()->loadById($rec['id']);
         } catch (Exception $e) {
             continue;
         }
         $environment->setPlatformConfig(array(\Scalr_Environment::SETTING_CC_ID => $this->autoCostCentre($environment->id)));
     }
     //Assigns project to each farm
     $res = $this->db->Execute("SELECT id, env_id, clientid FROM farms");
     while ($rec = $res->FetchRow()) {
         try {
             $dbFarm = DBFarm::LoadByID($rec['id']);
         } catch (Exception $e) {
             continue;
         }
         $dbFarm->SetSetting(DBFarm::SETTING_PROJECT_ID, $this->autoProject($dbFarm->EnvID, $dbFarm->ID));
     }
     //Initializes servers properties
     $res = $this->db->Execute("\n            SELECT DISTINCT s.server_id, s.env_id, s.farm_id\n            FROM servers s\n            LEFT JOIN server_properties p ON p.server_id = s.server_id AND p.name = ?\n            LEFT JOIN server_properties p2 ON p2.server_id = s.server_id AND p2.name = ?\n            WHERE p.server_id IS NULL OR p.`value` IS NULL\n            OR (s.farm_id IS NOT NULL AND (p2.server_id IS NULL OR p2.`value` IS NULL))\n        ", [SERVER_PROPERTIES::ENV_CC_ID, SERVER_PROPERTIES::FARM_PROJECT_ID]);
     while ($rec = $res->FetchRow()) {
         $ccid = $this->autoCostCentre($rec['env_id']);
         $this->db->Execute("\n                INSERT `server_properties` (`server_id`, `name`, `value`)\n                VALUE (?, ?, ?)\n                ON DUPLICATE KEY UPDATE `value` = IFNULL(`value`, ?)\n            ", [$rec['server_id'], SERVER_PROPERTIES::ENV_CC_ID, $ccid, $ccid]);
         //Farm may not exist for bundle task servers
         if ($rec['farm_id']) {
             $projectid = $this->autoProject($rec['env_id'], $rec['farm_id']);
             $this->db->Execute("\n                    INSERT `server_properties` (`server_id`, `name`, `value`)\n                    VALUE (?, ?, ?)\n                    ON DUPLICATE KEY UPDATE `value` = IFNULL(`value`, ?)\n                ", [$rec['server_id'], SERVER_PROPERTIES::FARM_PROJECT_ID, $projectid, $projectid]);
         }
     }
 }
Пример #19
0
 /**
  * Gets budgeted cost for all quarters of specified year
  *
  * @param    int      $year       The year
  * @param    string   $ccId       optional The identifier of the cost centre or parent cost centre
  * @param    string   $projectId  optional The identifier of the project
  * @throws   InvalidArgumentException
  */
 protected function getBudgetInfo($year, $ccId = null, $projectId = null)
 {
     if (!empty($projectId)) {
         $subjectId = $projectId;
         $subjectType = QuarterlyBudgetEntity::SUBJECT_TYPE_PROJECT;
         $subjectEntity = ProjectEntity::findPk($projectId);
     } else {
         if (!empty($ccId)) {
             $subjectId = $ccId;
             $subjectType = QuarterlyBudgetEntity::SUBJECT_TYPE_CC;
             $subjectEntity = CostCentreEntity::findPk($ccId);
         }
     }
     if ($subjectEntity->accountId !== $this->user->getAccountId()) {
         //throw new Scalr_Exception_InsufficientPermissions();
     }
     if (empty($subjectId) || !preg_match('/^[[:xdigit:]-]{36}$/', $subjectId)) {
         throw new InvalidArgumentException(sprintf("Invalid identifier of the project or cost center."));
     }
     if (!preg_match('/^\\d{4}$/', $year)) {
         throw new InvalidArgumentException(sprintf("Invalid year."));
     }
     if ($subjectType == QuarterlyBudgetEntity::SUBJECT_TYPE_CC) {
         $collection = QuarterlyBudgetEntity::getCcBudget($year, $subjectId);
         $prevCollection = QuarterlyBudgetEntity::getCcBudget($year - 1, $subjectId);
     } else {
         $collection = QuarterlyBudgetEntity::getProjectBudget($year, $subjectId);
         $prevCollection = QuarterlyBudgetEntity::getProjectBudget($year - 1, $subjectId);
     }
     $quarters = new Quarters(SettingEntity::getQuarters(true));
     $today = new DateTime('now', new DateTimeZone('UTC'));
     //Start dates for an each quarter
     $startDates = $quarters->getDays();
     $budgets = [];
     for ($quarter = 1; $quarter <= 4; ++$quarter) {
         $period = $quarters->getPeriodForQuarter($quarter, $year);
         $prevPeriod = $quarters->getPeriodForQuarter($quarter, $year - 1);
         //Finds budget for specified quarter in the collection
         $entity = current($collection->filterByQuarter($quarter));
         //Previous Year entity
         $prevEntity = current($prevCollection->filterByQuarter($quarter));
         if ($entity instanceof QuarterlyBudgetEntity) {
             $budget = ['budget' => round($entity->budget), 'budgetFinalSpent' => round($entity->cumulativespend), 'spentondate' => $entity->spentondate instanceof DateTime ? $entity->spentondate->format('Y-m-d') : null, 'budgetSpent' => round($entity->cumulativespend)];
             if ($budget['budget']) {
                 $budget['budgetOverspend'] = max(round($entity->cumulativespend - $entity->budget), 0);
                 $budget['budgetOverspendPct'] = round($budget['budgetOverspend'] / $budget['budget'] * 100);
             }
         } else {
             //Budget has not been set yet.
             $budget = ['budget' => 0, 'budgetFinalSpent' => 0, 'spentondate' => null, 'budgetSpent' => 0, 'budgetOverspend' => 0, 'budgetOverspendPct' => 0];
         }
         $budget['year'] = $year;
         $budget['quarter'] = $quarter;
         $budget['startDate'] = $startDates[$quarter - 1];
         //Whether this quarter has been closed or not
         $budget['closed'] = $period->end->format('Y-m-d') < gmdate('Y-m-d');
         //The number of the days in the current quarter
         $daysInQuarter = $period->start->diff($period->end, true)->days + 1;
         //In case quarter is closed projection should be calculated
         if (!$budget['closed']) {
             $daysPassed = $period->start->diff($today, true)->days + 1;
             $budget['dailyAverage'] = $daysPassed == 0 ? 0 : round($budget['budgetSpent'] / $daysPassed, 2);
             $budget['projection'] = round($daysInQuarter * $budget['dailyAverage']);
         } else {
             $budget['dailyAverage'] = $daysInQuarter == 0 ? 0 : round($budget['budgetFinalSpent'] / $daysInQuarter, 2);
         }
         $budget['costVariance'] = round((isset($budget['projection']) ? $budget['projection'] : $budget['budgetSpent']) - $budget['budget'], 2);
         $budget['costVariancePct'] = $budget['budget'] == 0 ? null : round(abs($budget['costVariance']) / $budget['budget'] * 100);
         $budget['monthlyAverage'] = round($budget['dailyAverage'] * 30);
         if ($prevEntity instanceof QuarterlyBudgetEntity) {
             $budget['prev'] = ['budget' => $prevEntity->budget, 'budgetFinalSpent' => $prevEntity->cumulativespend, 'spentondate' => $prevEntity->spentondate instanceof DateTime ? $prevEntity->spentondate->format('Y-m-d') : null, 'closed' => $prevPeriod->end->format('Y-m-d') < gmdate('Y-m-d'), 'costVariance' => $prevEntity->cumulativespend - $prevEntity->budget, 'costVariancePct' => $prevEntity->budget == 0 ? null : round(abs($prevEntity->cumulativespend - $prevEntity->budget) / $prevEntity->budget * 100)];
         } else {
             $budget['prev'] = ['budget' => null, 'budgetFinalSpent' => 0, 'spentondate' => null, 'closed' => $prevPeriod->end->format('Y-m-d') < gmdate('Y-m-d'), 'budgetSpent' => 0, 'costVariance' => 0, 'costVariancePct' => 0];
         }
         $budgets[] = $budget;
     }
     $result = ['budgets' => $budgets, 'ccId' => $ccId, 'projectId' => $projectId, 'quarter' => $quarters->getQuarterForDate(), 'year' => $year];
     if (!empty($projectId)) {
         $result['shared'] = $subjectEntity->shared;
     }
     return $result;
 }
Пример #20
0
 /**
  * Gets the list of the Cost Centers which correspond to Account
  *
  * @return  \Scalr\Model\Collections\ArrayCollection  Returns collection of the entities
  */
 public function getCostCenters()
 {
     $ccs = new ArrayCollection();
     foreach (AccountCostCenterEntity::findByAccountId($this->id) as $accountCc) {
         $cc = CostCentreEntity::findPk($accountCc->ccId);
         if (!$cc instanceof CostCentreEntity) {
             continue;
         }
         $ccs->append($cc);
     }
     return $ccs;
 }