src/Service/Basket.php line 71

Open in your IDE?
  1. <?php
  2. namespace App\Service;
  3. use App\Controller\Page\CheckoutController;
  4. use App\Entity\Airport;
  5. use App\Entity\Booking;
  6. use App\Entity\BookingPerson;
  7. use App\Entity\Game;
  8. use App\Entity\Mail;
  9. use App\Entity\MainBooker;
  10. use App\Entity\MainBookerHome;
  11. use App\Entity\StadiumCategory;
  12. use App\Entity\User;
  13. use App\Entity\VRExtraCosts;
  14. use App\Generator\Invoice;
  15. use App\Model\Basket as BasketModel;
  16. use App\Model\Pyton\Accommodation\AccommodationWrapper;
  17. use App\Model\Pyton\AccommodationReceipt;
  18. use App\Model\Pyton\Basket as PytonBasket;
  19. use App\Model\Pyton\Flight\Leg;
  20. use App\Model\Pyton\Flight\Trip;
  21. use App\Model\Pyton\FlightReceipt;
  22. use App\Sendgrid\MailerInterface;
  23. use App\Util\StringToEntityUtil;
  24. use DateTime;
  25. use Doctrine\ORM\EntityManagerInterface;
  26. use Exception;
  27. use FOS\UserBundle\Util\TokenGeneratorInterface;
  28. use JMS\Serializer\SerializerInterface;
  29. use Money\Currency;
  30. use Money\Money;
  31. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  32. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  33. final class Basket
  34. {
  35.     public const SESSION_BASKET_NAME 'pyton_basket_%s';
  36.     public function __construct(
  37.         private readonly SessionInterface $session,
  38.         private readonly Pyton $pyton,
  39.         private readonly EntityManagerInterface $entityManager,
  40.         private readonly TokenGeneratorInterface $tokenGenerator,
  41.         private readonly MailerInterface $mailer,
  42.         private readonly Invoice $invoiceGenerator,
  43.         private readonly SerializerInterface $serializer,
  44.         private readonly ParameterBagInterface $parameterBag,
  45.         private readonly StringToEntityUtil $stringToEntityUtil,
  46.     ) {
  47.     }
  48.     /**
  49.      * @return string
  50.      */
  51.     public function getSessionId()
  52.     {
  53.         if (!$this->session->getId()) {
  54.             $this->session->start();
  55.         }
  56.         return $this->session->getId();
  57.     }
  58.     /**
  59.      * Returns the basket from the session, otherwise  return empty BasketModel.
  60.      */
  61.     public function getBasket(Game $matchbool $createPytonBasket false): ?BasketModel
  62.     {
  63.         /** @var BasketModel $basket */
  64.         $basket $this->session->get(sprintf(self::SESSION_BASKET_NAME$match->getId()), new BasketModel());
  65.         $basket->setPrice($this->calculatePrice($basket$match));
  66.         if ($createPytonBasket) {
  67.             if (!$basket->getPytonBasket()) {
  68.                 $basket->setPytonBasket(new PytonBasket());
  69.             }
  70.             if (!$basket->getPytonBasket()->getBasketId()) {
  71.                 try {
  72.                     $response json_decode($this->pyton->createBasket(), true);
  73.                     if (!empty($response['BasketId'])) {
  74.                         $basket->getPytonBasket()->setBasketId($response['BasketId']);
  75.                     }
  76.                 } catch (Exception $exception) {
  77.                 }
  78.             }
  79.         }
  80.         return $basket;
  81.     }
  82.     /**
  83.      * @return $this
  84.      */
  85.     public function setBasket(Game $matchBasketModel $basket): self
  86.     {
  87.         // TODO:: https://symfony.com/doc/current/components/http_foundation/session_configuration.html#session-metadata
  88.         $this->session->set(sprintf(self::SESSION_BASKET_NAME$match->getId()), $basket);
  89.         return $this;
  90.     }
  91.     /**
  92.      * @throws UnknownCurrencyException
  93.      *
  94.      * @return Money
  95.      */
  96.     private function calculatePrice(BasketModel $basketGame $match)
  97.     {
  98.         $adults $basket->getAdults() ?? 1;
  99.         $children $basket->getChildren() ?? 0;
  100.         $price 0;
  101.         $price += ($match->getMatchTicketPrice()->getAmount() * ($adults $children));
  102.         if ($accommodation $this->getSelectedAccommodation($basket)) {
  103.             $price += ($accommodation->getPriceDetails()->getPrice()->getValue() * ($adults $children));
  104.         }
  105.         if ($basketCategory $basket->getStadiumCategory()) {
  106.             foreach ($match->getCategories() as $matchCategory) {
  107.                 if ($matchCategory->getCategory()->getId() === $basketCategory) {
  108.                     $price += ($matchCategory->getPrice()->getAmount() * ($adults $children));
  109.                 }
  110.             }
  111.         }
  112.         if ($flight $this->getSelectedTrip($basket)) {
  113.             $roundedFlightValue round($flight->getPrice()->getValue() / 100) * 100;
  114.             $price += ($roundedFlightValue * ($adults $children));
  115.         }
  116. //        if ($discountTotal = $basket->getDiscountTotal()) {
  117. //            $price -= (int) $basket->getDiscountTotal()->getAmount();
  118. //        }
  119.         return new Money($price, new Currency('EUR'));
  120.     }
  121.     public function getSelectedAccommodation(BasketModel $basket): ?AccommodationWrapper
  122.     {
  123.         if (!$basket->getAccommodation() || !$basket->getAccomodationList()) {
  124.             return null;
  125.         }
  126.         /** @var AccommodationWrapper $accommodation */
  127.         foreach ($basket->getAccomodationList() as $accommodation) {
  128.             if ($basket->getAccommodation() === $accommodation->getAccommodation()->getId()) {
  129.                 // At this point the accommodation still has (cron)cached price-details;
  130.                 // therefor we need to update it with the actual chosen travel-data
  131.                 $accommodation->getPriceDetails()
  132.                     ->setDepartureDate($basket->getDepartDate())
  133.                     ->setDurationInDays($basket->getReturnDate()->diff($basket->getDepartDate())->days 1);
  134.                 return $accommodation;
  135.             }
  136.         }
  137.         return null;
  138.     }
  139.     /**
  140.      * @return AccommodationWrapper|null
  141.      */
  142.     public function getSelectedTrip(BasketModel $basket): ?Trip
  143.     {
  144.         if (!$basket->getFlight() || !$basket->getFlightList()) {
  145.             return null;
  146.         }
  147.         foreach ($basket->getFlightList()->getFlights()->getTrips() as $trip) {
  148.             /** @var Trip $trip */
  149.             if ($basket->getFlight() === $trip->getId()) {
  150.                 return $trip;
  151.             }
  152.         }
  153.         return null;
  154.     }
  155.     /**
  156.      * @throws Exception
  157.      *
  158.      * @return AccommodationReceipt|null
  159.      */
  160.     public function getSelectedAccommodationRooms(BasketModel $basket)
  161.     {
  162.         $selectedRooms = [];
  163.         if (!$basket->getPytonBasket()) {
  164.             return $selectedRooms;
  165.         }
  166.         $accomodationReceiptArray json_decode($basket->getPytonBasket()->getAccommodationReceipt(), true);
  167. //        dd($accomodationReceiptArray);
  168.         if (isset($accomodationReceiptArray['Receipt']['Accommodation'])) {
  169.             foreach ($accomodationReceiptArray['Receipt']['Accommodation']['Units'] as $val => $unit) {
  170.                 if ($unit['Allotment']['Chosen'] > 0) {
  171.                     $selectedRooms[] = $unit;
  172.                 }
  173.             }
  174.         } else {
  175.             return 'nrf';
  176.         }
  177.         return $selectedRooms;
  178.     }
  179.     /**
  180.      * @throws Exception
  181.      */
  182.     public function getSelectedAccommodationForPytonReceipt(BasketModel $basket): ?AccommodationReceipt
  183.     {
  184.         $accommodationReceipt = new AccommodationReceipt();
  185.         $accommodation $this->getSelectedAccommodation($basket);
  186.         if (null === $accommodation) {
  187.             return $accommodationReceipt;
  188.         }
  189.         $accommodationReceipt->addAccommodation($accommodation);
  190.         for ($i 1$i <= $basket->getAdults(); ++$i) {
  191.             $accommodationReceipt->addTraveller(new DateTime('-30 years'));
  192.         }
  193.         for ($i 1$i <= $basket->getChildren(); ++$i) {
  194.             $accommodationReceipt->addTraveller(new DateTime('-24 years')); //Fault in Pyton, should be 16
  195.         }
  196.         return $accommodationReceipt;
  197.     }
  198.     /**
  199.      * @throws Exception
  200.      */
  201.     public function getSelectedFlightForPytonReceipt(BasketModel $basket): ?FlightReceipt
  202.     {
  203.         if (!$basket->getFlight() || !$basket->getFlightList()) {
  204.             return null;
  205.         }
  206.         $flightReceipt = new FlightReceipt();
  207.         /** @var Trip $trip */
  208.         foreach ($basket->getFlightList()->getFlights()->getTrips() as $trip) {
  209.             if ($trip->getId() === $basket->getFlight()) {
  210.                 $flightReceipt->addTrip($trip);
  211.             }
  212.         }
  213.         for ($i 1$i <= $basket->getAdults(); ++$i) {
  214.             $flightReceipt->addTraveller(new DateTime('-30 years'));
  215.         }
  216.         for ($i 1$i <= $basket->getChildren(); ++$i) {
  217.             $flightReceipt->addTraveller(new DateTime('-24 years')); //Fault in Pyton, should be 16
  218.         }
  219.         if (empty($flightReceipt->getTrips())) {
  220.             return null;
  221.         }
  222.         /** @var Trip $trip */
  223.         foreach ($flightReceipt->getTrips() as $trip) {
  224.             foreach ($trip->getInbound()->getLegIds() as $legId) {
  225.                 /** @var Leg $leg */
  226.                 foreach ($basket->getFlightList()->getFlights()->getLegs() as $leg) {
  227.                     if ($leg->getId() === $legId) {
  228.                         $flightReceipt->addLeg($leg);
  229.                         if (!$flightReceipt->getFirstDeparture()) {
  230.                             $flightReceipt->setFirstDeparture($leg->getArrive());
  231.                         }
  232.                     }
  233.                 }
  234.             }
  235.             foreach ($trip->getOutbound()->getLegIds() as $legId) {
  236.                 /** @var Leg $leg */
  237.                 foreach ($basket->getFlightList()->getFlights()->getLegs() as $leg) {
  238.                     if ($leg->getId() === $legId) {
  239.                         $flightReceipt->addLeg($leg);
  240.                         if (!$flightReceipt->getFinalDestination()) {
  241.                             $flightReceipt->setFinalDestination($leg->getArrive());
  242.                         }
  243.                     }
  244.                 }
  245.             }
  246.         }
  247.         return $flightReceipt;
  248.     }
  249.     /**
  250.      * @throws UnknownCurrencyException
  251.      *
  252.      * @return int|null
  253.      */
  254.     public function getTicketCount(Game $match)
  255.     {
  256.         $basket $this->getBasket($match);
  257.         return $basket->getAdults() + $basket->getChildren();
  258.     }
  259.     /**
  260.      * @throws Exception
  261.      *
  262.      * @return Booking
  263.      */
  264.     public function saveBasket(Game $matchUser $userfloat $paidAmount 0)
  265.     {
  266.         $basket $this->getBasket($match);
  267.         $booking = new Booking();
  268.         $booking->setUser($user);
  269.         $booking->setMatch($match);
  270.         $booking->setPiggyParticipate((bool) $this->session->get(CheckoutController::PIGGY_PARTICIPATE_KEY));
  271.         $booking->setPiggyReferral($this->session->get(CheckoutController::PIGGY_REFERRAL_KEY));
  272.         if ($basket->getStadiumCategory() && $stadiumCategory $this->entityManager->getRepository(
  273.                 StadiumCategory::class
  274.             )->find($basket->getStadiumCategory())) {
  275.             $booking->setStadiumCategory($stadiumCategory);
  276.         }
  277.         $booking
  278.             ->setPrice($basket->getPrice())
  279.             ->setDepartDate($basket->getDepartDate())
  280.             ->setReturnDate($basket->getReturnDate())
  281.             ->setAccommodation($basket->getAccommodation())
  282.             ->setFlight($basket->getFlight())
  283.             ->setAdults($basket->getAdults())
  284.             ->setChildren($basket->getChildren())
  285.             ->setRooms($basket->getRooms())
  286. //            ->setTravelInsurance($basket->isTravelInsurance())
  287. //            ->setCancellationBasicInsurance($basket->isCancellationBasicInsurance())
  288. //            ->setCancellationAllInsurance($basket->isCancellationAllInsurance())
  289.             ->setTotalInsuranceCosts($basket->getFullPrice()->subtract($basket->getPrice()));
  290.         /* @var VRExtraCosts $extraCost */
  291.         // basket.extraCosts is filled in ExtracostsService.calculateExtraCosts
  292.         foreach ($basket->getExtraCosts() as $bookingExtraCost) {
  293.             $VRExtraCostRepository $this->entityManager->getRepository(VRExtraCosts::class);
  294.             $unmanagedVRExtraCost $bookingExtraCost->getExtraCost();
  295.             $bookingExtraCost->setExtraCost(
  296.                 $VRExtraCostRepository->find(
  297.                     $unmanagedVRExtraCost->getId()
  298.                 )
  299.             );
  300.             $booking->addExtraCost($bookingExtraCost);
  301.         }
  302.         $booking->setTotalInsuranceCosts($basket->getCalculatedExtraPrices());
  303.         // chosenAccommodation opslaan
  304.         $chosenAccommodation $this->serializer->toArray(
  305.             $this->getSelectedAccommodationRooms($basket)
  306.         ); // $this->basketService->getSelectedAccommodationRooms($basket);
  307.         $booking->setChosenAccommodation($chosenAccommodation);
  308.         if ($basket->getDiscountTotal() && $basket->getDiscountReceipt()) {
  309.             $booking->setDiscountTotal($basket->getDiscountTotal());
  310.             $booking->setDiscountReceipt($basket->getDiscountReceipt());
  311.         }
  312.         if ($basket->getAirport() && $airport $this->entityManager
  313.                 ->getRepository(Airport::class)->find($basket->getAirport())) {
  314.             $booking->setAirport($airport);
  315.         }
  316.         if ($basket->getFlight()) {
  317.             $flightData = [];
  318.             foreach ($basket->getFlightListNormalized() as $flight) {
  319.                 if ($flight['tripId'] === $basket->getFlight()) {
  320.                     $flightData $flight;
  321.                     break;
  322.                 }
  323.             }
  324.             $booking->setFlightInbound(
  325.                 $this->serializer->toArray($flightData['inbound'])
  326.             );
  327.             $booking->setFlightOutbound(
  328.                 $this->serializer->toArray($flightData['outbound'])
  329.             );
  330.         }
  331.         $basketMainBooker $basket->getTravelersData()['mainBooker'];
  332.         if (!$mainBooker $this->entityManager->getRepository(MainBooker::class)->findOneBy(['user' => $user->getId()]
  333.         )) {
  334.             $mainBooker = new MainBooker();
  335.             $mainBooker
  336.                 ->setCompany($basketMainBooker['company'])
  337.                 ->setAddress($basketMainBooker['address'])
  338.                 ->setGender($basketMainBooker['gender'])
  339.                 ->setHouseNumber($basketMainBooker['houseNumber'])
  340.                 ->setHouseNumberAttribute($basketMainBooker['houseNumberAttribute'])
  341.                 ->setFirstNames($basketMainBooker['firstNames'])
  342.                 ->setLastName($basketMainBooker['lastName'])
  343.                 ->setZipcode($basketMainBooker['zipcode'])
  344.                 ->setCity($basketMainBooker['city'])
  345.                 ->setCountry($basketMainBooker['country'])
  346.                 ->setDob($basketMainBooker['dob'])
  347.                 ->setMobile($basketMainBooker['mobile'])
  348.                 ->setEmail($basketMainBooker['email'])
  349.                 ->setUser($user);
  350.         }
  351.         $booking->setMainBooker($mainBooker);
  352.         foreach ($basket->getTravelersData()['persons'] as $personData) {
  353.             $person = new BookingPerson();
  354.             $person
  355.                 ->setBooking($booking)
  356.                 ->setGender($personData['gender'])
  357.                 ->setFirstNames($personData['firstNames'])
  358.                 ->setLastName($personData['lastName'])
  359.                 ->setDob($personData['dob'])
  360.                 ->setCountry($personData['country']);
  361.             $booking->addPerson($person);
  362.         }
  363.         $mainBookerHomeData $basket->getTravelersData()['mainBookerHome'];
  364.         $mainBookerHome = new mainBookerHome();
  365.         $mainBookerHome
  366.             ->setGender($mainBookerHomeData['gender'])
  367.             ->setFirstName($mainBookerHomeData['firstName'])
  368.             ->setLastName($mainBookerHomeData['lastName'])
  369.             ->setMobile($mainBookerHomeData['mobile']);
  370.         $booking->setMainBookerHome($mainBookerHome);
  371.         $booking->setPaid(new Money($paidAmount 100, new Currency('EUR')));
  372.         $this->entityManager->persist($booking);
  373.         $this->entityManager->flush();
  374.         $this->invoiceGenerator->generateInvoiceForNewBooking($booking$paidAmount 100);
  375.         return $booking;
  376.     }
  377.     /**
  378.      * @throws \Twig\Error\LoaderError
  379.      * @throws \Twig\Error\RuntimeError
  380.      * @throws \Twig\Error\SyntaxError
  381.      */
  382.     public function createUser(Game $match): User
  383.     {
  384.         $basket $this->getBasket($match);
  385.         $userRepository $this->entityManager->getRepository(User::class);
  386.         $email $basket->getTravelersData()['mainBooker']['email'];
  387.         $username mb_substr($email0mb_strpos($email'@'));
  388.         if ($user $userRepository->findOneBy(['email' => $email])) {
  389.             return $user;
  390.         }
  391.         $user = new User();
  392.         $user
  393.             ->setEnabled(true)
  394.             ->setEmail($email)
  395.             ->setRoles(['ROLE_SITE_USER']);
  396.         while (!empty($userRepository->findOneBy(['username' => $username]))) {
  397.             $username .= rand(0100);
  398.         }
  399.         $user->setUsername($username);
  400.         // generate password
  401.         $password mb_substr($this->tokenGenerator->generateToken(), 08);
  402.         $user->setPlainPassword($password);
  403.         $this->entityManager->persist($user);
  404.         $this->entityManager->flush();
  405.         $mail $this->getMail('site_newuser_mail');
  406.         $this->mailer->mail(
  407.             $mail,
  408.             'noreply@voetbalretour.nl',
  409.             [$basket->getTravelersData()['mainBooker']['email']],
  410.             [
  411.                 'name' => $basket->getTravelersData()['mainBooker']['firstNames'],
  412.                 'password' => $password,
  413.                 'email' => $basket->getTravelersData()['mainBooker']['email'],
  414.             ],
  415.             []
  416.         );
  417. //        $message = (new Swift_Message())
  418. //            ->setFrom('info@voetbalretour.nl')
  419. //            ->setTo($basket->getTravelersData()['mainBooker']['email'])
  420. //            ->setSubject('Account aangemaakt')
  421. //            ->setBody($this->twig->render('mail/account_created.html.twig', [
  422. //                'password' => $password
  423. //            ]), 'text/html')
  424. //        ;
  425. //
  426. //        $this->mailer->send($message);
  427.         return $user;
  428.     }
  429.     private function getMail(string $mailId): ?Mail
  430.     {
  431.         $mail $this->parameterBag->get($mailId);
  432.         return $this->stringToEntityUtil->stringToEntity(
  433.             $mail
  434.         );
  435.     }
  436.     public function test()
  437.     {
  438. //        $user = $this->entityManager->getRepository(User::class)->findOneBy(['email' => 'randy@getnoticed.nl']);
  439. //
  440. //        $mainbooker = $this->entityManager->getRepository(MainBooker::class)->findOneBy(['user' => $user->getId()]);
  441. //        dd($mainbooker);
  442.     }
  443. }