feat(api) : add machine count to category related items endpoint

This commit is contained in:
2026-04-04 17:29:39 +02:00
parent 8b02f821d3
commit 14ed38704f
2 changed files with 191 additions and 1 deletions

View File

@@ -0,0 +1,142 @@
<?php
declare(strict_types=1);
namespace App\Controller;
use App\Entity\Composant;
use App\Entity\MachineComponentLink;
use App\Entity\MachinePieceLink;
use App\Entity\MachineProductLink;
use App\Entity\Piece;
use App\Entity\Product;
use App\Enum\ModelCategory;
use App\Repository\ModelTypeRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
#[Route('/api/model_types/{id}')]
final class ModelTypeRelatedItemsController extends AbstractController
{
public function __construct(
private readonly ModelTypeRepository $modelTypes,
private readonly EntityManagerInterface $em,
) {}
#[Route('/related-items', name: 'api_model_type_related_items', methods: ['GET'])]
public function relatedItems(string $id): JsonResponse
{
$this->denyAccessUnlessGranted('ROLE_VIEWER');
$modelType = $this->modelTypes->find($id);
if (!$modelType) {
return new JsonResponse(
['message' => 'Catégorie introuvable.'],
Response::HTTP_NOT_FOUND,
);
}
$items = match ($modelType->getCategory()) {
ModelCategory::COMPONENT => $this->fetchComposantsWithMachineCount($id),
ModelCategory::PIECE => $this->fetchPiecesWithMachineCount($id),
ModelCategory::PRODUCT => $this->fetchProductsWithMachineCount($id),
};
return new JsonResponse($items);
}
/**
* @return list<array{id: string, name: string, reference: null|string, machineCount: int}>
*/
private function fetchComposantsWithMachineCount(string $modelTypeId): array
{
$qb = $this->em->createQueryBuilder();
$qb->select(
'c.id',
'c.name',
'c.reference',
'COALESCE(c.referenceAuto, c.reference) as displayReference',
'COUNT(DISTINCT mcl.id) as machineCount',
)
->from(Composant::class, 'c')
->leftJoin(MachineComponentLink::class, 'mcl', 'WITH', 'mcl.composant = c')
->where('c.typeComposant = :modelTypeId')
->setParameter('modelTypeId', $modelTypeId)
->groupBy('c.id', 'c.name', 'c.reference', 'c.referenceAuto')
->orderBy('c.name', 'ASC')
;
return $this->formatResults($qb->getQuery()->getArrayResult());
}
/**
* @return list<array{id: string, name: string, reference: null|string, machineCount: int}>
*/
private function fetchPiecesWithMachineCount(string $modelTypeId): array
{
$qb = $this->em->createQueryBuilder();
$qb->select(
'p.id',
'p.name',
'p.reference',
'COALESCE(p.referenceAuto, p.reference) as displayReference',
'COUNT(DISTINCT mpl.id) as machineCount',
)
->from(Piece::class, 'p')
->leftJoin(MachinePieceLink::class, 'mpl', 'WITH', 'mpl.piece = p')
->where('p.typePiece = :modelTypeId')
->setParameter('modelTypeId', $modelTypeId)
->groupBy('p.id', 'p.name', 'p.reference', 'p.referenceAuto')
->orderBy('p.name', 'ASC')
;
return $this->formatResults($qb->getQuery()->getArrayResult());
}
/**
* @return list<array{id: string, name: string, reference: null|string, machineCount: int}>
*/
private function fetchProductsWithMachineCount(string $modelTypeId): array
{
$qb = $this->em->createQueryBuilder();
$qb->select(
'pr.id',
'pr.name',
'pr.reference',
'COUNT(DISTINCT mpl.id) as machineCount',
)
->from(Product::class, 'pr')
->leftJoin(MachineProductLink::class, 'mpl', 'WITH', 'mpl.product = pr')
->where('pr.typeProduct = :modelTypeId')
->setParameter('modelTypeId', $modelTypeId)
->groupBy('pr.id', 'pr.name', 'pr.reference')
->orderBy('pr.name', 'ASC')
;
return $this->formatResults($qb->getQuery()->getArrayResult());
}
/**
* @param array<int, array<string, mixed>> $rows
*
* @return list<array{id: string, name: string, reference: null|string, machineCount: int}>
*/
private function formatResults(array $rows): array
{
return array_values(array_map(
static fn (array $row): array => [
'id' => (string) $row['id'],
'name' => (string) ($row['name'] ?? ''),
'reference' => isset($row['displayReference']) && '' !== $row['displayReference']
? (string) $row['displayReference']
: (isset($row['reference']) && '' !== $row['reference'] ? (string) $row['reference'] : null),
'machineCount' => (int) $row['machineCount'],
],
$rows,
));
}
}