<?php
namespace App\MDS\ApiBundle\Controller;
use App\Entity\ClientContact;
use App\MDS\GreenPatioBundle\Entity\Reservation;
use App\MDS\GreenPatioBundle\Entity\ReservationLoungeDetails;
use App\MDS\GreenPatioBundle\Entity\ReservationLoungeDescription;
use App\MDS\GreenPatioBundle\Entity\ReservationLoungeSimple;
use App\MDS\GreenPatioBundle\Entity\ReservationLoungePicture;
use App\MDS\GreenPatioBundle\Entity\ReservationService;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
class ApiProposalsClientController extends AbstractController
{
private EntityManagerInterface $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
/**
* @Route("/api/client/proposal/{token}", name="generate_token", methods={"GET"})
*/
public function generateToken(Request $request, $token)
{
// Obtener reserva asociada al token
$reservation = $this->em->getRepository(Reservation::class)->findOneBy(['token' => $token]);
if (!$reservation) {
throw $this->createNotFoundException('No se encontró ninguna reserva para el token proporcionado.');
}
$data = [
'reservation' => $this->formatReservation($reservation),
'options' => [],
'reservationService' => []
];
// Agregar servicios de la reserva
$reservationServices = $this->em->getRepository(ReservationService::class)->findBy(['reservationId' => $reservation->getId()]);
foreach ($reservationServices as $service) {
if ( $service->getUnits() > 0 ) {
$units = $service->getUnits();
} else {
$units = 1;
}
if ( $service->getPax() > 0 ) {
$pax = $service->getPax();
} else {
$pax = 1;
}
$priceOver = $service->getOver(); // Precio adicional fijo
$price = $service->getPrice(); // Precio base del servicio
$commission = $service->getCommission(); // Porcentaje de comisión
$iva = $service->getIva(); // Porcentaje de IVA
// Calcula el precio total base por pax y unidades
$totalPrice = ($price * $pax * $units);
// Calcula la comisión como porcentaje del precio base
$priceCommission = $totalPrice * ($commission / 100);
// Suma la comisión al precio base
$totalConComision = $totalPrice + $priceCommission;
$dateInAt = $service->getDateInAt();
$dateOutAt = $service->getDateOutAt();
if ($dateInAt && $dateOutAt) {
// Calcular la diferencia
$interval = $dateInAt->diff($dateOutAt);
// Obtener los días
$days = ($interval->days) + 1;
}
// Suma el precio fijo ($priceOver) al subtotal con comisión
$totalConDays = $totalConComision * $days;
$totalConOver = $totalConDays + $priceOver;
// Calcula el IVA como porcentaje del total con el over incluido
$priceIva = $totalConOver * ($iva / 100);
// Suma el IVA al total
$totalPrice = $totalConOver + $priceIva;
$data['reservationService'][] = [
'id' => $service->getId(),
'reservationId' => $service->getReservationId(),
'supplierId' => $service->getSupplierId(),
'serviceId' => $service->getServiceId(),
'serviceCatId' => $service->getServiceCatId(),
'serviceCatName' => $service->getServiceCatName(),
'name' => $service->getName(),
'price' => $service->getPrice(),
'currency' => $service->getCurrency(),
'units' => $units,
'opCommission' => $service->getOpCommission(),
'commission' => $service->getCommission(),
'opOver' => $service->getOpOver(),
'priceOver' => $priceOver,
'opIva' => $service->getOpIva(),
'iva' => $service->getIva(),
'pax' => $pax,
'hour' => $service->getHour(),
'dateInAt' => $service->getDateInAt() ? $service->getDateInAt()->format('Y-m-d H:i:s') : null,
'dateOutAt' => $service->getDateOutAt() ? $service->getDateOutAt()->format('Y-m-d H:i:s') : null,
'contcolor' => $service->getContcolor(),
'rank' => $service->getRank(),
'assistantId' => $service->getAssistantId(),
'activityId' => $service->getActivityId(),
'pay' => $service->getPay(),
'createdAt' => $service->getCreatedAt()->format('Y-m-d H:i:s'),
'createdId' => $service->getCreatedId(),
'updatedAt' => $service->getUpdatedAt()->format('Y-m-d H:i:s'),
'updatedId' => $service->getUpdatedId(),
'toInvoice' => $service->getToInvoice(),
'totalSinIva' => $totalConOver,
'totalIva' => $priceIva,
'totalPrice' => $totalPrice,
'viewInfo' => $service->getViewInfo()
];
}
// Procesar los salones
$loungeItems = $this->em->getRepository(ReservationLoungeSimple::class)->findBy(['idReservation' => $reservation->getId()]);
foreach ($loungeItems as $item) {
// Obtener el idioma en relación al reservationLoungeSimple
$data['reservation']['idWebLanguage'] = $item->getLanguage() ? $item->getLanguage() : 1; // Default to Spanish if not set
$uniqueId = $item->getId();
$rankQuote = $item->getRankQuote();
$loungeIva = $item->getIva();
if (empty($loungeIva) && !is_numeric($loungeIva)) {
$loungeIva = 21;
}
// Formatear los datos del lounge
$loungeData = $this->formatLoungeData($item, $this->em, $uniqueId, $loungeIva);
// Agrupar por rankQuote
if (!isset($data['options'][$rankQuote])) {
$data['options'][$rankQuote] = [];
}
$data['options'][$rankQuote][] = $loungeData;
}
return new JsonResponse($data);
}
private function formatReservation($reservation)
{
$contactEmail = null;
if($reservation->getClientContact()){
$contact = $this->em->getRepository(ClientContact::class)->findById($reservation->getClientContact());
$contactEmail = $contact->getEmail();
} else{
$contactEmail = $reservation->getContactUnregistered();
}
return [
'id' => $reservation->getId(),
'title' => $reservation->getTitle(),
'client' => $reservation->getClient(),
'createdAt' => $reservation->getCreatedAt()->format('Y-m-d H:i:s'),
'priority' => $reservation->getPriority(),
'dateStart' => $reservation->getDateStart() ? $reservation->getDateStart()->format('Y-m-d H:i:s') : null,
'dateEnd' => $reservation->getDateEnd() ? $reservation->getDateEnd()->format('Y-m-d H:i:s') : null,
'createdBy' => $reservation->getCreatedBy(),
'supplier' => $reservation->getSupplier(),
'status' => $reservation->getStatus(),
'updatedAt' => $reservation->getUpdatedAt()->format('Y-m-d H:i:s'),
'updatedBy' => $reservation->getUpdatedBy(),
'daysBlock' => $reservation->getDaysBlock(),
'advancePayment' => $reservation->getAdvancePayment(),
'idProposal' => $reservation->getIdProposal(),
'cateringName' => $reservation->getCateringName(),
'boolCatering' => $reservation->getBoolCatering(),
'pax' => $reservation->getPax(),
'deposit' => $reservation->getDeposit(),
'accessKey' => $reservation->getAccessKey(),
'description' => $reservation->getDescription(),
'clientContact' => $reservation->getClientContact(),
'contactUnregistered' => $reservation->getContactUnregistered(),
'days' => $reservation->getDays(),
'contract' => $reservation->getContract(),
'nameContactUnregistered' => $reservation->getNameContactUnregistered(),
'phoneContactUnregistered' => $reservation->getPhoneContactUnregistered(),
'token' => $reservation->getToken(),
'contactEmail' => $contactEmail,
];
}
private function formatLoungeData($item, $entityManager, $uniqueId, $loungeIva)
{
$loungeName = $item->getLoungeName();
$reservationLoungeDetail = $this->em->getRepository(ReservationLoungeDetails::class)->findOneBy(['name' => $loungeName]);
if (!$reservationLoungeDetail) {
return [];
}
try {
$loungeIva = $item->getServicePrice() * ($loungeIva / 100);
} catch (\Throwable $th) {
$loungeIva = $item->getServicePrice() * (21 / 100);
}
$comboIds = $reservationLoungeDetail->getCombo();
return [
'id' => $uniqueId,
'loungeId' => $reservationLoungeDetail->getId(),
'loungeName' => $reservationLoungeDetail->getName(),
'type' => $item->getType(), // Añadir type
'rankQuote' => $item->getRankQuote(), // Añadir rankQuote
'dateStart' => $item->getDateStart() ? $item->getDateStart()->format('Y-m-d H:i:s') : null,
'dateEnd' => $item->getDateEnd() ? $item->getDateEnd()->format('Y-m-d H:i:s') : null,
'pax' => $item->getPax(),
'price' => $item->getServicePrice(),
'loungeIva' => $loungeIva,
'combo' => $comboIds,
'isCombo' => $comboIds ? 1 : 0,
'descriptions' => $this->getDescriptions($reservationLoungeDetail, $entityManager),
'loungeDescription' => $item->getLoungeDescription(),
'importantDescription' => (empty($item->getType())) ? $item->getImportantDescription() : '',
'importantDescGeneralText' => $item->getImportantDescGeneralText(),
'importantDescSchedules' => $item->getImportantDescSchedules(),
'importantDescParking' => $item->getImportantDescParking(),
'pictures' => $this->getPictures($reservationLoungeDetail, $entityManager),
'comboDetails' => $comboIds ? $this->getComboDetails($comboIds, $entityManager) : [],
'loungeDetails' => $this->getLoungeDetails($reservationLoungeDetail->getId(), $entityManager),
'totalPrice' => $item->getServicePrice() + $loungeIva
];
}
private function getDescriptions($loungeDetail, $entityManager)
{
$descriptions = [];
$result = $this->em->getRepository(ReservationLoungeDescription::class)->findBy(['loungeId' => $loungeDetail->getId()]);
foreach ($result as $description) {
$descriptions[] = [
'language' => $description->getLanguage(),
'description' => $description->getDescription(),
'createdAt' => $description->getCreatedAt()->format('Y-m-d H:i:s'),
'updatedAt' => $description->getUpdatedAt()->format('Y-m-d H:i:s'),
];
}
return $descriptions;
}
private function getPictures($loungeDetail, $entityManager)
{
$pictures = [];
$result = $this->em->getRepository(ReservationLoungePicture::class)->findBy(['loungeId' => $loungeDetail->getId()]);
foreach ($result as $picture) {
$pictures[] = [
'id' => $picture->getId(),
'title' => $picture->getTitle(),
'imageLarge' => $picture->getImageLarge(),
'imageMedium' => $picture->getImageMedium(),
'imageSmall' => $picture->getImageSmall(),
'createdAt' => $picture->getCreatedAt()->format('Y-m-d H:i:s'),
'updatedAt' => $picture->getUpdatedAt()->format('Y-m-d H:i:s'),
];
}
return $pictures;
}
private function getComboDetails($comboIds, $entityManager)
{
$comboDetails = [];
$comboIdArray = explode(',', $comboIds);
foreach ($comboIdArray as $comboId) {
$comboDetail = $this->em->getRepository(ReservationLoungeDetails::class)->find($comboId);
if ($comboDetail) {
$comboDetails[] = [
'id' => $comboDetail->getId(),
'loungeName' => $comboDetail->getName(),
'meters' => $comboDetail->getMeters(),
'length' => $comboDetail->getLength(),
'width' => $comboDetail->getWidth(),
'height' => $comboDetail->getHeight(),
'capSchool' => $comboDetail->getCapSchool(),
'capTheater' => $comboDetail->getCapTheater(),
'capCocktail' => $comboDetail->getCapCocktail(),
'capBanquet' => $comboDetail->getCapBanquet(),
'capImperial' => $comboDetail->getCapImperial(),
'rankLounge' => $comboDetail->getRankLounge(),
'descriptions' => $this->getDescriptions($comboDetail, $entityManager),
'pictures' => $this->getPictures($comboDetail, $entityManager),
];
}
}
return $comboDetails;
}
private function getLoungeDetails($id, $entityManager)
{
// Buscar detalles del lounge directamente en la tabla ReservationLoungeDetails
$loungeDetail = $this->em->getRepository(ReservationLoungeDetails::class)->findOneBy(['id' => $id]);
if (!$loungeDetail) {
return null; // Si no se encuentra, devolvemos null
}
return [
'id' => $loungeDetail->getId(),
'name' => $loungeDetail->getName(),
'meters' => $loungeDetail->getMeters(),
'length' => $loungeDetail->getLength(),
'width' => $loungeDetail->getWidth(),
'height' => $loungeDetail->getHeight(),
'capSchool' => $loungeDetail->getCapSchool(),
'capTheater' => $loungeDetail->getCapTheater(),
'capCocktail' => $loungeDetail->getCapCocktail(),
'capBanquet' => $loungeDetail->getCapBanquet(),
'capImperial' => $loungeDetail->getCapImperial(),
'rankLounge' => $loungeDetail->getRankLounge(),
'createdAt' => $loungeDetail->getCreatedAt() ? $loungeDetail->getCreatedAt()->format('Y-m-d H:i:s') : null,
'updatedAt' => $loungeDetail->getUpdatedAt() ? $loungeDetail->getUpdatedAt()->format('Y-m-d H:i:s') : null,
];
}
}