• Модуль: intranet
  • Путь к файлу: ~/bitrix/modules/intranet/lib/ustat/ustat.php
  • Класс: BitrixIntranetUStatUStat
  • Вызов: UStat::getDepartmentGraphData
static function getDepartmentGraphData($departmentId, TypeDateTime $dateFrom, TypeDateTime $dateTo, $interval)
{
	if (!in_array($interval, array('hour', 'day', 'month'), true))
	{
		throw new MainArgumentException('Interval should be the "hour", or "day", or "month".');
	}

	$data = array();

	if ($interval === 'hour')
	{
		$query = new EntityQuery(DepartmentHourTable::getEntity());

		$query->setSelect(array('DATE' => 'HOUR', 'TOTAL'));

		foreach (UserHourTable::getSectionNames() as $sectionName)
		{
			$query->addSelect($sectionName);
		}

		$query->setFilter(array(
			'=DEPT_ID' => $departmentId,
			'> array(
				ConvertTimeStamp($dateFrom->getTimestamp(), 'FULL'),
				ConvertTimeStamp($dateTo->getTimestamp(), 'FULL')
			)
		));

		$keyFormat = 'Y-m-d H:00:00';

		// no company involvement for hourly data
	}
	elseif ($interval === 'day')
	{
		$query = new EntityQuery(DepartmentDayTable::getEntity());

		$query->setSelect(array('DATE' => 'DAY', 'TOTAL', 'INVOLVEMENT'));

		foreach (UserHourTable::getSectionNames() as $sectionName)
		{
			$query->addSelect($sectionName);
		}

		$query->setFilter(array(
			'=DEPT_ID' => $departmentId,
			'> array(
				ConvertTimeStamp($dateFrom->getTimestamp()),
				ConvertTimeStamp($dateTo->getTimestamp())
			)
		));

		$keyFormat = 'Y-m-d';
	}
	elseif ($interval === 'month')
	{
		$query = new EntityQuery(DepartmentDayTable::getEntity());
		$sqlHelper = Application::getConnection()->getSqlHelper();

		$monthExpression = array(
			'data_type' => 'string',
			'expression' => array(str_replace(
				$sqlHelper->formatDate('YYYY-MM'), // get db format
				str_replace('%', '%%', $sqlHelper->formatDate('YYYY-MM')), // and quote it for sprintf
				$sqlHelper->formatDate('YYYY-MM', '%1$s') // in main expression
			), 'DAY')
		);

		$query->registerRuntimeField('DATE', $monthExpression);
		$query->registerRuntimeField('TOTAL_SUM', array(
			'data_type' => 'integer',
			'expression' => array('SUM(%s)', 'TOTAL')
		));

		$query->setSelect(array('DATE', 'TOTAL_SUM'));

		foreach (UserHourTable::getSectionNames() as $sectionName)
		{
			$query->registerRuntimeField($sectionName.'_SUM', array(
				'data_type' => 'integer',
				'expression' => array('SUM(%s)', $sectionName)
			));

			$query->addSelect($sectionName.'_SUM');
		}

		$query->setFilter(array(
			'=DEPT_ID' => $departmentId,
			'> array(
				ConvertTimeStamp($dateFrom->getTimestamp()),
				ConvertTimeStamp($dateTo->getTimestamp())
			)
		));

		$query->setGroup('DATE');

		$keyFormat = 'Y-m';

		// company involvement will be attached later
	}

	$query->setOrder('DATE');

	$result = $query->exec();

	while ($row = $result->fetch())
	{
		// back-format keys
		foreach ($row as $k => $v)
		{
			if (mb_substr($k, -4) === '_SUM')
			{
				$row[mb_substr($k, 0, -4)] = $v;
				unset($row[$k]);
			}
		}

		/** @var TypeDateTime[] $row */
		if (!is_object($row['DATE']))
		{
			$key = $row['DATE'];
			$row['DATE'] = new TypeDateTime($row['DATE'], $keyFormat);
		}
		else
		{
			$key = $row['DATE']->format($keyFormat);
		}

		$data[$key] = $row;
	}

	if ($interval === 'month')
	{
		// count involvement
		$invQuery = new EntityQuery(DepartmentDayTable::getEntity());

		$invQuery->setSelect(array('DATE' => 'DAY', 'INVOLVEMENT'));

		$invQuery->setFilter(array(
			'=DEPT_ID' => $departmentId,
			'> array(
				ConvertTimeStamp($dateFrom->getTimestamp()),
				ConvertTimeStamp($dateTo->getTimestamp())
			)
		));

		$invQuery->addOrder('INVOLVEMENT', 'DESC');

		$result = $invQuery->exec();

		$invData = array();

		while ($row = $result->fetch())
		{
			/** @var TypeDateTime[] $row */
			$invData[$row['DATE']->format('Y-m')][$row['DATE']->format('j')] = $row['INVOLVEMENT'];
		}

		// get 70% most involved days
		foreach ($invData as $month => $monthData)
		{
			$bestDays = array_slice($monthData, 0, round(count($monthData)*0.7));

			if (count($bestDays))
			{
				$involvement = round(array_sum($bestDays)/count($bestDays));
				$data[$month]['INVOLVEMENT'] = $involvement;
			}
		}
	}

	return $data;
}