<?php
namespace App\Controller\Quote;
use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
use ApiPlatform\Core\Exception\ResourceClassNotSupportedException;
use App\DataProvider\Quote\QuoteCollectionDataProvider;
use App\Handler\Quote\CrudQuoteHandler;
use App\Model\CustomerFile\CustomerFile;
use App\Model\Exception\ProspectNotFoundException;
use App\Model\Exception\QuoteNotFoundException;
use App\Model\Product\Product;
use App\Model\Response\DataPersisterResponse;
use App\Service\ApiWebServiceFilterBuilder\PaginationFilterBuilder;
use App\V4\Model\Quote\Quote;
use App\V4\Service\Pdf\PdfGenerator;
use App\V4\Voters\QuoteVoter;
use Doctrine\Common\Annotations\AnnotationException;
use Lexik\Bundle\JWTAuthenticationBundle\TokenExtractor\TokenExtractorInterface;
use Psr\Cache\InvalidArgumentException;
use ReflectionException;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Serializer\Exception\ExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Twig\Error\LoaderError;
use Twig\Error\SyntaxError;
final class QuoteController extends AbstractController
{
/**
* @var ItemDataProviderInterface
*/
private $itemDataProvider;
/**
* @var PdfGenerator
*/
private $pdfGenerator;
public function __construct(ItemDataProviderInterface $itemDataProvider, PdfGenerator $pdfGenerator)
{
$this->itemDataProvider = $itemDataProvider;
$this->pdfGenerator = $pdfGenerator;
}
/**
* @Route("/api/quote", name="quote_edit_route", methods={"PUT"})
* @Security("is_granted('ROLE_ADMIN') or (is_granted('QUOTE_CUD'))", message="not_allowed_edit_quote")
*
* @throws AnnotationException
* @throws ClientExceptionInterface
* @throws DecodingExceptionInterface
* @throws ExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface
* @throws ProspectNotFoundException
* @throws QuoteNotFoundException
* @throws InvalidArgumentException
* @throws ReflectionException
*/
public function editQuote(Request $request, CrudQuoteHandler $crudQuoteHandler)
{
$jsonResponse = new DataPersisterResponse($crudQuoteHandler->handlePut(
$request->get('request') ? $request->get('request') : $request->getContent(),
$request->files->all()
));
return $jsonResponse;
}
/**
* @Route("/api/quotes", name="quote_get_route", methods={"GET"})
* @Security("is_granted('ROLE_USER')",
* message="not_allowed_get_quote")
*
* @param Request $request
* @param QuoteCollectionDataProvider $collectionDataProvider
*
* @return JsonResponse
*
* @throws ClientExceptionInterface
* @throws DecodingExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ServerExceptionInterface
* @throws TransportExceptionInterface
*/
public function listQuote(Request $request, QuoteCollectionDataProvider $collectionDataProvider): JsonResponse
{
return new JsonResponse(
$collectionDataProvider->getRawCollection(
$collectionDataProvider->completeSearchBodyFromRequest($request, [])
),
Response::HTTP_OK
);
}
/**
* @Route("/api/quote/{id}/generatepdf", name="quote_generate_pdf", methods={"POST"})
*
* @throws ClientExceptionInterface
* @throws LoaderError
* @throws RedirectionExceptionInterface
* @throws ResourceClassNotSupportedException
* @throws ServerExceptionInterface
* @throws SyntaxError
* @throws TransportExceptionInterface
*/
public function generateQuotePdf(Request $request, string $id): JsonResponse
{
$this->denyAccessUnlessGranted(QuoteVoter::QUOTE_LINES_EXPORT_PDF);
$quote = $this->itemDataProvider->getItem(Quote::class, $id);
if (!$quote instanceof Quote) {
return new JsonResponse(['code' => Response::HTTP_NOT_FOUND, 'errorMessage' => 'not_found'], Response::HTTP_NOT_FOUND);
}
$quoteData = json_decode($request->getContent(), true);
if (empty($quoteData['templateId']) || empty($quoteData['customerId']) || !$id) {
return new JsonResponse(['code' => Response::HTTP_BAD_REQUEST, 'errorMessage' => 'generate_quote_pdf_missing_template_or_id'], 400);
}
if (!isset($quoteData[PdfGenerator::OPTION_MODE])) {
$quoteData[PdfGenerator::OPTION_MODE] = PdfGenerator::MODE_REPLACE;
}
$base64File = $this->pdfGenerator->generatePdfContentByTemplate($quote, $quoteData['templateId'], $quoteData);
$response = $this->pdfGenerator->generatePdfWithTemplateForQuote($quote, $base64File, $quoteData[PdfGenerator::OPTION_MODE], $quoteData['templateId']);
return new JsonResponse($response);
}
/**
* @Route("/api/quote/{id}/productsfiles", name="quote_products_files", methods={"GET"})
*
* @param CollectionDataProviderInterface $collectionDataProvider
* @param TokenExtractorInterface $tokenExtractor
* @param RequestStack $requestStack
* @param RouterInterface $router
* @param Request $request
* @param string $id
*
* @return JsonResponse
*
* @throws ResourceClassNotSupportedException
*/
public function getQuoteProductsFiles(
CollectionDataProviderInterface $collectionDataProvider,
TokenExtractorInterface $tokenExtractor,
RequestStack $requestStack,
RouterInterface $router,
Request $request,
string $id
): JsonResponse {
$products = $collectionDataProvider->getCollection(Product::class, null, [
'filters' => [
PaginationFilterBuilder::ACTIVATE_PAGNIATION_KEY => false,
'quoteIds' => [$id],
],
]);
$allFiles = [];
/** @var Product $product */
foreach ($products as $product) {
/** @var CustomerFile[] $files */
$files = $collectionDataProvider->getCollection(CustomerFile::class, null, [
'filters' => [
'productId' => $product->getId(),
],
]);
// Filter logo
foreach ($files as $key => $file) {
if ($file->getId() === $product->getImageId()) {
continue;
}
$token = $tokenExtractor->extract($requestStack->getMasterRequest());
$allFiles[] = [
'name' => $file->getRealFileName(),
'type' => $file->getMimeType(),
'source' => $router->generate(
'files_download_route',
['id' => $file->getId()],
UrlGeneratorInterface::ABSOLUTE_URL
),
];
}
}
return new JsonResponse(['files' => $allFiles]);
}
}