Files
Inventory/src/Controller/UsedInController.php
2026-04-04 17:25:43 +02:00

205 lines
6.7 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Controller;
use App\Entity\ComposantPieceSlot;
use App\Entity\ComposantProductSlot;
use App\Entity\MachineComponentLink;
use App\Entity\MachinePieceLink;
use App\Entity\MachineProductLink;
use App\Entity\PieceProductSlot;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Attribute\Route;
final class UsedInController extends AbstractController
{
public function __construct(
private readonly EntityManagerInterface $em,
) {}
#[Route('/api/composants/{id}/used-in', name: 'api_composant_used_in', methods: ['GET'])]
public function composantUsedIn(string $id): JsonResponse
{
$this->denyAccessUnlessGranted('ROLE_VIEWER');
return new JsonResponse([
'machines' => $this->findMachinesUsingComposant($id),
]);
}
#[Route('/api/pieces/{id}/used-in', name: 'api_piece_used_in', methods: ['GET'])]
public function pieceUsedIn(string $id): JsonResponse
{
$this->denyAccessUnlessGranted('ROLE_VIEWER');
return new JsonResponse([
'machines' => $this->findMachinesUsingPiece($id),
'composants' => $this->findComposantsUsingPiece($id),
]);
}
#[Route('/api/products/{id}/used-in', name: 'api_product_used_in', methods: ['GET'])]
public function productUsedIn(string $id): JsonResponse
{
$this->denyAccessUnlessGranted('ROLE_VIEWER');
return new JsonResponse([
'machines' => $this->findMachinesUsingProduct($id),
'composants' => $this->findComposantsUsingProduct($id),
'pieces' => $this->findPiecesUsingProduct($id),
]);
}
/**
* @return list<array{id: string, name: null|string, site: null|array{id: string, name: null|string}}>
*/
private function findMachinesUsingComposant(string $id): array
{
$qb = $this->em->createQueryBuilder();
$qb->select('m.id', 'm.name', 's.id as siteId', 's.name as siteName')
->from(MachineComponentLink::class, 'mcl')
->join('mcl.machine', 'm')
->leftJoin('m.site', 's')
->where('mcl.composant = :id')
->setParameter('id', $id)
->groupBy('m.id', 'm.name', 's.id', 's.name')
->orderBy('m.name', 'ASC')
;
return $this->formatMachineResults($qb->getQuery()->getArrayResult());
}
/**
* @return list<array{id: string, name: null|string, site: null|array{id: string, name: null|string}}>
*/
private function findMachinesUsingPiece(string $id): array
{
$qb = $this->em->createQueryBuilder();
$qb->select('m.id', 'm.name', 's.id as siteId', 's.name as siteName')
->from(MachinePieceLink::class, 'mpl')
->join('mpl.machine', 'm')
->leftJoin('m.site', 's')
->where('mpl.piece = :id')
->setParameter('id', $id)
->groupBy('m.id', 'm.name', 's.id', 's.name')
->orderBy('m.name', 'ASC')
;
return $this->formatMachineResults($qb->getQuery()->getArrayResult());
}
/**
* @return list<array{id: string, name: null|string, site: null|array{id: string, name: null|string}}>
*/
private function findMachinesUsingProduct(string $id): array
{
$qb = $this->em->createQueryBuilder();
$qb->select('m.id', 'm.name', 's.id as siteId', 's.name as siteName')
->from(MachineProductLink::class, 'mpl')
->join('mpl.machine', 'm')
->leftJoin('m.site', 's')
->where('mpl.product = :id')
->setParameter('id', $id)
->groupBy('m.id', 'm.name', 's.id', 's.name')
->orderBy('m.name', 'ASC')
;
return $this->formatMachineResults($qb->getQuery()->getArrayResult());
}
/**
* @return list<array{id: string, name: null|string}>
*/
private function findComposantsUsingPiece(string $id): array
{
$qb = $this->em->createQueryBuilder();
$qb->select('c.id', 'c.name')
->from(ComposantPieceSlot::class, 'cps')
->join('cps.composant', 'c')
->where('cps.selectedPiece = :id')
->setParameter('id', $id)
->groupBy('c.id', 'c.name')
->orderBy('c.name', 'ASC')
;
return array_values(array_map(
static fn (array $row): array => [
'id' => $row['id'],
'name' => $row['name'],
],
$qb->getQuery()->getArrayResult(),
));
}
/**
* @return list<array{id: string, name: null|string}>
*/
private function findComposantsUsingProduct(string $id): array
{
$qb = $this->em->createQueryBuilder();
$qb->select('c.id', 'c.name')
->from(ComposantProductSlot::class, 'cps')
->join('cps.composant', 'c')
->where('cps.selectedProduct = :id')
->setParameter('id', $id)
->groupBy('c.id', 'c.name')
->orderBy('c.name', 'ASC')
;
return array_values(array_map(
static fn (array $row): array => [
'id' => $row['id'],
'name' => $row['name'],
],
$qb->getQuery()->getArrayResult(),
));
}
/**
* @return list<array{id: string, name: null|string}>
*/
private function findPiecesUsingProduct(string $id): array
{
$qb = $this->em->createQueryBuilder();
$qb->select('p.id', 'p.name')
->from(PieceProductSlot::class, 'pps')
->join('pps.piece', 'p')
->where('pps.selectedProduct = :id')
->setParameter('id', $id)
->groupBy('p.id', 'p.name')
->orderBy('p.name', 'ASC')
;
return array_values(array_map(
static fn (array $row): array => [
'id' => $row['id'],
'name' => $row['name'],
],
$qb->getQuery()->getArrayResult(),
));
}
/**
* @param array<int, array<string, mixed>> $rows
*
* @return list<array{id: string, name: null|string, site: null|array{id: string, name: null|string}}>
*/
private function formatMachineResults(array $rows): array
{
return array_values(array_map(
static fn (array $row): array => [
'id' => $row['id'],
'name' => $row['name'],
'site' => $row['siteId']
? ['id' => $row['siteId'], 'name' => $row['siteName']]
: null,
],
$rows,
));
}
}