<?php
declare(strict_types=1);
namespace App\V4\Action\Quote;
use ApiPlatform\Core\DataPersister\DataPersisterInterface;
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
use ApiPlatform\Core\Exception\ResourceClassNotSupportedException;
use App\Service\Form\FormUtils;
use App\V4\DataPersister\AbstractWithoutRequestDataPersister;
use App\V4\Form\Type\Quote\QuoteType;
use App\V4\Model\Quote\Quote;
use App\V4\Service\Pdf\PdfGenerator;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpClient\Exception\ClientException;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Exception\ExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
/**
* Cette route a pour objectif d'autoriser un service
* externe à créer ou mettre à jours une entité (ici un devis)
* sans pour autant envoyer toutes les informations nécessaires
* et sans être contraint par les champs choisis par le client dans
* ses ViewOrders.
*
* @Route("/api/v4/quote/partial-persist", methods={"POST"})
* @Route("/api/v4/quote/{id}/partial-persist", methods={"PUT"})
*/
class PartialQuotePersistAction extends AbstractController
{
use FormUtils;
/**
* @var ItemDataProviderInterface
*/
private $itemDataProvider;
/**
* @var DataPersisterInterface
*/
private $dataPersister;
/**
* @var PdfGenerator
*/
private $pdfGenerator;
public function __construct(
ItemDataProviderInterface $itemDataProvider,
DataPersisterInterface $dataPersister,
PdfGenerator $pdfGenerator
) {
$this->itemDataProvider = $itemDataProvider;
$this->dataPersister = $dataPersister;
$this->pdfGenerator = $pdfGenerator;
}
/**
* @throws ExceptionInterface
* @throws ResourceClassNotSupportedException
* @throws TransportExceptionInterface
*/
public function __invoke(Request $request, ?string $id = null): JsonResponse
{
try {
$quote = $this->getEntity($id);
} catch (NotFoundHttpException $exception) {
return new JsonResponse(['error' => $exception->getMessage()], Response::HTTP_NOT_FOUND);
}
$form = $this->createForm(QuoteType::class, $quote, ['method' => null !== $id ? 'PUT' : 'POST']);
$form->submit($request->get($form->getName()), false);
if (!$form->isSubmitted() || !$form->isValid()) {
return new JsonResponse($this->convertFormErrorsToArrayV4($form), Response::HTTP_UNPROCESSABLE_ENTITY);
}
/** @var Quote $quote */
$quote = $form->getData();
$quote->getStatus()->setNormalizeAsIRI(true);
$this->dataPersister->persist($quote, [
AbstractWithoutRequestDataPersister::CONTEXT_IS_V4 => true,
]);
/** @var Quote $quote */
$quote = $this->itemDataProvider->getItem(Quote::class, $quote->getId());
$newPDF = $form->get('newPdf')->getData();
if ($newPDF) {
$this->pdfGenerator->generatePdfForQuote($quote, $newPDF);
}
return new JsonResponse([
'id' => $quote->getId(),
], Response::HTTP_CREATED);
}
private function getEntity(?string $id): Quote
{
if (null === $id) {
return new Quote();
}
try {
$quote = $this->itemDataProvider->getItem(Quote::class, $id);
if ($quote instanceof Quote) {
return $quote;
}
} catch (ClientException $e) {
}
throw new NotFoundHttpException("Quote #$id not found.");
}
}