/** * @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'); }