Beispiel #1
0
    /**
     * @Route("/payment/process", name="booking_step_four_process", schemes={"https"})
     * @Method("POST")
     */
    public function processStepFourAction(Request $request)
    {
        $bookingManager = $this->getBookingManager();
        $hotel = $bookingManager->getHotel();
        $bankingInformationForm = $this->createForm('seh_customer_banking_information_type', $bankingInformationData = new BankingInformationData(), array('hotel' => $hotel));
        $bankingInformationForm->submit($request);
        $bookingUserSelection = $this->getCurrentBooking();
        $loyalty = false;
        $user = null;
        $em = $this->getDoctrine()->getManager();
        if (!$bookingUserSelection->isStepValid(3)) {
            $this->get('session')->getFlashBag()->add('notice', 'booking.session.unvalidated');
            return $this->redirect($this->generateUrl('booking_step_one', array('bookingId' => $bookingUserSelection->getBookingId())));
        }
        $bankingInformationForm = $this->createForm('seh_customer_banking_information_type', $bankingInformationData = new BankingInformationData(), array('hotel' => $bookingManager->getHotel()));
        $bankingInformationForm->submit($request);
        if ($bookingUserSelection->getProcessed()) {
            $bookingUserSelection->validateStep(4);
            $bookingManager->saveBookingToSession($bookingUserSelection);
            if ($request->isXmlHttpRequest()) {
                return new JsonResponse(true);
            }
            return $this->redirect($this->generateUrl('booking_step_five', array('bookingId' => $bookingUserSelection->getBookingId())));
        }
        $bankingInformationForm = $this->createForm('seh_customer_banking_information_type', $bankingInformationData = new BankingInformationData(), array('hotel' => $bookingManager->getHotel()));
        $bankingInformationForm->submit($request);
        $accountData = new AccountData();
        if ($bookingUserSelection->getAuthMode() == BookingUserSelection::BOOKING_AUTH_MOD_LOGGED_OFF) {
            $accountData = $bookingUserSelection->getNoAccountData();
        } elseif ($bookingUserSelection->getAuthMode() == BookingUserSelection::BOOKING_AUTH_MOD_NEW_ACCOUNT) {
            $newAccountData = $bookingUserSelection->getNewAccountData();
            $loyalty = $newAccountData->getLoyalty();
            $accountData = $newAccountData->getCustomer();
        } elseif ($bookingUserSelection->getAuthMode() == BookingUserSelection::BOOKING_AUTH_MOD_LOGGED_IN) {
            $accountData = new AccountData();
            $securityContext = $this->get('security.context');
            if ($securityContext->isGranted('IS_AUTHENTICATED_FULLY') or $securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
                $accountData->fromUser($user = $this->getUser());
                $loyalty = (bool) $user->getAccentCards();
            }
        }
        if ($bankingInformationForm->isValid()) {
            $currentLang = $this->get('bigfoot_context')->get('language');
            /** @var HttpClient $client */
            $client = $this->get('reservit')->getClient();
            $userSelection = $bookingUserSelection->getSelectedRooms();
            // Preparing Booking entity for later persisting
            $bookingEntity = new Booking();
            $brandContext = $this->container->get('bigfoot_context')->get('brand', true);
            $requestorId = $brandContext['parameters']['requestor.id'];
            // If Brand Extender
            if ($requestorId != 0 && $brandContext['value'] != strtolower($bookingManager->getHotel()->getBrand()->getArtsysID())) {
                $requestorId = 0;
            }
            $reservationIds = array(array('source' => $requestorId, 'value' => $bookingUserSelection->getBookingId(), 'type' => 16));
            $status = 'Initiate';
            $otaRequestName = 'HotelRes';
            if ($reservitId = $bookingUserSelection->getReservitId()) {
                $status = 'Modify';
                $otaRequestName = 'HotelResNotif';
                $reservationIds[] = array('source' => 'ReservIT', 'value' => $reservitId, 'type' => 18);
                $bookingEntity = $this->getRepository('SehBundle:Booking\\Booking')->findOneBy(array('reservitId' => $reservitId));
            }
            $bookingEntity->setCustomerLoyalty($loyalty);
            $bookingEntity->setHotel($bookingManager->getHotel());
            $bookingEntity->setStartDate($bookingUserSelection->getDatePaxData()->startingDate);
            $bookingEntity->setEndDate($bookingUserSelection->getDatePaxData()->endingDate);
            $bookingEntity->setTotalAmount($bookingUserSelection->getRoomsTotal() + $bookingUserSelection->getServicesTotal());
            $bookingEntity->setTotalAmountHt($bookingUserSelection->getRoomsTotalHt() + $bookingUserSelection->getServicesTotalHt());
            if ($user) {
                $bookingEntity->setCustomer($user);
            }
            $bookingEntity->setCustomerTitle($this->getRepository('SehBundle:Customer\\Title')->find($accountData->getTitle()));
            $bookingEntity->setCustomerFirstName($accountData->getFirstName());
            $bookingEntity->setCustomerLastName($accountData->getLastName());
            $bookingEntity->setCustomerEmail($accountData->getEmail());
            $bookingEntity->setCustomerPhone($accountData->getPhone());
            $bookingEntity->setCustomerCountry($accountData->getCountry());
            $bookingEntity->setCustomerLocale($accountData->getLang());
            $grandTotal = 0;
            $totalOnSpot = 0;
            $currency = 'EUR';
            $roomStays = array();
            $services = array();
            $roomsList = $bookingUserSelection->getRoomsList();
            // Each room the customer wants to book corresponds to a RoomStay tag
            foreach ($userSelection as $room) {
                $roomTypeCode = $room['roomType'];
                $roomRateCode = $room['roomRate'];
                // Preparing RoomTypes for the current RoomStay
                $roomTypes = array();
                $roomTypes[] = array('code' => $roomTypeCode, 'number_of_units' => 1);
                // Preparing RoomRates for the current RoomStay
                /** @var RoomRate $objRoomRate */
                $objRoomRate = $roomsList[$roomTypeCode]['roomRates'][$roomRateCode]['roomRate'];
                $roomRates = array();
                $total = 0;
                $roomRate = array('number_of_units' => 1, 'rate_plan_category' => $objRoomRate->getPlanCategory(), 'rate_plan_code' => $objRoomRate->getPlanCode(), 'start_date' => $objRoomRate->getStartDate(), 'end_date' => $objRoomRate->getEndDate(), 'rates' => array());
                /** @var Rate $rate */
                foreach ($objRoomRate->getRates() as $rate) {
                    $roomRate['rates'][] = array('start_date' => $rate->getStartDate()->format('Y-m-d'), 'end_date' => $rate->getEndDate()->format('Y-m-d'), 'base' => array('after_tax' => $rate->getBase()->getAfterTax(), 'currency' => $rate->getBase()->getCurrency()));
                    $total += $rate->getBase()->getAfterTax() * $rate->getUnitMultiplier();
                    $currency = $rate->getBase()->getCurrency();
                }
                $roomRates[] = $roomRate;
                // Preparing GuestCounts for the current RoomStay
                $guestCounts = array();
                $children = array();
                foreach ($room['children'] as $child) {
                    if (!isset($children[$child->age])) {
                        $children[$child->age] = 0;
                    }
                    $children[$child->age]++;
                }
                $guestCounts[] = array('age_code' => Container::_AGE_CODE_ADULT, 'count' => $room['nbAdults']);
                foreach ($children as $age => $nbChildren) {
                    $guestCounts[] = array('age_code' => Container::_AGE_CODE_CHILDREN, 'count' => $nbChildren, 'age' => $age);
                }
                // Preparing TimeSpan for the current RoomStay
                $startDate = clone $bookingUserSelection->getDatePaxData()->startingDate;
                if ($bookingUserSelection->getCheckinHour()) {
                    $startDate->add(new \DateInterval(sprintf('PT%sH', $bookingUserSelection->getCheckinHour())));
                }
                if ($bookingUserSelection->getCheckinMinute()) {
                    $startDate->add(new \DateInterval(sprintf('PT%sM', $bookingUserSelection->getCheckinMinute())));
                }
                // Saving room informations to database
                /** @var RoomType $roomType */
                $roomType = $roomsList[$roomTypeCode]['roomType'];
                $libelle = $roomType->getDescriptionForLocale(strtoupper($currentLang));
                $labels = explode('--N--', $libelle);
                $roomTitle = count($labels) > 1 ? $labels[1] : $labels[0];
                $roomSubtitle = count($labels) > 1 ? $labels[0] : '';
                $labels = explode('--D--', $roomTitle);
                $roomTitle = $labels[0];
                $roomDescription = count($labels) > 1 ? $labels[1] : '';
                $bookingEntity->addRoom($roomEntity = new Room());
                $roomEntity->setRoomTypeTitle($roomTitle);
                $roomEntity->setRoomTypeSubtitle($roomSubtitle);
                $roomEntity->setRoomTypeDescription($roomDescription);
                $roomEntity->setRoomTypeReservitId($roomTypeCode);
                if (!($roomRateDescription = $objRoomRate->getDescriptionForLocale(strtoupper($currentLang)))) {
                    $roomRateDescription = $this->container->get('translator')->trans('booking.one.rooms.room.default.name');
                }
                $roomEntity->setRoomRateTitle($roomRateDescription);
                $roomEntity->setRoomRateReservitId($objRoomRate->getPlanCode());
                $roomEntity->setNbAdults($room['nbAdults']);
                $roomEntity->setPrice($total);
                $roomEntity->setCurrency($currency);
                $servicesRph = array();
                /** @var \C2is\OTA\Model\HotelAvail\Response\Service $service */
                foreach ($room['optionalServices'] as $codeService => $service) {
                    if (isset($room['selectedServices'][$codeService]) and $selectedService = $room['selectedServices'][$codeService] and $selectedService['quantity'] and !$service->getMandatory() && ($selectedService['duration'] || !$service->getDetails()->getPricePerNight())) {
                        $servicePrice = $service->getPrice()->getOnSpot() ? $service->getPrice()->getOnSpot()->getAmount() : $service->getPrice()->getBase()->getAfterTax();
                        $serviceRph = count($services);
                        $serviceArray = array('rph' => $serviceRph, 'quantity' => $selectedService['quantity'], 'inventory_code' => $service->getInventoryCode(), 'pricing_type' => $service->getPricingType(), 'amount' => array('after_tax' => $service->getPrice()->getOnSpot() ? 0 : $servicePrice, 'currency' => $service->getPrice()->getBase()->getCurrency()));
                        $currency = $service->getPrice()->getBase()->getCurrency();
                        if ($service->getDetails()->getPricePerNight()) {
                            $duration = $selectedService['duration'] ?: 1;
                            $serviceArray['details'] = array('duration' => sprintf('P%sD', $duration));
                        }
                        $services[] = $serviceArray;
                        // Saves service information to database
                        $roomEntity->addService($serviceEntity = new Service());
                        $serviceEntity->setReservitId($codeService);
                        $serviceEntity->setName($service->getDescriptionForLocale(strtoupper($currentLang)));
                        $serviceEntity->setDuration($selectedService['duration']);
                        $serviceEntity->setQuantity($selectedService['quantity']);
                        $serviceEntity->setOnSpot((bool) $service->getPrice()->getOnSpot());
                        $serviceEntity->setCurrency($service->getPrice()->getBase()->getCurrency());
                        $serviceEntity->setMandatory(false);
                        $serviceEntity->setInclusive((bool) $service->getInclusive());
                        $serviceEntity->setPrice($servicePrice);
                        $servicePrice *= $selectedService['quantity'];
                        if ($service->getDetails()->getPricePerNight()) {
                            $servicePrice *= $selectedService['duration'];
                        }
                        if (!$service->getPrice()->getOnSpot()) {
                            $total += (double) $servicePrice;
                        } else {
                            $totalOnSpot += (double) $servicePrice;
                        }
                        $servicesRph[] = $serviceRph;
                    }
                }
                foreach ($room['mandatoryServices'] as $codeService => $service) {
                    $servicePrice = $service->getPrice()->getOnSpot() ? $service->getPrice()->getOnSpot()->getAmount() : $service->getPrice()->getBase()->getAfterTax();
                    $serviceRph = count($services);
                    $serviceArray = array('rph' => $serviceRph, 'inventory_code' => $service->getInventoryCode(), 'pricing_type' => $service->getPricingType(), 'amount' => array('after_tax' => $service->getPrice()->getOnSpot() ? 0 : $servicePrice, 'currency' => $service->getPrice()->getBase()->getCurrency()));
                    $currency = $service->getPrice()->getBase()->getCurrency();
                    $quantity = 0;
                    if ($service->getDetails()->getPricePerPax()) {
                        $quantity += $room['nbAdults'];
                        if ($service->getDetails()->getChild()) {
                            $quantity += count($room['children']);
                        }
                    }
                    $quantity = $quantity ?: 1;
                    $serviceArray['quantity'] = $quantity;
                    $duration = 0;
                    if ($service->getDetails()->getPricePerNight()) {
                        $duration = $bookingUserSelection->getDatePaxData()->getNbNights();
                        $serviceArray['details'] = array('duration' => sprintf('P%sD', $duration));
                    }
                    $services[] = $serviceArray;
                    // Saves service information to database
                    $roomEntity->addService($serviceEntity = new Service());
                    $serviceEntity->setReservitId($codeService);
                    $serviceEntity->setName($service->getDescriptionForLocale(strtoupper($currentLang)));
                    $serviceEntity->setDuration($duration);
                    $serviceEntity->setQuantity($quantity);
                    $serviceEntity->setOnSpot((bool) $service->getPrice()->getOnSpot());
                    $serviceEntity->setCurrency($service->getPrice()->getBase()->getCurrency());
                    $serviceEntity->setMandatory(true);
                    $serviceEntity->setPrice($servicePrice);
                    $servicePrice *= $quantity;
                    if ($service->getDetails()->getPricePerNight()) {
                        $servicePrice *= $duration;
                    }
                    if (!$service->getPrice()->getOnSpot()) {
                        $total += $servicePrice;
                    } else {
                        $totalOnSpot += (double) $servicePrice;
                    }
                    $servicesRph[] = $serviceRph;
                }
                $roomStayArray = array('room_types' => $roomTypes, 'room_rates' => $roomRates, 'timespan' => array('start' => $startDate, 'end' => $bookingUserSelection->getDatePaxData()->endingDate), 'hotel' => array('chain_code' => 51, 'code' => $bookingUserSelection->getHotelId()), 'guest_counts' => $guestCounts, 'total' => array('after_tax' => $total, 'currency' => $bookingUserSelection->getStayTaxCurrency()));
                if ($servicesRph) {
                    $roomStayArray['services'] = array();
                    foreach ($servicesRph as $serviceRph) {
                        $roomStayArray['services'][] = array('per_room' => true, 'rph' => $serviceRph);
                    }
                }
                $roomStays[] = $roomStayArray;
                $grandTotal += $total;
            }
            /** @var Customer\ReservitTitle $reservitTitle */
            $reservitTitle = $this->getRepository('SehBundle:Customer\\ReservitTitle')->createQueryBuilder('rt')->join('rt.titles', 't')->where('t.id = :titleId')->setParameter('titleId', $accountData->getTitle())->getQuery()->getOneOrNullResult();
            $comments = array();
            if ($comment = trim($bookingUserSelection->getComment())) {
                $comments[] = array('lang' => $accountData->getLang(), 'originator_code' => 0, 'viewable' => true, 'message' => $comment);
            }
            $guest = array('rph' => 0, 'profile_type' => 1, 'gender' => $reservitTitle->getValue(), 'person_name' => array('given_name' => $accountData->getFirstName(), 'surname' => $accountData->getLastName()), 'email' => $accountData->getEmail(), 'address' => array('country' => array('name' => Intl::getRegionBundle()->getCountryName($accountData->getCountry()), 'code' => $accountData->getCountry())), 'lang' => strtoupper($accountData->getLang()), 'comments' => $comments);
            if ($accountData->getPhone()) {
                $guest['telephone'] = array('country_access_code' => '33', 'number' => $accountData->getPhone());
            }
            $accentCardNumber = null;
            if ($bookingUserSelection->getAuthMode() == BookingUserSelection::BOOKING_AUTH_MOD_LOGGED_IN) {
                if ($user) {
                    /** @var Customer\AccentCard $card */
                    if ($card = $this->getRepository('SehBundle:Customer\\AccentCard')->findOneByUserMainCard($user)) {
                        $accentCardNumber = $card->getNumber();
                    }
                }
            } else {
                $accentCardNumber = $bookingUserSelection->getAccentCard();
            }
            if ($accentCardNumber) {
                $guest['loyalty'] = array('membership_id' => $accentCardNumber, 'program_id' => 'ACCENT');
            }
            $otaRequest = $this->container->get('ota.factory')->createRequest($otaRequestName, array('lang' => strtoupper($currentLang), 'status' => $status, 'requestor.id' => $requestorId, 'reservations' => array(array('room_stays' => $roomStays, 'guests' => array($guest), 'services' => $services, 'global_info' => array('total' => array('after_tax' => $grandTotal, 'currency' => $currency), 'guarantee' => array('guarantees_accepted' => array(array('card_type' => $bankingInformationData->getCardType(), 'card_number' => $bankingInformationData->getCardNumber(), 'card_expire_date' => sprintf('%s%s', $bankingInformationData->getExpireMonth(), $bankingInformationData->getExpireYear()), 'card_series_code' => $bankingInformationData->getSeriesCode(), 'card_holder_name' => $bankingInformationData->getHolderName()))), 'hotel_reservation_ids' => $reservationIds)))));
            $errors = array();
            try {
                $response = $client->send($otaRequest);
            } catch (\Exception $e) {
                $bookingUserSelection->setBankingInformationErrors(array('errors' => array($e->getMessage())));
                $bookingManager->saveBookingToSession($bookingUserSelection);
                return new RedirectResponse($this->generateUrl('booking_step_four', array('bookingId' => $bookingUserSelection->getBookingId())) . '#creditCardInfo');
            }
            /** @var HotelRes $hotelResData  */
            $hotelResData = $response->getMessage()->getData();
            if ($errors or $errors = $hotelResData->getErrors()) {
                $bookingUserSelection->setReservationErrors($errors);
                $bookingManager->saveBookingToSession($bookingUserSelection);
                $logger = $this->get('logger');
                /** @var BookingLogManager $bookingLogManager */
                $bookingLogManager = $this->get('seh.booking_log_manager');
                $jsonRoomStays = json_encode($roomStays);
                $jsonGuest = json_encode($guest);
                $jsonServices = json_encode($services);
                $contentToLog = <<<EOT
HotelID : {$bookingUserSelection->getHotelId()}
Start Date : {$bookingUserSelection->getDatePaxData()->startingDate->format('d/m/Y')}
End Date : {$bookingUserSelection->getDatePaxData()->endingDate->format('d/m/Y')}
Nb rooms : {$bookingUserSelection->getDatePaxData()->nbRooms}
Room Stay : {$jsonRoomStays}
Guest : {$jsonGuest}
Services : {$jsonServices}

EOT;
                $logFileName = $bookingLogManager->logXml($contentToLog . $response->getXml());
                $logger->error(sprintf('RIT error on HotelRes request. See "%s" log file for more details', $logFileName));
                return new RedirectResponse($this->generateUrl('booking_step_four', array('bookingId' => $bookingUserSelection->getBookingId())) . '#creditCardInfo');
            }
            $reservationIds = array();
            $prepaidPercent = 0;
            $prepaidAmount = 0;
            /** @var HotelReservation $reservation */
            foreach ($hotelResData->getReservations() as $reservation) {
                /** @var HotelReservationId $hotelReservationId */
                foreach ($reservation->getGlobalInfo()->getHotelReservationIds() as $hotelReservationId) {
                    if ($hotelReservationId->getSource() == 'ReservIT') {
                        $reservationIds[] = $hotelReservationId->getValue();
                    }
                }
                if ($payments = $reservation->getGlobalInfo()->getGuaranteesPayments()) {
                    /** @var GuaranteePayment $payment */
                    foreach ($payments as $payment) {
                        $prepaidPercent += (double) $payment->getAmountPercent()->getPercent();
                        $prepaidAmount += (double) $payment->getAmountPercent()->getAmount();
                    }
                }
            }
            $bookingUserSelection->setReservationIds($reservationIds);
            $bookingUserSelection->setReservitId(implode('-', $reservationIds));
            // Adding BookingUserSelection informations to Booking Entity
            $bookingEntity->setReservitId(implode('-', $reservationIds));
            $bookingEntity->setBookingId($bookingUserSelection->getBookingId());
            $bookingEntity->setBookingPolicies(implode('|', $bookingUserSelection->getBookingPolicies()));
            $bookingEntity->setCancelPolicies(implode('|', $bookingUserSelection->getCancelPolicies()));
            $bookingEntity->setStayTaxAmount($bookingUserSelection->getStayTaxAmount());
            $bookingEntity->setStayTaxCurrency($bookingUserSelection->getStayTaxCurrency());
            $prepaid = $prepaidPercent * ($bookingEntity->getTotalAmount() - $totalOnSpot) / 100 + $prepaidAmount;
            $bookingEntity->setTotalPrepaid($prepaid);
            $bookingEntity->setTotalOnSpot($bookingEntity->getTotalAmount() - $prepaid);
            if (!$bookingUserSelection->getPromoCodeError() && ($code = $bookingUserSelection->getDatePaxData()->getPromoCode())) {
                $bookingEntity->setPromoCode($code);
            }
            $bookingUserSelection->setProcessed(true);
            $bookingUserSelection->validateStep(4);
            $bookingManager->releaseHotelSession($bookingUserSelection);
            $session = $this->get('session');
            $session->set(sprintf(BookingManager::SESSION_HOTEL_PATTERN, $bookingUserSelection->getHotelId()), $bookingUserSelection);
            $em->persist($bookingEntity);
            $em->flush();
            /** @var EmailManager $emailManager */
            $emailManager = $this->get('seh.email_manager');
            $emailManager->sendEmail($bookingEntity->getCustomerEmail(), 'booking', $this->get('translator')->trans('email.booking.confirmation.subject', array('%bookingId%' => $bookingUserSelection->getReservitId())), 'SehBundle:mails/booking:confirmation.html.twig', array('booking' => $bookingEntity));
            return $this->redirect($this->generateUrl('booking_step_five', array('bookingId' => $bookingUserSelection->getBookingId())));
        }
        $formErrors = $this->getFormErrorsAsArray($bankingInformationForm);
        $bookingUserSelection->setBankingInformationErrors($formErrors);
        $bookingManager->saveBookingToSession($bookingUserSelection);
        return $this->redirect($this->generateUrl('booking_step_four', array('bookingId' => $bookingUserSelection->getBookingId())) . '#creditCardInfo');
    }