From a5355dce42525b4a09c899ba42a2e75c0b1dd323 Mon Sep 17 00:00:00 2001 From: mathieu-chouchou Date: Mon, 6 Jan 2020 18:02:36 +0100 Subject: [PATCH] Added two controllers for two other graphs SalesByRegion, calculates sales grouped by regions SalesByGranularity, calculates sales on a interval with a granularity --- api/src/Controller/AverageSurfacePrice.php | 14 +++- api/src/Controller/SalesByGranularity.php | 72 +++++++++++++++++ api/src/Controller/SalesByRegion.php | 60 ++++++++++++++ api/src/Entity/PropertySale.php | 91 ++++++++++++++++++++-- 4 files changed, 228 insertions(+), 9 deletions(-) create mode 100644 api/src/Controller/SalesByGranularity.php create mode 100644 api/src/Controller/SalesByRegion.php diff --git a/api/src/Controller/AverageSurfacePrice.php b/api/src/Controller/AverageSurfacePrice.php index bab972b..da9c68a 100644 --- a/api/src/Controller/AverageSurfacePrice.php +++ b/api/src/Controller/AverageSurfacePrice.php @@ -4,6 +4,7 @@ namespace App\Controller; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use App\Entity\PropertySale; @@ -23,9 +24,20 @@ class AverageSurfacePrice WHERE ps.price != 0 AND ps.surface != 0 GROUP BY month"; - return $this->em + $query = $this->em ->createQuery($query) ->getResult(); + + $result = array_map(function($data) { + $data['value'] = floatval($data['value']); + return $data; + }, $query); + + return new Response( + json_encode($result), + Response::HTTP_OK, + ['content-type' => 'application/json'] + ); } } diff --git a/api/src/Controller/SalesByGranularity.php b/api/src/Controller/SalesByGranularity.php new file mode 100644 index 0000000..df4d8a0 --- /dev/null +++ b/api/src/Controller/SalesByGranularity.php @@ -0,0 +1,72 @@ +em = $em; + } + + public function __invoke(Request $data) + { + $granularity = $data->query->get('granularity'); + $date_start = $data->query->get('date_start'); + $date_end = $data->query->get('date_end'); + + if(!preg_match('/^(day|month|year)$/', $granularity)) { + return new Response( + 'Bad Request : granularity in wrong format', + Response::HTTP_BAD_REQUEST, + ['content-type' => 'application/text'] + ); + } + + $date_regex = '/^\d{4}-\d{2}-\d{2}$/'; + if(!preg_match($date_regex, $date_start)) { + return new Response( + 'Bad Request : date_start is in wrong format', + Response::HTTP_BAD_REQUEST, + ['content-type' => 'application/text'] + ); + } + if(!preg_match($date_regex, $date_end)) { + return new Response( + 'Bad Request : date_end is in wrong format', + Response::HTTP_BAD_REQUEST, + ['content-type' => 'application/text'] + ); + } + + + $query = "SELECT + DATE_TRUNC('$granularity', ps.date) sales_date, + COUNT(ps.price) sales + FROM App:PropertySale ps + WHERE + ps.date BETWEEN '$date_start' AND '$date_end' + GROUP BY sales_date + ORDER BY sales_date"; + + $result = $this->em + ->createQuery($query) + ->getResult(); + + return new Response( + json_encode($result), + Response::HTTP_OK, + ['content-type' => 'application/json'] + ); + } +} + +?> \ No newline at end of file diff --git a/api/src/Controller/SalesByRegion.php b/api/src/Controller/SalesByRegion.php new file mode 100644 index 0000000..61257d5 --- /dev/null +++ b/api/src/Controller/SalesByRegion.php @@ -0,0 +1,60 @@ +em = $em; + } + + public function __invoke(Request $data) + { + $year = $data->query->get('year'); + + if(!preg_match('/^\d{4}$/', $year)) { + return new Response( + 'Bad Request', + Response::HTTP_BAD_REQUEST, + ['content-type' => 'application/text'] + ); + } + + $year = $year.'-01-01'; + + $query = "SELECT + ps.region, + COUNT(ps) value + FROM App:PropertySale ps + WHERE + DATE_TRUNC('year', ps.date) = '$year' + GROUP BY ps.region"; + + $query = $this->em + ->createQuery($query) + ->getResult(); + + $result = array_map(function($data) { + $data['value'] = intval($data['value']); + return $data; + }, $query); + + return new Response( + json_encode($result), + Response::HTTP_OK, + ['content-type' => 'application/json'] + ); + } +} + +?> \ No newline at end of file diff --git a/api/src/Entity/PropertySale.php b/api/src/Entity/PropertySale.php index 95ed5cf..f5c6728 100644 --- a/api/src/Entity/PropertySale.php +++ b/api/src/Entity/PropertySale.php @@ -6,6 +6,8 @@ use Doctrine\ORM\Mapping as ORM; use ApiPlatform\Core\Annotation\ApiResource; use App\Controller\AverageSurfacePrice; +use App\Controller\SalesByRegion; +use App\Controller\SalesByGranularity; use Symfony\Component\Validator\Constraints as Assert; @@ -14,17 +16,90 @@ use Symfony\Component\Validator\Constraints as Assert; * * @ORM\Entity * @ApiResource( - * collectionOperations={ + * collectionOperations = { * "get", - * "average_surface_price"={ - * "method"="GET", - * "path"="/property_sales/average_surface_price", - * "controller"=AverageSurfacePrice::class, - * "pagination_enabled"=false, - * "read"=false, + * "average_surface_price" = { + * "method" = "GET", + * "path" = "/property_sales/average_surface_price", + * "controller" = AverageSurfacePrice::class, + * "pagination_enabled" = false, + * "read" = false, + * "openapi_context" = { + * "summary" = "Gets the average surface price for mutations", + * "description" = "Gets the average surface price for mutations", + * "read" = "false" + * } * }, + * "sales_by_region" = { + * "method" = "GET", + * "path" = "/property_sales/sales_by_region", + * "controller" = SalesByRegion::class, + * "pagination_enabled" = false, + * "read" = false, + * "openapi_context" = { + * "summary" = "Gets the sales grouped by region", + * "description" = "Gets the sales grouped by region", + * "read" = "false", + * "parameters" = { + * { + * "in" = "query", + * "name" = "year", + * "required" = true, + * "schema" = { + * "type" = "integer", + * "format" = "int64" + * }, + * "example" = 2015 + * } + * } + * } + * }, + * "sales_by_granularity" = { + * "method" = "GET", + * "path" = "/property_sales/sales_by_granularity", + * "controller" = SalesByGranularity::class, + * "pagination_enabled" = false, + * "read" = false, + * "openapi_context" = { + * "summary" = "Gets the sales on a given interval with a given granularity", + * "description" = "Gets the sales on a given interval with a given granularity", + * "read" = "false", + * "parameters"= { + * { + * "in" = "query", + * "name" = "granularity", + * "required" = true, + * "schema" = { + * "type" = "string", + * "enum" = {"year", "month", "day"} + * }, + * "example" = "year" + * }, + * { + * "in" = "query", + * "name" = "date_start", + * "required" = true, + * "schema" = { + * "type" = "string", + * "format" = "full-date" + * }, + * "example" = "2015-12-24" + * }, + * { + * "in" = "query", + * "name" = "date_end", + * "required" = true, + * "schema" = { + * "type" = "string", + * "format" = "full-date" + * }, + * "example" = "2019-12-24" + * } + * } + * } + * } * }, - * itemOperations={}, + * itemOperations={} * ) */ class PropertySale -- GitLab