<?php
namespace AppBundle\Controller\Dashboard;
use AppBundle\Controller\Controller;
use AppBundle\Form\Model\Dashboard\DashboardFilters;
use AppBundle\Form\Type\Dashboard\DashboardFiltersType;
use DomainBundle\Query\Insurer\GetInsurerInsights;
use DomainBundle\Query\Operator\GetOperatorInsights;
use DomainBundle\Query\Reporting\GetReviewInsights;
use DomainBundle\Repository\Reporting\ReviewFilters;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use ValueObject\DateTime\DateRange;
/**
* Controller for the admin insights dashboard.
*/
class DashboardController extends Controller
{
/**
* @Route("/", name="app_dashboard")
*
* @Security("is_granted('ROLE_USER')")
*/
public function dashboardAction(Request $request) {
return $this->redirectToRoute('app_ticket_list');
if (!$this->isGranted('ROLE_ADMIN')) {
return $this->redirectToRoute('app_ticket_list');
}
$filters = $this->getFilterManager()->getFilters(DashboardFilters::class, $request);
$form = $this->createForm(DashboardFiltersType::class, $filters, array(
'method' => 'GET',
'action' => $this->generateUrl('app_dashboard'),
));
$form->handleRequest($request);
$filters = $this->getFilterManager()->normalizeFilters($filters);
$formView = $form->createView();
$formView->children['view']->vars['attr']['mtl-init'] = 'dashboardViewSelect';
$dateSegments = $this->getFilterDateSegments($filters->dateRange);
return $this->render('@App/dashboard/dashboard.html.twig', array(
'filters_form' => $formView,
'filters_args' => $this->getFilterManager()->saveFilters($filters),
'view_type' => $this->getViewType($filters),
'view_data' => $this->getViewData($filters),
'segments' => $dateSegments,
));
}
/**
* Gets the chosen report type (operator, insurer).
*/
public function getViewType(DashboardFilters $filters) {
return $filters->view;
}
/**
* Gets view data for the given report type.
*/
public function getViewData(DashboardFilters $filters) {
$type = $this->getViewType($filters);
switch ($type) {
case 'operator':
return $this->getOperatorInsights($filters);
case 'insurer':
return $this->getInsurerInsights($filters);
case 'reviews':
return $this->getReviewsInsights($filters);
}
throw $this->createNotFoundException(vsprintf('Dashboard view type "%s" is not recognised', array(
$type,
)));
}
/**
* Gets view data for the operator insights report.
*/
public function getOperatorInsights(DashboardFilters $filters) {
$query = new GetOperatorInsights($filters->dateRange, $filters->orderBy, $filters->orderDir);
return $this->handleQuery($query);
}
/**
* Gets view data for the insurer insights report.
*/
public function getInsurerInsights(DashboardFilters $filters) {
$query = new GetInsurerInsights($filters->dateRange, $filters->orderBy, $filters->orderDir);
return $this->handleQuery($query);
}
/**
* Gets view data for the reviews insights report.
*/
public function getReviewsInsights(DashboardFilters $filters) {
$reviewFilters = new ReviewFilters();
$reviewFilters->dateRange = $filters->dateRange;
$reviewFilters->orderBy = $filters->orderBy;
$reviewFilters->orderDir = $filters->orderDir;
$query = new GetReviewInsights($reviewFilters);
return $this->handleQuery($query);
}
/**
* Gets date segments for insurer insights.
*
* This functionality matches that found in the GetInsurerInsights query, but in this case
* is used to pre-populate the ticket filters when clicking on an individual cell.
*/
public function getFilterDateSegments(DateRange $dateRange) {
$startDate = $dateRange->getStartDate();
$endDate = $dateRange->getEndDate();
$segmentEndDate = date_create('9999-12-31'); // the first 30d segment has an arbitrarily-large upper bound
$out = array();
foreach (array(
'p30d' => new \DateInterval('P30D'),
'p60d' => new \DateInterval('P60D'),
'p90d' => new \DateInterval('P90D'),
'rest' => new \DateInterval('P99Y'),
) as $k => $interval) {
$segmentStartDate = date_create('now')->sub($interval);
$out[$k] = DateRange::from(
max($startDate, min($segmentStartDate, $endDate)),
max($startDate, min($segmentEndDate, $endDate))
);
$segmentEndDate = $segmentStartDate; // use this segment's start date as the next segment's end date
}
return $out;
}
}