<?php
namespace Uniski\CommerceBundle\Event;
use Doctrine\ORM\EntityManagerInterface;
use Uniski\CommerceBundle\Entity\Booking;
use Uniski\CommerceBundle\Event\BookingEvent;
use Uniski\CommerceBundle\Event\PaymentEvent;
use Uniski\CommerceBundle\Service\BookingManager;
use Uniski\CommerceBundle\Service\PaymentManager;
use Uniski\UserBundle\Service\NotificationManager;
use Uniski\ResourceBundle\Service\RoomStockManager;
use Uniski\CommerceBundle\Exception\OverPaymentException;
use Uniski\CommerceBundle\Service\BookingDocumentService;
use Uniski\ResourceBundle\Exception\StockUpdateException;
use Uniski\HotelBedsBundle\Booking\DomainModel\BookingService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use HotelBedsBundle\Booking\DomainModel\InvalidBookingException;
use HotelBedsBundle\Booking\DomainModel\BookingNotConfirmedException;
/**
* Commerce subscriber
*/
class CommerceSubscriber implements EventSubscriberInterface
{
protected $notificationManager;
protected $stock;
protected $bookingManager;
protected $payment;
protected $em;
protected $bookingDocumentService;
function __construct(NotificationManager $nm,
RoomStockManager $sm,
BookingManager $bm,
PaymentManager $pm,
EntityManagerInterface $em,
BookingDocumentService $bookingDocumentService,
BookingService $bookingService
) {
$this->notificationManager = $nm;
$this->stock = $sm;
$this->bookingManager = $bm;
$this->payment = $pm;
$this->em = $em;
$this->bookingDocumentService = $bookingDocumentService;
$this->bookingService = $bookingService;
}
public static function getSubscribedEvents()
{
return [
'booking.saved' => 'onBookingSaved',
'payment.payed' => 'onPaymentPayed',
'payment.failed' => 'onPaymentFailed',
];
}
public function onBookingSaved(BookingEvent $event)
{
$booking = $event->getBooking();
$info=$booking->getInfo();
$referenceIsset=isset($info['reference']);
if (($booking->getHotel()->getSource() == "CLOUDHOSPITALITY" || (substr($booking->getHotel()->getSource(), 0, 2) == "TG") && !$referenceIsset) && $booking->getPaymentMethod() == Booking::PAYMENT_TRANSFER && $booking->getStatus() != Booking::STATUS_DELETED) {
try {
$status = $this->bookingService->confirmBooking($booking);
} catch (StockUpdateException $e) {
$message = '<p><strong>¡ERROR DEL SISTEMA!</strong>:<br>';
$message .= 'Se ha realizado un pago cuando no ha habia cupos suficientes o ha habido algún problema con el sistema de cupos<br>';
$message .= 'Revisa la reserva ' . $booking->getToken() . '<br>';
$message .= 'Mas detalles: <br>' . $e->getMessage() . '</p>';
$this->notificationManager->notifyAdmin('default', $message);
$this->bookingManager->logHistory($booking, $message);
} catch (InvalidBookingException $e) {
$message = '<p><strong>¡ERROR DEL SISTEMA!</strong>:<br>';
$message .= 'Se ha realizado un pago pero la información la reserva en HOTELBEDS es erronea<br>';
$message .= 'Finaliza la reserva ' . $booking->getToken() . '<br>';
$this->notificationManager->notifyAdmin('default', $message);
$this->bookingManager->logHistory($booking, $message);
} catch (BookingNotConfirmedException $e) {
$message = '<p><strong>¡ERROR DE HOTELBEDS!</strong>:<br>';
$message .= 'Se ha realizado un pago pero HOTELBEDS no ha confirmado la reserva ' . $e->status() . '<br>';
$message .= 'Finaliza la reserva manualmente' . $booking->getToken() . '<br>';
$this->notificationManager->notifyAdmin('default', $message);
$this->bookingManager->logHistory($booking, $message);
} catch (\Exception $e) {
$message = '<p><strong>¡ERROR DEL SISTEMA!</strong>:<br>';
$message .= 'Ha habido algun error durante la confirmación de la reserva<br>';
$message .= 'Revisa la reserva, contacta con los clientes y finaliza la reserva manualmente si es posible<br>';
$message .= 'Reserva ' . $booking->getToken() . '<br>';
$message .= 'Mas detalles: <br>' . $e->getMessage() . '</p>';
$this->notificationManager->notifyAdmin('default', $message);
$this->bookingManager->logHistory($booking, $message);
}
}
if ($event->getPreviousStatus()) {
if ($event->getComments()) $message = $event->getComments();
else $message = "Cambio de estado de " . $event->getPreviousStatus() . " a " . $booking->getStatus();
$this->bookingManager->logHistory($booking, $message);
} else {
if ($event->getComments()) $message = $event->getComments();
else $message = "Se ha creado la reserva";
if ($booking->getStatus() == Booking::STATUS_PRE_BOOKED) {
//Send notification to administator when it's prebooked
$this->notificationManager->notifyAdmin(NotificationManager::ADMIN_BOOKING_PRE_BOOKED, $booking);
//Send notification to user to thanks user with info and bonds attachments
$this->notificationManager->notifyUser(NotificationManager::USER_BOOKING_PRE_BOOKED, $booking->getUser(), $booking);
}
if ($booking->getPaymentMethod() == Booking::PAYMENT_TRANSFER) {
//Send notification to administator when it's prebooked
$this->notificationManager->notifyAdmin(NotificationManager::ADMIN_BOOKING_TRANSFER, $booking);
//Send notification to user to thanks user with info and bonds attachments
$this->notificationManager->notifyUser(NotificationManager::USER_BOOKING_TRANSFER, $booking->getUser(), $booking);
}
$this->bookingManager->logHistory($booking, $message);
}
}
public function onPaymentPayed(PaymentEvent $event)
{
$booking = $event->getTransaction()->getBooking();
$firstTimePayed = $booking->getPayed() == 0;
try {
$booking->addPayed($event->getAmount());
} catch(OverPaymentException $e) {
$message = '<p><strong>¡ERROR DEL SISTEMA!</strong>:<br>';
$message .= 'Se ha realizado un pago superior al valor pendiente de pago<br>';
$message .= 'Revisa la reserva ' . $booking->getToken() .'<br>';
$message .= 'Más detalles: <br>' . $e->getMessage() .'</p>';
$this->notificationManager->notifyAdmin('default', $message);
$this->bookingManager->logHistory($booking, $message);
}
//Si es el primer cop que paga reserva cupo
if ($firstTimePayed) {
try {
$status = $this->bookingService->confirmBooking($booking);
} catch(StockUpdateException $e) {
$message = '<p><strong>¡ERROR DEL SISTEMA!</strong>:<br>';
$message .= 'Se ha realizado un pago cuando no ha habia cupos suficientes o ha habido algún problema con el sistema de cupos<br>';
$message .= 'Revisa la reserva ' . $booking->getToken() .'<br>';
$message .= 'Mas detalles: <br>' . $e->getMessage() .'</p>';
$this->notificationManager->notifyAdmin('default', $message);
$this->bookingManager->logHistory($booking, $message);
} catch (InvalidBookingException $e) {
$message = '<p><strong>¡ERROR DEL SISTEMA!</strong>:<br>';
$message .= 'Se ha realizado un pago pero la información la reserva en HOTELBEDS es erronea<br>';
$message .= 'Finaliza la reserva ' . $booking->getToken() .'<br>';
$this->notificationManager->notifyAdmin('default', $message);
$this->bookingManager->logHistory($booking, $message);
} catch (BookingNotConfirmedException $e) {
$message = '<p><strong>¡ERROR DE HOTELBEDS!</strong>:<br>';
$message .= 'Se ha realizado un pago pero HOTELBEDS no ha confirmado la reserva ' . $e->status() . '<br>';
$message .= 'Finaliza la reserva manualmente' . $booking->getToken() .'<br>';
$this->notificationManager->notifyAdmin('default', $message);
$this->bookingManager->logHistory($booking, $message);
} catch (\Exception $e) {
$message = '<p><strong>¡ERROR DEL SISTEMA!</strong>:<br>';
$message .= 'Ha habido algun error durante la confirmación de la reserva<br>';
$message .= 'Revisa la reserva, contacta con los clientes y finaliza la reserva manualmente si es posible<br>';
$message .= 'Reserva ' . $booking->getToken() .'<br>';
$message .= 'Mas detalles: <br>' . $e->getMessage() .'</p>';
$this->notificationManager->notifyAdmin('default', $message);
$this->bookingManager->logHistory($booking, $message);
}
}
//Update booking status
if ($booking->getPending() > 0) {
//////////////////////////////////////////////////////
/// ///
/// the user has NOT payed totally, pending debt ///
/// SO WE DO NOT ISSUE BONDS AND INVOICE ///
/// ///
//////////////////////////////////////////////////////
$booking->setStatus(Booking::STATUS_HALF_PAYED);
//Send notification to administator
$this->notificationManager->notifyAdmin(NotificationManager::ADMIN_BOOKING_PAYED, $booking);
$this->notificationManager->notifyUser(NotificationManager::USER_BOOKING_PAYED,
$booking->getUser(),
$booking);
return $this->bookingManager->save($booking);
}
//////////////////////////////////////////////////////
/// ///
/// the user has payed totally, no pending debt ///
/// ///
//////////////////////////////////////////////////////
$booking->setStatus(Booking::STATUS_PAYED);
//generate an invoice id and save documents
$this->bookingDocumentService->generateDocuments($booking);
//Send notification to administator
$this->notificationManager->notifyAdmin(NotificationManager::ADMIN_BOOKING_PAYED, $booking);
//Send notification to user to thanks user with info and bonds and insurance attachments
$attachments = [$booking->getBond(), $booking->getInvoice()];
foreach ($booking->getMembers() as $member) {
if ($member->getInsurance()) {
//grouping by insurance id, in order to avoid duplicates
$insurance = $member->getInsurance();
$attachments[$insurance->getId()] = $insurance->getDocument();
}
}
$this->notificationManager->notifyUser(NotificationManager::USER_BOOKING_PAYED,
$booking->getUser(),
$booking,
$attachments);
/*
// Disabled: Send notification to hotel
if ($booking->getHotel()->getEmail()) {
$this->notificationManager->notify(NotificationManager::HOTEL_BOOKING_PAYED,
$booking->getHotel()->getEmail(),
$booking);
}*/
$this->bookingManager->save($booking);
}
public function onPaymentFailed(PaymentEvent $event)
{
$booking = $event->getTransaction()->getBooking();
$message = sprintf(
"Pago no completado en la reserva %s. Motivo: %s",
$event->getStatusMessage(),
$booking->getToken()
);
$this->bookingManager->logHistory($booking, $message);
$this->notificationManager->notifyAdmin('default', $message);
}
}