diff --git a/api/.gitignore b/api/.gitignore index ae93018f235cd62b0e8536d2cce6dab6f898b1be..c930ddc07af540284ffa34249f9b1830b8f6d331 100644 --- a/api/.gitignore +++ b/api/.gitignore @@ -22,4 +22,3 @@ ### Migration ### /migrations/* -``` diff --git a/api/composer.json b/api/composer.json index 812930e4ef38d7aa75643aa4aa8a6e4896b16db6..992dbcf30f9fdc7bf3b01ad63cab6a9d7b1fb802 100644 --- a/api/composer.json +++ b/api/composer.json @@ -8,6 +8,7 @@ "api-platform/core": "^3.2", "beberlei/doctrineextensions": "dev-master", "doctrine/cache": "*", + "beberlei/doctrineextensions": "^1.3", "doctrine/doctrine-bundle": "^2.7", "doctrine/doctrine-migrations-bundle": "^3.2", "doctrine/orm": "^2.12", diff --git a/api/composer.lock b/api/composer.lock index f2a9d6ba930bc72d2efb09f3d3685fac6c4f4b5e..ed564cfd62f30f7eb57ffa5d8eab3aab0e2eebad 100644 --- a/api/composer.lock +++ b/api/composer.lock @@ -8,16 +8,16 @@ "packages": [ { "name": "api-platform/core", - "version": "v3.2.7", + "version": "v3.2.9", "source": { "type": "git", "url": "https://github.com/api-platform/core.git", - "reference": "f297d2192652a3acd2a644707740de8cb5069221" + "reference": "fe07a7f8196bfbefd2f8d02d0f7cacb6b1fbf527" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/core/zipball/f297d2192652a3acd2a644707740de8cb5069221", - "reference": "f297d2192652a3acd2a644707740de8cb5069221", + "url": "https://api.github.com/repos/api-platform/core/zipball/fe07a7f8196bfbefd2f8d02d0f7cacb6b1fbf527", + "reference": "fe07a7f8196bfbefd2f8d02d0f7cacb6b1fbf527", "shasum": "" }, "require": { @@ -69,9 +69,11 @@ "phpstan/phpstan-doctrine": "^1.0", "phpstan/phpstan-phpunit": "^1.0", "phpstan/phpstan-symfony": "^1.0", + "phpunit/phpunit": "^9.5", "psr/log": "^1.0 || ^2.0 || ^3.0", "ramsey/uuid": "^3.9.7 || ^4.0", "ramsey/uuid-doctrine": "^1.4 || ^2.0", + "sebastian/comparator": "<5.0", "soyuka/contexts": "v3.3.9", "soyuka/stubs-mongodb": "^1.0", "symfony/asset": "^6.1 || ^7.0", @@ -165,9 +167,66 @@ ], "support": { "issues": "https://github.com/api-platform/core/issues", - "source": "https://github.com/api-platform/core/tree/v3.2.7" + "source": "https://github.com/api-platform/core/tree/v3.2.9" + }, + "time": "2023-12-20T17:01:35+00:00" + }, + { + "name": "beberlei/doctrineextensions", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/beberlei/DoctrineExtensions.git", + "reference": "008f162f191584a6c37c03a803f718802ba9dd9a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/beberlei/DoctrineExtensions/zipball/008f162f191584a6c37c03a803f718802ba9dd9a", + "reference": "008f162f191584a6c37c03a803f718802ba9dd9a", + "shasum": "" + }, + "require": { + "doctrine/orm": "^2.7", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.14", + "nesbot/carbon": "*", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "symfony/yaml": "^4.2 || ^5.0", + "zf1/zend-date": "^1.12", + "zf1/zend-registry": "^1.12" + }, + "type": "library", + "autoload": { + "psr-4": { + "DoctrineExtensions\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Steve Lacey", + "email": "steve@steve.ly" + } + ], + "description": "A set of extensions to Doctrine 2 that add support for additional query functions available in MySQL, Oracle, PostgreSQL and SQLite.", + "keywords": [ + "database", + "doctrine", + "orm" + ], + "support": { + "source": "https://github.com/beberlei/DoctrineExtensions/tree/v1.3.0" }, - "time": "2023-11-30T13:51:25+00:00" + "time": "2020-11-29T07:37:23+00:00" }, { "name": "beberlei/doctrineextensions", diff --git a/api/config/packages/doctrine.yaml b/api/config/packages/doctrine.yaml index 7492f195c2b11bc451948f25b53e77fe8e3607fe..b4cd04c1bfdf40c20eeb8ae07e08d2838f64fd49 100644 --- a/api/config/packages/doctrine.yaml +++ b/api/config/packages/doctrine.yaml @@ -36,8 +36,6 @@ doctrine: least: DoctrineExtensions\Query\Postgresql\Least regexp_replace: DoctrineExtensions\Query\Postgresql\RegexpReplace - - when@test: doctrine: dbal: diff --git a/api/src/Controller/SaleController.php b/api/src/Controller/SaleController.php new file mode 100644 index 0000000000000000000000000000000000000000..cad37dcdee8370f85b3b741bdba45f41e6ceb508 --- /dev/null +++ b/api/src/Controller/SaleController.php @@ -0,0 +1,28 @@ +saleService = $saleService; + } + + public function __invoke(): JsonResponse + { + $result = $this->saleService->getMonthlyAveragePriceEvolution(); + + return $this->json($result); + } +} diff --git a/api/src/Dto/MonthlyAveragePriceEvolutionDto.php b/api/src/Dto/MonthlyAveragePriceEvolutionDto.php new file mode 100644 index 0000000000000000000000000000000000000000..fc489793a1899d0e949a3b794bc596300a54455c --- /dev/null +++ b/api/src/Dto/MonthlyAveragePriceEvolutionDto.php @@ -0,0 +1,17 @@ +month = $month; + $this->year = $year; + $this->averagePrice = $averagePrice; + } +} diff --git a/api/src/Entity/Sale.php b/api/src/Entity/Sale.php index 309712a4acb2c31df1c6ca1691be60aae86f813f..daf8ab9451fa0051b1e6c711619b62592eebdf7e 100644 --- a/api/src/Entity/Sale.php +++ b/api/src/Entity/Sale.php @@ -3,9 +3,10 @@ namespace App\Entity; use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\GetCollection; +use App\Controller\SaleController; use Doctrine\ORM\Mapping as ORM; use ApiPlatform\Metadata\Get; -use ApiPlatform\Metadata\GetCollection; use App\Controller\BarChartController; @@ -24,6 +25,18 @@ use App\Controller\BarChartController; ] )] + +#[ApiResource( + operations: [ + new GetCollection( + uriTemplate: '/sales/monthly_average_price_evolution', + controller: SaleController::class, + name: 'monthly_average_price_evolution' + ) + ] +)] + +/** A sale. */ #[ORM\Entity] class Sale { diff --git a/api/src/Service/SaleService.php b/api/src/Service/SaleService.php new file mode 100644 index 0000000000000000000000000000000000000000..6f2a07be684b1f9c3cae940052fa09ca794c205a --- /dev/null +++ b/api/src/Service/SaleService.php @@ -0,0 +1,41 @@ +entityManager = $entityManager; + } + + public function getMonthlyAveragePriceEvolution(): array + { + $queryBuilder = $this->entityManager->createQueryBuilder(); + + $result = $queryBuilder + ->select('MONTH(s.date) as month', 'YEAR(s.date) as year', 'AVG(CASE WHEN s.surface <> 0 THEN s.amount / s.surface ELSE 0 END) as average_price') + ->from(Sale::class, 's') + ->groupBy('year, month') + ->orderBy('year, month') + ->getQuery() + ->getResult(); + + $monthlyAveragePriceEvolutions = []; + foreach ($result as $row) { + $monthlyAveragePriceEvolutions[] = new MonthlyAveragePriceEvolutionDto( + (int)$row['month'], + (int)$row['year'], + (float)$row['average_price'] + ); + } + + return $monthlyAveragePriceEvolutions; + } +} diff --git a/insertions/script-2.mjs b/insertions/script-2.mjs index abf296dde3c46983aa254bf1cfa00b45a4b736d8..d3c2ba5c614c1698a5f8e697ca31a4d4567b9cc3 100644 --- a/insertions/script-2.mjs +++ b/insertions/script-2.mjs @@ -134,6 +134,6 @@ rl.on('line', (line) => { }); rl.on('close', () => { - const str = `INSERT INTO vente(date, value, region, surface) VALUES\n${lines.join(",\n")};`; + const str = `INSERT INTO sale(date, amount, region, surface) VALUES\n${lines.join(",\n")};`; console.log(str); });