src/Controller/Website/DddController.php line 40

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Controller\Website;
  4. use App\Client\ErpClient;
  5. use App\Form\Website\Type\PurchaseQuoteRequest\DddPurchaseQuoteRequestType;
  6. use App\Helper\Partner\PartnerHelper;
  7. use App\Repository\Cabin\CabinCategoryRepository;
  8. use App\Service\Ddd\DddPageContext;
  9. use App\Service\Ddd\DddPageContextBuilder;
  10. use App\Service\Ddd\DddQuoteRequestPayloadFactory;
  11. use App\Service\Ddd\DddStepContext;
  12. use App\Service\Ddd\DddStepContextResolver;
  13. use Croisiland\CommonBundle\Model\ProspectRequestModel;
  14. use Doctrine\ORM\NonUniqueResultException;
  15. use Exception;
  16. use Sulu\Component\Content\Compat\StructureInterface;
  17. use Symfony\Component\Form\FormError;
  18. use Symfony\Component\HttpFoundation\JsonResponse;
  19. use Symfony\Component\HttpFoundation\Request;
  20. use Symfony\Component\HttpFoundation\RequestStack;
  21. use Symfony\Component\HttpFoundation\Response;
  22. use Symfony\Component\Routing\Annotation\Route;
  23. class DddController extends BaseWebsiteController
  24. {
  25. public function __construct(
  26. private readonly DddPageContextBuilder $dddPageContextBuilder,
  27. private readonly DddStepContextResolver $dddStepContextResolver,
  28. private readonly DddQuoteRequestPayloadFactory $dddQuoteRequestPayloadFactory,
  29. private readonly RequestStack $requestStack,
  30. private readonly PartnerHelper $partnerHelper,
  31. private readonly CabinCategoryRepository $cabinCategoryRepository,
  32. private readonly ErpClient $erpClient,
  33. ) {
  34. }
  35. public function indexAction(StructureInterface $structure, $preview = false, $partial = false)
  36. {
  37. $templateVars = array_merge($this->getSharedLayoutFormViews(), [
  38. 'quoteRequestForm' => $this->createForm(DddPurchaseQuoteRequestType::class)->createView(),
  39. ]);
  40. $request = $this->requestStack->getCurrentRequest();
  41. if ($request !== null) {
  42. $pageContext = $this->dddPageContextBuilder->buildFromCruiseId(
  43. $request->query->getInt('croisiere', 0)
  44. );
  45. if ($pageContext !== null) {
  46. $templateVars = array_merge($templateVars, $pageContext->toTemplateVars());
  47. }
  48. if ($request->request->get('ddd') !== null) {
  49. $quoteRequestForm = $this->createForm(
  50. DddPurchaseQuoteRequestType::class
  51. );
  52. $quoteRequestForm->handleRequest($request);
  53. }
  54. }
  55. return $this->renderStructure(
  56. $structure,
  57. $templateVars,
  58. $preview,
  59. $partial
  60. );
  61. }
  62. #[Route('/ddd/quote-request/form', name: 'website_ddd_quote_request_form', methods: ['POST'])]
  63. public function quoteFormAction(Request $request): Response
  64. {
  65. $cruiseId = $request->query->getInt('croisiere', 0);
  66. if ($cruiseId <= 0) {
  67. return new Response('Missing cruise id', Response::HTTP_BAD_REQUEST);
  68. }
  69. $pageContext = $this->dddPageContextBuilder->buildFromCruiseId($cruiseId);
  70. if ($pageContext === null) {
  71. return new Response('Cruise not found', Response::HTTP_NOT_FOUND);
  72. }
  73. $this->dddStepContextResolver->resolve($request, 4, $pageContext->cruise);
  74. $success = false;
  75. $form = $this->createForm(
  76. DddPurchaseQuoteRequestType::class
  77. );
  78. $form->handleRequest($request);
  79. if ($form->isSubmitted() && $form->isValid()) {
  80. try {
  81. $this->erpClient->createQuoteRequest($form->getData());
  82. $success = true;
  83. }
  84. catch (Exception $exception) {
  85. if ($exception->getCode() === Response::HTTP_NOT_ACCEPTABLE) {
  86. $form->addError(new FormError($exception->getMessage()));
  87. }
  88. else {
  89. $form->addError(new FormError("Une erreur est survenue lors du traitement de votre demande. Merci de réessayer plus tard."));
  90. }
  91. }
  92. }
  93. if (!$request->isXmlHttpRequest()) {
  94. $referer = $request->headers->get('Referer');
  95. if (is_string($referer) && $referer !== '') {
  96. if ($success) {
  97. $separator = str_contains($referer, '?') ? '&' : '?';
  98. return $this->redirect($referer.$separator.'quoteConfirmation=1');
  99. }
  100. return $this->redirect($referer);
  101. }
  102. }
  103. if ($success) {
  104. $payload = $this->dddQuoteRequestPayloadFactory->createFromValidatedForm(
  105. $form,
  106. $request,
  107. $cruiseId
  108. );
  109. return $this->render('pages/_includes/ddd/_quote_form_ajax_fragment.html.twig', [
  110. 'success' => true,
  111. ]);
  112. }
  113. $formQueryParams = array_filter([
  114. 'croisiere' => $cruiseId,
  115. 'type' => $request->query->get('type'),
  116. 'subtype' => $request->query->get('subtype'),
  117. 'atmosphere' => $request->query->get('atmosphere'),
  118. 'category' => $request->query->get('category'),
  119. 'cabin' => $request->query->get('cabin'),
  120. 'price' => $request->query->get('price'),
  121. ], static fn ($value) => $value !== null && $value !== '');
  122. return $this->render('pages/_includes/ddd/_quote_form.html.twig', [
  123. 'quoteRequestForm' => $form->createView(),
  124. 'formQueryParams' => $formQueryParams,
  125. ]);
  126. }
  127. #[Route('/ddd/fragments/step/{step}', name: 'website_ddd_step_fragment', methods: ['GET'])]
  128. public function stepFragmentAction(Request $request, int $step): JsonResponse
  129. {
  130. $cruiseId = $request->query->getInt('croisiere', 0);
  131. if ($cruiseId <= 0) {
  132. return new JsonResponse([
  133. 'success' => false,
  134. 'error' => 'Missing cruise id',
  135. ], Response::HTTP_BAD_REQUEST);
  136. }
  137. $pageContext = $this->dddPageContextBuilder->buildFromCruiseId($cruiseId);
  138. if ($pageContext === null) {
  139. return new JsonResponse([
  140. 'success' => false,
  141. 'error' => 'Cruise not found',
  142. ], Response::HTTP_NOT_FOUND);
  143. }
  144. $templateByStep = [
  145. 1 => 'pages/_includes/ddd/steps/_step_subtype_cabin.html.twig',
  146. 2 => 'pages/_includes/ddd/steps/_step_atmosphere.html.twig',
  147. 3 => 'pages/_includes/ddd/steps/_step_category_cabin.html.twig',
  148. 4 => 'pages/_includes/ddd/steps/_step_quote_form.html.twig',
  149. ];
  150. if (!isset($templateByStep[$step])) {
  151. return new JsonResponse([
  152. 'success' => false,
  153. 'error' => 'Step not implemented yet',
  154. 'step' => $step,
  155. ], Response::HTTP_NOT_IMPLEMENTED);
  156. }
  157. $dddContext = $this->dddStepContextResolver->resolve($request, $step, $pageContext->cruise);
  158. $templateVars = [
  159. ...$pageContext->toTemplateVars(),
  160. 'dddContext' => $dddContext,
  161. ...$dddContext->toTemplateVars(),
  162. ];
  163. if ($step === 4) {
  164. $quoteRequestForm = $this->createForm(
  165. DddPurchaseQuoteRequestType::class,
  166. $this->buildQuoteFormInitialData($request, $dddContext, $pageContext)
  167. );
  168. $quoteRequestForm->handleRequest($request);
  169. $templateVars['quoteRequestForm'] = $quoteRequestForm->createView();
  170. }
  171. $html = $this->renderView($templateByStep[$step], $templateVars);
  172. return new JsonResponse([
  173. 'success' => true,
  174. 'step' => $step,
  175. 'context' => [
  176. 'cruiseId' => $dddContext->cruiseId,
  177. 'cabinTypeId' => $dddContext->cabinTypeId,
  178. 'cabinSubTypeId' => $dddContext->cabinSubTypeId,
  179. 'atmosphereId' => $dddContext->atmosphereId,
  180. 'categoryId' => $dddContext->categoryId,
  181. 'cabinCode' => $dddContext->cabinCode,
  182. ],
  183. 'html' => $html,
  184. ]);
  185. }
  186. /**
  187. * @param Request $request
  188. * @param DddStepContext $dddContext
  189. * @param DddPageContext $pageContext
  190. * @return ProspectRequestModel
  191. * @throws NonUniqueResultException
  192. */
  193. private function buildQuoteFormInitialData(Request $request, DddStepContext $dddContext, DddPageContext $pageContext): ProspectRequestModel
  194. {
  195. $price = $request->query->get('price');
  196. return (new ProspectRequestModel())
  197. ->setCruise($pageContext->cruise)
  198. ->setPartner($this->partnerHelper->getCurrentPartner())
  199. ->setPrice((float) $price)
  200. ->setCabinCategory(
  201. $this->cabinCategoryRepository->find($dddContext->categoryId)
  202. )
  203. ;
  204. }
  205. }