src/Controller/DeliveryController.php line 54

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Delivery;
  4. use App\Entity\Customer;
  5. use App\Entity\DeliveryArticle;
  6. use App\Entity\DeliveryHistoryStatus;
  7. use App\Entity\Document;
  8. use App\Entity\Packaging;
  9. use App\Entity\Tracking;
  10. use App\Entity\User;
  11. use App\Entity\VehicleType;
  12. use App\Enum\DeliveryStatusEnum;
  13. use App\Enum\PriceComplementaryEnum;
  14. use App\Event\DeliveryWorkflowEvent;
  15. use App\Form\DeliveryArticleFormType;
  16. use App\Form\DeliveryRecipientType;
  17. use App\Form\DeliverySenderType;
  18. use App\Repository\DeliveryStatusRepository;
  19. use App\Service\DeliveryService;
  20. use App\Service\FileUploader;
  21. use App\Workflow\Transition\DeliveryTransition;
  22. use Doctrine\Persistence\ManagerRegistry;
  23. use Symfony\Bridge\Doctrine\Form\Type\EntityType;
  24. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  25. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  26. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  27. use Symfony\Component\Form\Extension\Core\Type\CollectionType;
  28. use Symfony\Component\Form\Extension\Core\Type\SubmitType;
  29. use Symfony\Component\HttpFoundation\File\UploadedFile;
  30. use Symfony\Component\HttpFoundation\Request;
  31. use Symfony\Component\HttpFoundation\Response;
  32. use Symfony\Component\Routing\Annotation\Route;
  33. class DeliveryController extends AbstractController
  34. {
  35. #[Route('/delivery', name: 'app_delivery', methods: ['GET', 'POST'])]
  36. public function index(Request $request): Response
  37. {
  38. if ($request->getMethod() == Request::METHOD_POST) {
  39. $isPro = (int)$request->request->get('isPro');
  40. $send = (int)$request->request->get('send');
  41. return $this->redirectToRoute('delivery_create', ['isPro' => $isPro, 'send' => $send]);
  42. }
  43. return $this->render('delivery/index.html.twig', [
  44. 'controller_name' => 'DeliveryController',
  45. ]);
  46. }
  47. #[Route('/delivery/create', name: 'delivery_create', methods: ['GET', 'POST'])]
  48. public function createDelivery(
  49. DeliveryService $deliveryService,
  50. ManagerRegistry $doctrine,
  51. Request $request,
  52. DeliveryStatusRepository $deliveryStatusRepository
  53. ): Response {
  54. $entityManager = $doctrine->getManager();
  55. $isPro = (bool)$request->query->get('isPro');
  56. $send = (bool)$request->query->get('send');
  57. /**
  58. * @var ?User $user
  59. */
  60. $user = $this->getUser();
  61. if (!$user) {
  62. throw new \Exception('User not found', Response::HTTP_NOT_FOUND);
  63. }
  64. $customer = $doctrine->getRepository(Customer::class)->find($user->getId());
  65. //TODO interdire aux livreurs
  66. if (!$customer) {
  67. return $this->redirectToRoute('accueil_vitrine');
  68. }
  69. $status = $deliveryStatusRepository->findOneBy(['name' => DeliveryStatusEnum::IN_PROGRESS->value]);
  70. if (!$status) {
  71. throw new \Exception('Status not found', Response::HTTP_NOT_FOUND);
  72. }
  73. $history = (new DeliveryHistoryStatus())->setStatus($status);
  74. $delivery = new Delivery();
  75. $delivery->setRequester($customer)
  76. ->setIsPro($isPro)
  77. ->setIsSend($send)
  78. ->addDeliveryHistoryStatus($history);
  79. $form = $this->createFormBuilder($delivery)
  80. ->add('sender', DeliverySenderType::class, [
  81. 'isPro' => $isPro,
  82. 'send' => $send
  83. ])
  84. ->getForm();
  85. $form->handleRequest($request);
  86. if ($form->isSubmitted() && $form->isValid()) {
  87. /** @var Delivery $delivery */
  88. $delivery = $form->getData();
  89. //TODO add autocomplete to get position
  90. $sender = $delivery->getSender();
  91. if (!$sender) {
  92. throw new \Exception('Sender not found', Response::HTTP_NOT_FOUND);
  93. }
  94. $tracking = (new Tracking())->setLongitude('2.4383')->setLatitude('48.7780');
  95. $sender->setPosition($tracking);
  96. $delivery->setSender($sender);
  97. $entityManager->persist($delivery);
  98. $entityManager->flush();
  99. $deliveryService->setDeliverySessionData($isPro, $send, $delivery->getId());
  100. return $this->redirectToRoute('add_delivery_recipient', [
  101. 'id' => $delivery->getId()
  102. ]);
  103. }
  104. return $this->render('delivery/create.html.twig', [
  105. 'form' => $form->createView()
  106. ]);
  107. }
  108. #[Route('/delivery/add/recipient/{id}', name: 'add_delivery_recipient', methods: ['GET', 'POST'])]
  109. public function addDeliveryRecipient(ManagerRegistry $doctrine, Request $request, Delivery $delivery): Response
  110. {
  111. $entityManager = $doctrine->getManager();
  112. $form = $this->createFormBuilder($delivery)
  113. ->add('recipient', DeliveryRecipientType::class, [
  114. 'isPro' => $delivery->isPro(),
  115. 'send' => $delivery->isSend(),
  116. ])
  117. ->getForm();
  118. $form->handleRequest($request);
  119. if ($form->isSubmitted() && $form->isValid()) {
  120. /** @var Delivery $delivery */
  121. $delivery = $form->getData();
  122. $entityManager->flush();
  123. return $this->redirectToRoute('add_delivery_articles', [
  124. 'id' => $delivery->getId()
  125. ]);
  126. }
  127. return $this->render('delivery/addRecipient.html.twig', [
  128. 'form' => $form->createView()
  129. ]);
  130. }
  131. #[Route('/delivery/add/articles/{id}', name: 'add_delivery_articles', methods: ['GET', 'POST'])]
  132. public function addDeliveryArticles(ManagerRegistry $doctrine, Request $request, FileUploader $fileUploader, Delivery $delivery): Response
  133. {
  134. $entityManager = $doctrine->getManager();
  135. $isPro = $delivery->isPro();
  136. $send = $delivery->isSend();
  137. $form = $this->createFormBuilder($delivery)
  138. ->add('deliveryArticles', CollectionType::class, [
  139. 'entry_type' => DeliveryArticleFormType::class,
  140. 'entry_options' => [
  141. 'label' => false,
  142. 'isPro' => $isPro,
  143. 'send' => $send
  144. ],
  145. 'allow_add' => true,
  146. 'allow_delete' => false,
  147. 'by_reference' => false
  148. ]);
  149. if (!$isPro || $send) {
  150. $form->add('packaging', ChoiceType::class, [
  151. 'choices' => [
  152. 'Oui' => true,
  153. 'Non' => false
  154. ],
  155. 'mapped' => false
  156. ]);
  157. }
  158. $form = $form->add('save', SubmitType::class, [
  159. 'attr' => ['class' => 'btn']
  160. ])
  161. ->getForm();
  162. $form->handleRequest($request);
  163. if ($form->isSubmitted() && $form->isValid()) {
  164. $packaging = (!$isPro || $send) ? $form->get('packaging')->getData() : 0;
  165. $articlesForm = $form->get('deliveryArticles');
  166. foreach ($articlesForm as $articleForm) {
  167. if ($isPro && !$send) {
  168. //Upload documents
  169. $documentsForm = $articleForm->get('documents');
  170. foreach ($documentsForm as $documentForm) {
  171. /** @var ?UploadedFile @documentFile */
  172. $documentFile = $documentForm->get('realName')->getData();
  173. /** @var Document $document */
  174. $document = $documentForm->getData();
  175. if ($documentFile) {
  176. $document = $fileUploader->updateDocument($document, $documentFile);
  177. }
  178. }
  179. } else {
  180. //Upload photo
  181. /** @var ?UploadedFile @photo */
  182. $photo = $articleForm->get('photo')->getData();
  183. /** @var DeliveryArticle $article */
  184. $article = $articleForm->getData();
  185. if ($photo) {
  186. $photoFileName = $fileUploader->upload($photo);
  187. $article->setPhoto($photoFileName);
  188. }
  189. }
  190. }
  191. /** @var Delivery $delivery */
  192. $delivery = $form->getData();
  193. $entityManager->flush();
  194. if ($packaging) {
  195. return $this->redirectToRoute('add_delivery_packaging', ['id' => $delivery->getId()]);
  196. }
  197. return $this->redirectToRoute('add_delivery_vehicle_type', ['id' => $delivery->getId()]);
  198. }
  199. return $this->render('delivery/addArticles.html.twig', [
  200. 'form' => $form->createView()
  201. ]);
  202. }
  203. #[Route('/delivery/add/packaging/{id}', name: 'add_delivery_packaging', methods: ['GET', 'POST'])]
  204. public function addDeliveryPackaging(ManagerRegistry $doctrine, Request $request, Delivery $delivery): Response
  205. {
  206. $entityManager = $doctrine->getManager();
  207. $form = $this->createFormBuilder($delivery)
  208. ->add('packaging', EntityType::class, [
  209. 'class' => Packaging::class,
  210. 'choice_label' => 'name',
  211. ])
  212. ->add('save', SubmitType::class)
  213. ->getForm();
  214. $form->handleRequest($request);
  215. if ($form->isSubmitted() && $form->isValid()) {
  216. /** @var Delivery $delivery */
  217. $delivery = $form->getData();
  218. $entityManager->flush();
  219. return $this->redirectToRoute('add_delivery_vehicle_type', ['id' => $delivery->getId()]);
  220. }
  221. return $this->render('delivery/addPackaging.html.twig', [
  222. 'form' => $form->createView()
  223. ]);
  224. }
  225. #[Route('/delivery/add/vehicle_type/{id}', name: 'add_delivery_vehicle_type', methods: ['GET', 'POST'])]
  226. public function addDeliveryVehicleType(ManagerRegistry $doctrine, Request $request, Delivery $delivery, EventDispatcherInterface $eventDispatcher): Response
  227. {
  228. $entityManager = $doctrine->getManager();
  229. $form = $this->createFormBuilder($delivery)
  230. ->add('vehicleType', EntityType::class, [
  231. 'class' => VehicleType::class,
  232. 'choice_label' => 'name',
  233. ])
  234. ->add('save', SubmitType::class)
  235. ->getForm();
  236. $form->handleRequest($request);
  237. if ($form->isSubmitted() && $form->isValid()) {
  238. /** @var Delivery $delivery */
  239. $delivery = $form->getData();
  240. $entityManager->flush();
  241. $eventDispatcher->dispatch(new DeliveryWorkflowEvent($delivery, DeliveryTransition::FINALIZATION), DeliveryWorkflowEvent::NAME);
  242. return $this->redirectToRoute('delivery_validation', ['id' => $delivery->getId()]);
  243. }
  244. return $this->render('delivery/addVehicleType.html.twig', [
  245. 'form' => $form->createView()
  246. ]);
  247. }
  248. #[Route('/delivery/validation/{id}', name: 'delivery_validation', methods: ['GET'])]
  249. public function deliveryValidation(ManagerRegistry $doctrine, Delivery $delivery, DeliveryService $deliveryService): Response
  250. {
  251. $entityManager = $doctrine->getManager();
  252. /** TODO : get meteo */
  253. $meteoFee = 2;
  254. $electricFee = $deliveryService->getPrice(PriceComplementaryEnum::ELECTRIC);
  255. $tva = $deliveryService->getTVA();
  256. /** TODO : get distance */
  257. $distance = 2500;
  258. $sousTotalHT = $deliveryService->getSousTotalHT($distance, $meteoFee);
  259. $cancellationFees = $deliveryService->getPrice(PriceComplementaryEnum::CANCELLATION_FEES);
  260. $returnFees = 0;
  261. $totalHT = $deliveryService->getTotalHT($delivery, $distance, $meteoFee, $electricFee);
  262. $tvaCost = $totalHT * $tva;
  263. $totals = [
  264. 'sousTotalHT' => $sousTotalHT,
  265. 'thermic' => $deliveryService->getThermicCost($delivery),
  266. 'electric' => $deliveryService->isElectric($delivery) ? $electricFee : 0,
  267. 'options' => $deliveryService->getOptions($delivery, $sousTotalHT),
  268. 'discount' => $deliveryService->getDiscount(),
  269. 'cancellationFees' => $cancellationFees,
  270. 'returnFees' => $returnFees,
  271. 'totalHT' => $totalHT,
  272. 'tva' => $tvaCost,
  273. 'totalTTC' => $totalHT + $tvaCost
  274. ];
  275. $delivery->setDeliveryTotals($totals);
  276. $entityManager->flush();
  277. return $this->render(
  278. 'delivery/validation.html.twig',
  279. array_merge(['delivery' => $delivery], $totals)
  280. );
  281. }
  282. #[Route('/delivery/payment/choose/{id}', name: 'add_delivery_payment_choose', methods: ['GET'])]
  283. public function addDeliveryPaymentChoose(Delivery $delivery): Response
  284. {
  285. return $this->render('delivery/paymentChoose.html.twig', [
  286. 'delivery' => $delivery
  287. ]);
  288. }
  289. #[Route('/delivery/cancel/{id}', name: 'cancel_delivery', methods: ['GET'])]
  290. public function cancelDelivery(Delivery $delivery, EventDispatcherInterface $eventDispatcher): Response
  291. {
  292. $eventDispatcher->dispatch(new DeliveryWorkflowEvent($delivery, DeliveryTransition::CANCELATION), DeliveryWorkflowEvent::NAME);
  293. return $this->redirectToRoute('app_course_index');
  294. }
  295. }