public function getTopFarmsPeriodData($accountId, array $allowedEnvs, $mode, $startDate, $endDate, $farmCount = 5)
{
$utcTz = new DateTimeZone('UTC');
$iterator = ChartPeriodIterator::create($mode, new DateTime($startDate, $utcTz), new DateTime($endDate, $utcTz), 'UTC');
$start = $iterator->getStart();
$end = $iterator->getEnd();
//Interval which is used in the database query for grouping
$queryInterval = preg_replace('/^1 /', '', $iterator->getInterval());
$criteria = !empty($allowedEnvs) ? ['envId' => $allowedEnvs] : [];
//Requests data for the specified period
$rawUsage = $this->getFarmData($accountId, $criteria, $start, $end, [$queryInterval, TagEntity::TAG_ID_FARM], true);
//Requests data for the previous period
$rawPrevUsage = $this->getFarmData($accountId, $criteria, $iterator->getPreviousStart(), $iterator->getPreviousEnd(), [$queryInterval, TagEntity::TAG_ID_FARM], true);
//Calculates top five farms for the specified period
$topFarms = [];
$arr = (new AggregationCollection(['farmId'], ['cost' => 'sum']))->load($rawUsage)->getArrayCopy();
if (!empty($arr['data']) && count($arr['data']) > $farmCount + 1) {
uasort($arr['data'], function ($a, $b) {
if ($a['cost'] == $b['cost']) {
return 0;
}
return $a['cost'] < $b['cost'] ? 1 : -1;
});
$i = 0;
foreach ($arr['data'] as $farmId => $v) {
$topFarms[$farmId] = $farmId;
if (++$i >= $farmCount) {
break;
}
}
}
//Subtotals by farms
$usage = new AggregationCollection(['farmId'], ['cost' => 'sum']);
//Previous period subtotals by farms
$prevUsage = new AggregationCollection(['farmId'], ['cost' => 'sum']);
if (empty($topFarms)) {
//Loads current period
foreach ($rawUsage as $item) {
$usage->append($item);
}
//Loads previous period
foreach ($rawPrevUsage as $item) {
$prevUsage->append($item);
}
} else {
//Loads current period and aggregates top 5 farms
foreach ($rawUsage as $item) {
if (array_key_exists($item['farmId'], $topFarms)) {
$usage->append($item);
}
}
//Loads previous period and aggregates top 5 farms
foreach ($rawPrevUsage as $item) {
if (array_key_exists($item['farmId'], $topFarms)) {
$prevUsage->append($item);
}
}
}
//Calculates percentage
$usage->calculatePercentage();
if ($iterator->getWholePreviousPeriodEnd() != $iterator->getPreviousEnd()) {
$rawPrevUsageWhole = $this->getFarmData($accountId, ['envId' => $allowedEnvs], $iterator->getPreviousStart(), $iterator->getWholePreviousPeriodEnd(), [TagEntity::TAG_ID_FARM], true);
//Previous whole period usage subtotals by farm
$prevUsageWhole = (new AggregationCollection(['farmId'], ['cost' => 'sum']))->load($rawPrevUsageWhole);
} else {
$prevUsageWhole = $prevUsage;
}
//Build farms total
$farmsTotal = [];
$it = $usage->getIterator();
foreach ($it as $farmId => $p) {
$pp = isset($prevUsage['data'][$farmId]) ? $prevUsage['data'][$farmId] : null;
$pw = isset($prevUsageWhole['data'][$farmId]) ? $prevUsageWhole['data'][$farmId] : null;
$cl = $this->getTotalDataArray($farmId, $this->fetchFarmName($farmId), $p, $pp, $pw, [], null, true);
$farmsTotal[] = $cl;
}
return $farmsTotal;
}