Newer
Older
<?php
firdaous elhalafi
a validé
use App\Dto\BarChartInput;
use App\Dto\BarChartOutput;
use App\Dto\MonthlyAveragePriceEvolution;
use App\Dto\DonutChartOutput;
use App\Entity\Sale;
use Doctrine\ORM\EntityManagerInterface;
firdaous elhalafi
a validé
use Doctrine\ORM\Query;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
private EntityManagerInterface $entityManager;
firdaous elhalafi
a validé
private CacheInterface $cache;
firdaous elhalafi
a validé
public function __construct(EntityManagerInterface $entityManager, CacheInterface $cache)
$this->entityManager = $entityManager;
firdaous elhalafi
a validé
$this->cache = $cache;
firdaous elhalafi
a validé
public function updateTimeSerisCache(): void
firdaous elhalafi
a validé
$this->cache->delete('time_series');
}
public function updateBartChartCache($input): void
{
$cacheKey = 'bar-chart' . $input;
firdaous elhalafi
a validé
firdaous elhalafi
a validé
if ($this->cache->has($cacheKey)) {
$this->cache->delete($cacheKey);
}
firdaous elhalafi
a validé
firdaous elhalafi
a validé
public function updateDonutChartCache($year): void
firdaous elhalafi
a validé
{
firdaous elhalafi
a validé
$cacheKey = 'donut-chart' . $year;
firdaous elhalafi
a validé
firdaous elhalafi
a validé
if ($this->cache->has($cacheKey)) {
$this->cache->delete($cacheKey);
firdaous elhalafi
a validé
}
firdaous elhalafi
a validé
}
firdaous elhalafi
a validé
firdaous elhalafi
a validé
public function getTimeSeries(): array
{
return $this->cache->get('time_series', function (ItemInterface $item) {
try {
$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(Query::HYDRATE_ARRAY);
$monthlyAveragePriceEvolutions = [];
foreach ($result as $row) {
#$row['average_price'] = $row['total_surface'] != 0 ? $row['total_price'] / $row['total_surface'] : 0;
firdaous elhalafi
a validé
$monthlyAveragePriceEvolutions[] = new MonthlyAveragePriceEvolution(
(int)$row['month'],
(int)$row['year'],
(float)$row['average_price']
);
}
$item->expiresAfter(600);
return $monthlyAveragePriceEvolutions;
} catch (\Exception $exception){
throw $exception;
firdaous elhalafi
a validé
}
firdaous elhalafi
a validé
});
}
firdaous elhalafi
a validé
firdaous elhalafi
a validé
private function generateCacheKey(BarChartInput $input): string
{
$inputArray = [
'start' => $input->start,
'end' => $input->end,
'granularity' => $input->granularity,
];
$jsonEncodedInput = json_encode($inputArray);
$cleanedKey = preg_replace('/[^A-Za-z0-9]/', '_', $jsonEncodedInput);
return $cleanedKey;
}
firdaous elhalafi
a validé
firdaous elhalafi
a validé
public function getBarChartData(BarChartInput $input): array
{
$cacheKey = 'bar-chart' . $this->generateCacheKey($input);
return $this->cache->get($cacheKey, function (ItemInterface $item) use ($input) {
try {
$startDate = new \DateTime($input->start);
$endDate = new \DateTime($input->end);
$queryBuilder = $this->entityManager->createQueryBuilder();
$output = [];
if ($input->granularity == 'month') {
$result = $queryBuilder
->select('YEAR(s.date) as year', 'MONTH(s.date) as month', 'COUNT(s.id) as occurrences')
->from(Sale::class, 's')
->where('s.date BETWEEN :start AND :end')
->setParameter('start', $startDate)
->setParameter('end', $endDate)
->groupBy('year', 'month')
->orderBy('year')
->getQuery()
firdaous elhalafi
a validé
} else {
switch ($input->granularity) {
case 'day':
$groupByExpression = 's.date';
$groupByAlias = 'date';
$dateFormat = 'Y-m-d';
break;
case 'year':
$groupByExpression = 'YEAR(s.date)';
$groupByAlias = 'year';
$dateFormat = 'Y';
break;
default:
throw new \InvalidArgumentException('Invalid granularity');
}
$result = $queryBuilder
->select("{$groupByExpression} as {$groupByAlias}", 'COUNT(s.id) as occurrences')
->from(Sale::class, 's')
->where('s.date BETWEEN :start AND :end')
->setParameter('start', $startDate)
->setParameter('end', $endDate)
->groupBy("{$groupByAlias}")
->orderBy("{$groupByAlias}")
->getQuery()
firdaous elhalafi
a validé
}
foreach ($result as $row) {
if ($input->granularity == 'month') {
$month = $row['month'];
$year = $row['year'];
$dateString = $year . '-' . str_pad($month, 2, '0', STR_PAD_LEFT);
} else {
$dateString = $row[$groupByAlias] instanceof \DateTimeInterface ? $row[$groupByAlias]->format($dateFormat) : $row[$groupByAlias];
}
$output[] = new BarChartOutput($dateString, (int)$row['occurrences']);
}
$item->expiresAfter(600);
return $output;
} catch (\Exception $exception){
throw $exception;
}
});
firdaous elhalafi
a validé
}
public function getDonutChartData(string $year): array
{
firdaous elhalafi
a validé
$cacheKey = 'donut-chart' . $year;
return $this->cache->get($cacheKey, function (ItemInterface $item) use ($year) {
try {
$repository = $this->entityManager->getRepository(Sale::class);
$result = $repository->createQueryBuilder('s')
->select('s.region', 'COUNT(s.id) as occurrences')
->andWhere('YEAR(s.date) = :year')
->setParameter('year', $year)
->groupBy('s.region')
->getQuery()
firdaous elhalafi
a validé
$data = [];
foreach ($result as $row) {
$data[] = new DonutChartOutput(
$row['region'],
(int)$row['occurrences'],
);
firdaous elhalafi
a validé
}
$item->expiresAfter(600);
return $data;
}catch (\Exception $exception){
throw $exception;
}
});
firdaous elhalafi
a validé
}