<?php
namespace App\Controller\BackOffice;
use App\Controller\BaseController;
use App\COREapi\CoreApi;
use App\COREapi\ReservationApi;
use App\Entity\Currency;
use App\Entity\Quote;
use App\Entity\QuoteItem;
use Api\Entity\Supplier;
use App\Entity\User;
use App\Form\CoreOffice\SupplierType;
use App\Form\MyQuoteItem\MyQuoteItemType;
use App\HubSpotAPI\HubSpotAPI;
use App\Model\QuoteItem\CancellationPolicyModel;
use App\Model\QuoteItem\MyQuoteItemModel;
use App\OpenExchangeRatesAPI\OpenExchangeRates;
use App\QuickbooksAPI\QuickbooksAPI;
use App\Repository\QuoteItemRepository;
use App\Repository\QuoteRepository;
use App\Reservation\ReservationFactory;
use Doctrine\ORM\EntityManagerInterface;
use finfo;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Form\FormErrorIterator;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Validator\ConstraintViolation;
use App\NotificationSystem\NotificationSystem;
/**
* @Route("/backoffice/quoteItem")
* @Security("is_granted('IS_AUTHENTICATED_FULLY')")
*/
class QuoteItemController extends BaseController
{
/**
* @Route("/sort/update", name="quoteItems_sort_update", methods={"POST"})
* @param Request $request
* @param QuoteItemRepository $quoteItemRepository
*/
public function quoteItemsSortUpdateAction(Request $request, QuoteItemRepository $quoteItemRepository): Response
{
try {
$quoteItemsToUpdate = $request->request->get('quoteItems');
$em = $this->getDoctrine()->getManager();
foreach ($quoteItemsToUpdate as $quoteItemToUpdate) {
if ($quoteItem = $quoteItemRepository->find($quoteItemToUpdate['id'])) {
$quoteItem->setSort($quoteItemToUpdate['sort']);
$em->persist($quoteItem);
$em->flush();
}
}
return $this->json(array('status' => 'success'));
} catch (\Exception $e) {
return $this->json(array(
"message" => $e->getMessage()
), 400);
}
}
/**
* @Route("/name/update", name="quoteItems_name_update", methods={"POST"})
* @param Request $request
* @param QuoteRepository $quoteRepository
* @return Response
*/
public function quoteItemsNameUpdateAction(Request $request, QuoteRepository $quoteRepository): Response
{
try {
$idQuote = $request->request->get('idQuote');
$lastNameToCopy = trim($request->request->get('lastNameToCopy'));
$nameToCopy = trim($request->request->get('nameToCopy'));
$overwriteAllName = trim($request->request->get('overwriteAllName'));
if (!$quote = $quoteRepository->find($idQuote)) {
throw new \Exception('Quote was not found');
}
$em = $this->getDoctrine()->getManager();
$i = 0;
foreach ($quote->getQuoteItems() as $quoteItem) {
if (!$quoteItem->isBooked() && ($overwriteAllName || !trim($quoteItem->getClientFullName()))) {
$quoteItem->resetClientNameAndLastNameJson();
$quoteItem->setClientName($nameToCopy);
$quoteItem->setClientLastName($lastNameToCopy);
$i++;
$em->persist($quoteItem);
$em->flush();
}
}
if ($i) {
$this->addFlash('success', 'The name has been Successfully updated for Quote #' . $quote->getQuoteNumber() . " - " . $quote->getDescription());
} else {
$this->addFlash('warning', 'There were no quote items to be updated for Quote #' . $quote->getQuoteNumber());
}
} catch (\Exception $e) {
$this->addFlash('error', "The Quote couldn't be updated. Error: " . $e->getMessage());
}
//Redirect to previous page
if ($url = $request->headers->get('referer')) {
$url = str_replace($request->getSchemeAndHttpHost(), "", $url);
return new RedirectResponse($url);
}
return $this->redirectToRoute('quote_edit', array('id' => $idQuote));
}
/**
* @Route("/newActivity/{quote}", name="my_quoteItem_new_activity", methods={"GET","POST"})
* @Security("is_granted('ROLE_USER_EDIT_CUSTOMER_ACCOUNT')")
* @param Request $request
* @param Quote $quote
* @param QuickbooksAPI $quickbooksAPI
* @param ReservationFactory $reservationFactory
* @param NotificationSystem $notificationSystem
* @param CoreApi $coreApi
* @return Response
*/
public function newActivity(Request $request, Quote $quote, QuickbooksAPI $quickbooksAPI, ReservationFactory $reservationFactory, NotificationSystem $notificationSystem, CoreApi $coreApi, HubSpotAPI $hubSpotAPI, ReservationApi $reservationApi): Response
{
locale_set_default('en-US');
$quoteItem = new QuoteItem();
$quoteItem->setQuote($quote);
//By default, one day
$quoteStart = $quote->getStartDate() ? $quote->getStartDate() : new \DateTime('now');
$date = new \DateTime('now');
$checkIn = max($quoteStart, $date);
$quoteItem->setCheckIn($checkIn);
$quoteItem->setCheckOut($checkIn);
$quoteItem->setType(QuoteItem::PRODUCT_TYPE_ACTIVITY);
$quoteItem->setSource(QuoteItem::PRODUCT_SOURCE_MANUALLY);
$quoteItem->setIdProduct(0); //Dummy value for test 171783
$quoteItem->setReservationNotBookStatus();
$quoteItem->setAccountingPendingStatus();
$quoteItem->setPriceRefreshAt(new \DateTime('now'));
$quoteItem->setIsPriceRefresh(true);
$quoteItem->setRetailIsCustomized(true);
$quoteItem->setShowRatesInOneLine(true);
$quoteItem->setAdditionalInformation(array("manuallyAdded" => true));
$quoteItem->setDisplayInOriginalCurrency(false);
$requestArray = $request->request->all();
if (array_key_exists('my_quote_item', $requestArray)) {
$quoteItem->setNumberOfAdults($requestArray['my_quote_item']['quoteItem']['quantity']);
if (!is_numeric($requestArray['my_quote_item']['quoteItem']['vendorId'])) {
unset($requestArray['my_quote_item']['quoteItem']['vendorId']);
$request->request->set('my_quote_item', $requestArray['my_quote_item']);
}
}
$this->setOriginalCurrencyObj($request, $quoteItem);
$cancellationPolicyFrontEnd = new CancellationPolicyModel();
$this->setCancellationPolicyFrontEnd($quoteItem, $cancellationPolicyFrontEnd);
$supplierCancellationPolicyFrontEnds = array();
$oxCancellationPolicyFrontEnds = array();
$quoteItem->setSupplierCancellationPolicyWasMissing(true);
$this->setCancellationPolicyFrontEnds($quoteItem, $request, $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds);
// if (array_key_exists('my_quote_item', $requestArray) && $requestArray['my_quote_item']['useOxCancellationPolicy']){
// foreach ($oxCancellationPolicyFrontEnds as $oxCancellationPolicyFrontEnd) {
// $cancellationPolicyFrontEnd = $oxCancellationPolicyFrontEnd;
// }
// }else{
// foreach ($supplierCancellationPolicyFrontEnds as $supplierCancellationPolicyFrontEnd) {
// $cancellationPolicyFrontEnd = $supplierCancellationPolicyFrontEnd;
// }
// }
$myQuoteItem = new MyQuoteItemModel($quoteItem, $cancellationPolicyFrontEnd, $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds);
$options = array('product' => QuoteItem::PRODUCT_TYPE_ACTIVITY);
$originalQuoteItem = clone($quoteItem);
$form = $this->createForm(MyQuoteItemType::class, $myQuoteItem, $options);
$form->handleRequest($request);
try {
$quoteItem = $myQuoteItem->getQuoteItem();
$this->saveQuoteItem($request, $form, $quoteItem, $cancellationPolicyFrontEnd, $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds, $originalQuoteItem, 'added', $quickbooksAPI, $reservationFactory, $notificationSystem, $coreApi, $hubSpotAPI, $reservationApi);
if ($quoteItem->getId()) {
//It was created the activity, redirect to My Quote Item edit view
return $this->redirectToRoute('my_quoteItem_edit', array('id' => $quoteItem->getId()));
}
} catch (\Exception $e) {
$this->addFlash('error', "<p>The Activity couldn't be saved.</p><p></p> Error: <br/>" . $e->getMessage() . "</p>");
}
$em = $this->getDoctrine()->getManager();
$exchangeRateData = $em->getRepository(Currency::class)->getRatesByShortName();
$supplier = new Supplier();
$formSupplier = $this->createForm(SupplierType::class, $supplier);
$formSupplier->handleRequest($request);
return $this->render('backOffice/myQuote/edit.html.twig', [
'formMyQuoteItem' => $form->createView(),
'quoteItem' => $quoteItem,
'title' => 'New Activity',
'supplier' => $supplier,
'formSupplier' => $formSupplier->createView(),
'exchangeRateData' => $exchangeRateData,
'hasQuoteCommission' => !!$quoteItem->getQuote()->getCustomerAccountCommissionType(),
]);
}
/**
* @Route("/newVilla/{quote}", name="my_quoteItem_new_villa", methods={"GET","POST"})
* @Security("is_granted('ROLE_USER_EDIT_CUSTOMER_ACCOUNT')")
* @param Request $request
* @param Quote $quote
* @param QuickbooksAPI $quickbooksAPI
* @param ReservationFactory $reservationFactory
* @param NotificationSystem $notificationSystem
* @param CoreApi $coreApi
* @return Response
*/
public function newVilla(Request $request, Quote $quote, QuickbooksAPI $quickbooksAPI, ReservationFactory $reservationFactory, NotificationSystem $notificationSystem, CoreApi $coreApi, HubSpotAPI $hubSpotAPI, ReservationApi $reservationApi): Response
{
locale_set_default('en-US');
$quoteItem = new QuoteItem();
$quoteItem->setQuote($quote);
//By default, one day
$quoteStart = $quote->getStartDate() ? $quote->getStartDate() : new \DateTime('now');
$date = new \DateTime('now');
$checkIn = max($quoteStart, $date);
$quoteItem->setCheckIn($checkIn);
$quoteItem->setCheckOut($checkIn);
$quoteItem->setType(QuoteItem::PRODUCT_TYPE_VILLA);
$quoteItem->setSource(QuoteItem::PRODUCT_SOURCE_MANUALLY);
$quoteItem->setIdProduct(0); //Dummy value for test 171783
$quoteItem->setReservationNotBookStatus();
$quoteItem->setAccountingPendingStatus();
$quoteItem->setPriceRefreshAt(new \DateTime('now'));
$quoteItem->setIsPriceRefresh(true);
$quoteItem->setRetailIsCustomized(true);
$quoteItem->setShowRatesInOneLine(true);
$quoteItem->setAdditionalInformation(array("manuallyAdded" => true));
$quoteItem->setDisplayInOriginalCurrency(false);
$requestArray = $request->request->all();
if (array_key_exists('my_quote_item', $requestArray)) {
$quoteItem->setNumberOfAdults($requestArray['my_quote_item']['quoteItem']['quantity']);
if (!is_numeric($requestArray['my_quote_item']['quoteItem']['vendorId'])) {
unset($requestArray['my_quote_item']['quoteItem']['vendorId']);
$request->request->set('my_quote_item', $requestArray['my_quote_item']);
}
}
$this->setOriginalCurrencyObj($request, $quoteItem);
$cancellationPolicyFrontEnd = new CancellationPolicyModel();
$this->setCancellationPolicyFrontEnd($quoteItem, $cancellationPolicyFrontEnd);
$supplierCancellationPolicyFrontEnds = array();
$oxCancellationPolicyFrontEnds = array();
$quoteItem->setSupplierCancellationPolicyWasMissing(true);
$this->setCancellationPolicyFrontEnds($quoteItem, $request, $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds);
// if (array_key_exists('my_quote_item', $requestArray) && $requestArray['my_quote_item']['useOxCancellationPolicy']){
// foreach ($oxCancellationPolicyFrontEnds as $oxCancellationPolicyFrontEnd) {
// $cancellationPolicyFrontEnd = $oxCancellationPolicyFrontEnd;
// }
// }else{
// foreach ($supplierCancellationPolicyFrontEnds as $supplierCancellationPolicyFrontEnd) {
// $cancellationPolicyFrontEnd = $supplierCancellationPolicyFrontEnd;
// }
// }
$myQuoteItem = new MyQuoteItemModel($quoteItem, $cancellationPolicyFrontEnd, $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds);
$options = array('product' => QuoteItem::PRODUCT_TYPE_VILLA);
$originalQuoteItem = clone($quoteItem);
$form = $this->createForm(MyQuoteItemType::class, $myQuoteItem, $options);
$form->handleRequest($request);
try {
$quoteItem = $myQuoteItem->getQuoteItem();
$this->saveQuoteItem($request, $form, $quoteItem, $cancellationPolicyFrontEnd, $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds, $originalQuoteItem, 'added', $quickbooksAPI, $reservationFactory, $notificationSystem, $coreApi, $hubSpotAPI, $reservationApi);
if ($quoteItem->getId()) {
//It was created the activity, redirect to My Quote Item edit view
return $this->redirectToRoute('my_quoteItem_edit', array('id' => $quoteItem->getId()));
}
} catch (\Exception $e) {
$this->addFlash('error', "<p>The Villa couldn't be saved.</p><p></p> Error: <br/>" . $e->getMessage() . "</p>");
}
$em = $this->getDoctrine()->getManager();
$exchangeRateData = $em->getRepository(Currency::class)->getRatesByShortName();
$supplier = new Supplier();
$formSupplier = $this->createForm(SupplierType::class, $supplier);
$formSupplier->handleRequest($request);
return $this->render('backOffice/myQuote/edit.html.twig', [
'formMyQuoteItem' => $form->createView(),
'quoteItem' => $quoteItem,
'title' => 'New Activity',
'supplier' => $supplier,
'formSupplier' => $formSupplier->createView(),
'exchangeRateData' => $exchangeRateData,
'hasQuoteCommission' => !!$quoteItem->getQuote()->getCustomerAccountCommissionType(),
]);
}
/**
* @Route("/newTransfer/{quote}", name="my_quoteItem_new_transfer", methods={"GET","POST"})
* @Security("is_granted('ROLE_USER_EDIT_CUSTOMER_ACCOUNT')")
* @param Request $request
* @param Quote $quote
* @return Response
*/
public function newTransfer(Request $request, Quote $quote, QuickbooksAPI $quickbooksAPI, ReservationFactory $reservationFactory, NotificationSystem $notificationSystem, CoreApi $coreApi, HubSpotAPI $hubSpotAPI, ReservationApi $reservationApi): Response
{
locale_set_default('en-US');
$quoteItem = new QuoteItem();
$quoteItem->setQuote($quote);
//By default one day
$quoteStart = $quote->getStartDate() ? $quote->getStartDate() : new \DateTime('now');
$date = new \DateTime('now');
$checkIn = max($quoteStart, $date);
$quoteItem->setCheckIn($checkIn);
$quoteItem->setCheckOut($checkIn);
$dateStr = $quoteItem->getDateToStr($checkIn);
$timeStr = "11:00 AM";//Default
$quoteItem->setIdProduct(0); //Dummy value for test 106510
$quoteItem->setType(QuoteItem::PRODUCT_TYPE_TRANSFER);
$quoteItem->setSource(QuoteItem::PRODUCT_SOURCE_MANUALLY);
$quoteItem->setReservationNotBookStatus();
$quoteItem->setAccountingPendingStatus();
$quoteItem->setPriceRefreshAt(new \DateTime('now'));
$quoteItem->setIsPriceRefresh(true);
$quoteItem->setRetailIsCustomized(true);
$quoteItem->setShowRatesInOneLine(false);
$quoteItem->setDisplayInOriginalCurrency(false);
$quoteItem->setAdditionalInformation(array(
"manuallyAdded" => true,
"transfer" => array(),
"transferDate" => $dateStr,
"transferTime" => $timeStr,
"transferAddress" => "")
);
$this->setOriginalCurrencyObj($request, $quoteItem);
$cancellationPolicyFrontEnd = new CancellationPolicyModel();
$this->setCancellationPolicyFrontEnd($quoteItem, $cancellationPolicyFrontEnd);
$supplierCancellationPolicyFrontEnds = array();
$oxCancellationPolicyFrontEnds = array();
$quoteItem->setSupplierCancellationPolicyWasMissing(true);
$this->setCancellationPolicyFrontEnds($quoteItem, $request, $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds);
// $requestArray = $request->request->all();
// if (array_key_exists('my_quote_item', $requestArray) && $requestArray['my_quote_item']['useOxCancellationPolicy']){
// $cancellationPolicyFrontEnd = $oxCancellationPolicyFrontEnds[0];
// }else{
// $cancellationPolicyFrontEnd = $supplierCancellationPolicyFrontEnds[0];
// }
$myQuoteItem = new MyQuoteItemModel($quoteItem, $cancellationPolicyFrontEnd, $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds);
$options = array('product' => QuoteItem::PRODUCT_TYPE_TRANSFER);
$originalQuoteItem = clone($quoteItem);
$form = $this->createForm(MyQuoteItemType::class, $myQuoteItem, $options);
$form->handleRequest($request);
try {
$quoteItem = $myQuoteItem->getQuoteItem();
$this->saveQuoteItem($request, $form, $quoteItem, $cancellationPolicyFrontEnd, $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds, $originalQuoteItem, 'added', $quickbooksAPI, $reservationFactory, $notificationSystem, $coreApi, $hubSpotAPI, $reservationApi);
if ($quoteItem->getId()) {
//It was created the activity, redirect to My Quote Item edit view
return $this->redirectToRoute('my_quoteItem_edit', array('id' => $quoteItem->getId()));
}
} catch (\Exception $e) {
$this->addFlash('error', "<p>The Transfer couldn't be saved.</p><p></p> Error: <br/>" . $e->getMessage() . "</p>");
}
$em = $this->getDoctrine()->getManager();
$exchangeRateData = $em->getRepository(Currency::class)->getRatesByShortName();
$supplier = new Supplier();
$formSupplier = $this->createForm(SupplierType::class, $supplier);
$formSupplier->handleRequest($request);
return $this->render('backOffice/myQuote/edit.html.twig', [
'formMyQuoteItem' => $form->createView(),
'quoteItem' => $quoteItem,
'title' => 'New Transfer',
'supplier' => $supplier,
'formSupplier' => $formSupplier->createView(),
'exchangeRateData' => $exchangeRateData,
'hasQuoteCommission' => !!$quoteItem->getQuote()->getCustomerAccountCommissionType(),
]);
}
/**
* @Route("/newCarRental/{quote}", name="my_quoteItem_new_car_rental", methods={"GET","POST"})
* @Security("is_granted('ROLE_USER_EDIT_CUSTOMER_ACCOUNT')")
* @param Request $request
* @param Quote $quote
* @return Response
*/
public function newCarRental(Request $request, Quote $quote, QuickbooksAPI $quickbooksAPI, ReservationFactory $reservationFactory, NotificationSystem $notificationSystem, CoreApi $coreApi, HubSpotAPI $hubSpotAPI, ReservationApi $reservationApi): Response
{
locale_set_default('en-US');
$quoteItem = new QuoteItem();
$quoteItem->setQuote($quote);
//By default, one day
$quoteStart = $quote->getStartDate() ? $quote->getStartDate() : new \DateTime('now');
$date = new \DateTime('now');
$checkIn = max($quoteStart, $date);
$quoteItem->setCheckIn($checkIn);
$quoteItem->setCheckOut($checkIn);
$dateStr = $quoteItem->getDateToStr($checkIn);
$timeStr = "TBC";//Default
$quoteItem->setIdProduct(0); //Dummy value for test 106510
$quoteItem->setType(QuoteItem::PRODUCT_TYPE_CAR_RENTAL);
$quoteItem->setSource(QuoteItem::PRODUCT_SOURCE_MANUALLY);
$quoteItem->setNumberOfAdults(1);
$quoteItem->setReservationNotBookStatus();
$quoteItem->setAccountingPendingStatus();
$quoteItem->setPriceRefreshAt(new \DateTime('now'));
$quoteItem->setIsPriceRefresh(true);
$quoteItem->setRetailIsCustomized(true);
$quoteItem->setShowRatesInOneLine(false);
$quoteItem->setDisplayInOriginalCurrency(false);
$quoteItem->setAdditionalInformation(array(
"manuallyAdded" => true,
"pickupDate" => $dateStr,
"pickupTime" => $timeStr,
"dropoffDate" => $dateStr,
"dropoffTime" => $timeStr,
"department" => null,
)
);
$this->setOriginalCurrencyObj($request, $quoteItem);
$cancellationPolicyFrontEnd = new CancellationPolicyModel();
$this->setCancellationPolicyFrontEnd($quoteItem, $cancellationPolicyFrontEnd);
$supplierCancellationPolicyFrontEnds = array();
$oxCancellationPolicyFrontEnds = array();
$quoteItem->setSupplierCancellationPolicyWasMissing(true);
$this->setCancellationPolicyFrontEnds($quoteItem, $request, $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds);
// $requestArray = $request->request->all();
// if (array_key_exists('my_quote_item', $requestArray) && $requestArray['my_quote_item']['useOxCancellationPolicy']){
// $cancellationPolicyFrontEnd = $oxCancellationPolicyFrontEnds[0];
// }else{
// $cancellationPolicyFrontEnd = $supplierCancellationPolicyFrontEnds[0];
// }
$myQuoteItem = new MyQuoteItemModel($quoteItem, $cancellationPolicyFrontEnd, $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds);
// , $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds,
$options = array('product' => QuoteItem::PRODUCT_TYPE_CAR_RENTAL);
$originalQuoteItem = clone($quoteItem);
$form = $this->createForm(MyQuoteItemType::class, $myQuoteItem, $options);
$form->handleRequest($request);
try {
$quoteItem = $myQuoteItem->getQuoteItem();
$additionalInformation = $quoteItem->getAdditionalInformation();
if (!key_exists('pickupTime', $additionalInformation)) {
$quoteItem->setAdditionalInformation(['pickupTime' => null]);
}
if (!key_exists('dropoffTime', $additionalInformation)) {
$quoteItem->setAdditionalInformation(['dropoffTime' => null]);
}
$this->saveQuoteItem($request, $form, $quoteItem, $cancellationPolicyFrontEnd, $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds, $originalQuoteItem, 'added', $quickbooksAPI, $reservationFactory, $notificationSystem, $coreApi, $hubSpotAPI, $reservationApi);
if ($quoteItem->getId()) {
//It was created the car rental, redirect to My Quote Item edit view
return $this->redirectToRoute('my_quoteItem_edit', array('id' => $quoteItem->getId()));
}
} catch (\Exception $e) {
$this->addFlash('error', "<p>The Car Rental couldn't be saved.</p><p></p> Error: <br/>" . $e->getMessage() . "</p>");
}
$em = $this->getDoctrine()->getManager();
$exchangeRateData = $em->getRepository(Currency::class)->getRatesByShortName();
$supplier = new Supplier();
$formSupplier = $this->createForm(SupplierType::class, $supplier);
$formSupplier->handleRequest($request);
return $this->render('backOffice/myQuote/edit.html.twig', [
'formMyQuoteItem' => $form->createView(),
'quoteItem' => $quoteItem,
'title' => 'New Transfer',
'supplier' => $supplier,
'formSupplier' => $formSupplier->createView(),
'exchangeRateData' => $exchangeRateData,
'hasQuoteCommission' => !!$quoteItem->getQuote()->getCustomerAccountCommissionType(),
]);
}
/**
* @Route("/newHotelService/{parentQuoteItem}/{type}", defaults={"type"="service"} ,name="quoteItem_new_hotel_service", methods={"GET","POST"})
* @Security("is_granted('ROLE_USER_EDIT_CUSTOMER_ACCOUNT')")
* @param Request $request
* @param QuoteItem $parentQuoteItem
* @param string $type
* @return Response
*/
public function newHotelService(Request $request, QuoteItem $parentQuoteItem, string $type, QuickbooksAPI $quickbooksAPI, ReservationFactory $reservationFactory, NotificationSystem $notificationSystem, CoreApi $coreApi, HubSpotAPI $hubSpotAPI, ReservationApi $reservationApi): Response
{
locale_set_default('en-US');
$options = array();
$quote = $parentQuoteItem->getQuote();
$quoteItem = new QuoteItem();
$quoteItem->setQuote($quote);
//By default, one day
$quoteItem->setCheckIn($parentQuoteItem->getCheckIn());
$quoteItem->setCheckOut($parentQuoteItem->getCheckOut());
$quoteItem->setOriginalCurrency($parentQuoteItem->getOriginalCurrency());
$quoteItem->setDisplayInOriginalCurrency($parentQuoteItem->getDisplayInOriginalCurrency() ?? false);
$quoteItem->setExchangeRate($parentQuoteItem->getExchangeRate());
//Default
$title = 'Hotel Service';
$quoteItem->setType(QuoteItem::PRODUCT_TYPE_HOTEL_SERVICE);
if ($type == 'resortFee') {
$title = 'Resort Fee';
$quoteItem->setType(QuoteItem::PRODUCT_TYPE_HOTEL_RESORT_FEE);
$quoteItem->setName('Resort Fee');
}
if (in_array($type, array('resortFee', 'service', 'hotel_service'))) {
//Safe the same cancellation policy we have in the parent item (hotel)
$quoteItem->setCancellationPolicy($parentQuoteItem->getCancellationPolicy());
$quoteItem->setCancellationPolicySupplier($parentQuoteItem->getCancellationPolicySupplier());
$quoteItem->setCancellationPolicyOx($parentQuoteItem->getCancellationPolicyOx());
$quoteItem->setUseOxCancellationPolicy($parentQuoteItem->getUseOxCancellationPolicy());
$quoteItem->setCancellationPenaltyDate($parentQuoteItem->getCancellationPenaltyDate());
$quoteItem->setCancellationPenaltyId($parentQuoteItem->getCancellationPenaltyId());
$quoteItem->setCancellationPolicyLabel($parentQuoteItem->getCancellationPolicyLabels() ?? "");
//Cancellation policy should be disabled.
$options = array('disabledCancellationPolicy' => true);
}
$options['product'] = $quoteItem->getType();
$quoteItem->setSource(QuoteItem::PRODUCT_SOURCE_MANUALLY);
$quoteItem->setIdProduct(0); //Dummy value for test
$quoteItem->setQuantity(1);
$quoteItem->setReservationNotBookStatus();
$quoteItem->setAccountingPendingStatus();
$quoteItem->setClientNameJson($parentQuoteItem->getClientNameJson());
$quoteItem->setClientLastNameJson($parentQuoteItem->getClientLastNameJson());
$quoteItem->setPriceRefreshAt(new \DateTime('now'));
$quoteItem->setIsPriceRefresh(true);
$quoteItem->setRetailIsCustomized(true);
$quoteItem->setShowRatesInOneLine(false);
$quoteItem->setAdditionalInformation(array("manuallyAdded" => true));
$quoteItem->setNumberOfAdults($parentQuoteItem->getNumberOfAdults());
$quoteItem->setParentQuoteItem($parentQuoteItem);
$cancellationPolicyFrontEnd = new CancellationPolicyModel();
$this->setCancellationPolicyFrontEnd($quoteItem, $cancellationPolicyFrontEnd);
$supplierCancellationPolicyFrontEnds = array();
$oxCancellationPolicyFrontEnds = array();
$this->setCancellationPolicyFrontEnds($quoteItem, $request, $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds);
$myQuoteItem = new MyQuoteItemModel($quoteItem, $cancellationPolicyFrontEnd, $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds);
$originalQuoteItem = clone($quoteItem);
$form = $this->createForm(MyQuoteItemType::class, $myQuoteItem, $options);
$requestArray = $request->request->all();
$requestArray['my_quote_item']['quoteItem']['clientNameJson'] = $parentQuoteItem->getClientNameJson();
$requestArray['my_quote_item']['quoteItem']['clientLastNameJson'] = $parentQuoteItem->getClientLastNameJson();
$request->request->set('my_quote_item', $requestArray['my_quote_item']);
$form->handleRequest($request);
try {
$quoteItem = $myQuoteItem->getQuoteItem();
$this->saveQuoteItem($request, $form, $quoteItem, $cancellationPolicyFrontEnd, $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds, $originalQuoteItem, 'added', $quickbooksAPI, $reservationFactory, $notificationSystem, $coreApi, $hubSpotAPI, $reservationApi);
if ($quoteItem->getId()) {
//It was created the hotel service, redirect to My Quote Item edit view
return $this->redirectToRoute('my_quoteItem_edit', array('id' => $quoteItem->getId()));
}
} catch (\Exception $e) {
$this->addFlash('error', "<p>The " . $title . " couldn't be saved.</p><p></p> Error: <br/>" . $e->getMessage() . "</p>");
}
return $this->render('backOffice/myQuote/edit.html.twig', [
'formMyQuoteItem' => $form->createView(),
'quoteItem' => $quoteItem,
'title' => $title,
'exchangeRateData' => $parentQuoteItem->getExchangeRate(),
'hasQuoteCommission' => !!$quoteItem->getQuote()->getCustomerAccountCommissionType(),
]);
}
/**
* @Route("/customizeRates",name="quoteItem_customize_rates", methods={"POST"})
* @Security("is_granted('ROLE_DISCONECT_RATE')")
* @param Request $request
* @param CoreApi $coreApi
* @param QuoteItemRepository $quoteItemRepository
* @return Response
*/
public function customizeRates(Request $request, CoreApi $coreApi, QuoteItemRepository $quoteItemRepository): Response
{
try {
//This is the Flow:
//1. Click on the button "Customized Rates"
//2. Show confirmation message: Cancel or Continue
//If they click on Continue, THEN:
//1. Change Source to Manually
//2. Call API to get NEW product id
//3. Set NetIsCustomized to true
//4. Set CommissionIsCustomized to true
//5. Update quote item with NEW product id
//6. Reload Quote Item view with inputs enabled...
if (!$quoteItem = $quoteItemRepository->find($request->request->get('id'))) {
throw new \Exception("Quote Item is not valid.");
}
if (!$quoteItem->isHotel() || $quoteItem->isManuallyAdded()) {
throw new \Exception("This Quote Item cannot have customize rates.");
}
if (!$coreApi->customizeRates($quoteItem)) {
throw new \Exception($coreApi->getErrorStr());
}
//Change to manually
$quoteItem->setIsCustomizeRate(true);
$quoteItem->setSource(QuoteItem::PRODUCT_SOURCE_MANUALLY);
$em = $this->getDoctrine()->getManager();
$em->persist($quoteItem);
$em->flush();
$em->refresh($quoteItem);
$this->addFlash('success', 'The Quote Item has been updated to allow customize rates.');
} catch (\Exception $e) {
$this->addFlash('error', "Customize rates failed. Detail: " . $e->getMessage());
if (!isset($quoteItem) || !$quoteItem) {
//Redirect to previous page
if ($url = $request->headers->get('referer')) {
$url = str_replace($request->getSchemeAndHttpHost(), "", $url);
return new RedirectResponse($url);
}
}
}
return $this->redirectToRoute('my_quoteItem_edit', array('id' => $quoteItem->getId()));
}
/**
* @Route("/edit/{id}", name="my_quoteItem_edit", methods={"GET","POST"})
* @Security("is_granted('ROLE_QUOTE_EDIT_ALL')")
* @param Request $request
* @param CoreApi $coreApi
* @param QuickbooksAPI $quickbooksAPI
* @param QuoteItem|null $quoteItem
* @param ReservationFactory $reservationFactory
* @param NotificationSystem $notificationSystem
* @param HubSpotAPI $hubSpotAPI
* @return Response
*/
public function edit(Request $request, CoreApi $coreApi, QuickbooksAPI $quickbooksAPI, QuoteItem $quoteItem = null, ReservationFactory $reservationFactory, NotificationSystem $notificationSystem, HubSpotAPI $hubSpotAPI, ReservationApi $reservationApi): Response
{
locale_set_default('en-US');
try {
$this->checkIfGrantedToSeeQuote($quoteItem->getQuote());
} catch (\Exception $e) {
$this->addFlash('warning', $e->getMessage());
return $this->redirectToRoute('all_quotes_index');
}
$options = array('product' => $quoteItem->getType(), 'disabledCancellationPolicy' => !$quoteItem->canCancellationPolicyBeUpdated(), 'showCancellationNumber' => $quoteItem->isCancelled());
if ($quoteItem->getAdditionalInformation()) {
if (isset($quoteItem->getAdditionalInformation()['pickupTime']) && is_array($quoteItem->getAdditionalInformation()['pickupTime'])) {
$newDateTime = new \DateTime();
$quoteItem->setAdditionalInformation(['pickupTime' => null]);
}
}
if ($quoteItem->getAdditionalInformation()) {
if (isset($quoteItem->getAdditionalInformation()['dropoffTime']) && is_array($quoteItem->getAdditionalInformation()['dropoffTime'])) {
$newDateTime = new \DateTime();
$quoteItem->setAdditionalInformation(['dropoffTime' => null]);
}
}
if (in_array($quoteItem->getType(), ['resortFee', 'hotel_service'])) {
//Safe the same cancellation policy we have in the parent item (hotel)
$parentQuoteItem = $this->getDoctrine()->getRepository(QuoteItem::class)->findOneBy(array('id' => $quoteItem->getParentQuoteItem()->getId()));
$quoteItem->setCancellationPolicy($parentQuoteItem->getCancellationPolicy());
$quoteItem->setCancellationPenaltyDate($parentQuoteItem->getCancellationPenaltyDate());
$quoteItem->setCancellationPenaltyId($parentQuoteItem->getCancellationPenaltyId());
$quoteItem->setCancellationPolicyLabel($parentQuoteItem->getCancellationPolicyLabels() ?? "");
$quoteItem->setUseOxCancellationPolicy($parentQuoteItem->getUseOxCancellationPolicy() ?? false);
//Cancellation policy should be disabled.
$quoteItem->setOriginalCurrency($parentQuoteItem->getOriginalCurrency());
$quoteItem->setDisplayInOriginalCurrency($parentQuoteItem->getDisplayInOriginalCurrency() ?? false);
$quoteItem->setExchangeRate($parentQuoteItem->getExchangeRate());
$options['disabledCancellationPolicy'] = true;
}
$this->setOriginalCurrencyObj($request, $quoteItem);
$cancellationPolicyFrontEnd = new CancellationPolicyModel();
$this->setCancellationPolicyFrontEnd($quoteItem, $cancellationPolicyFrontEnd);
$supplierCancellationPolicyFrontEnds = array();
$oxCancellationPolicyFrontEnds = array();
$this->setCancellationPolicyFrontEnds($quoteItem, $request, $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds);
$myQuoteItem = new MyQuoteItemModel($quoteItem, $cancellationPolicyFrontEnd, $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds);
$originalQuoteItem = clone $quoteItem;
$requestArray = $request->request->all();
if (array_key_exists('my_quote_item', $requestArray) && array_key_exists('vendorId', $requestArray['my_quote_item']['quoteItem']) && !is_numeric($requestArray['my_quote_item']['quoteItem']['vendorId'])) {
unset($requestArray['my_quote_item']['quoteItem']['vendorId']);
$request->request->set('my_quote_item', $requestArray['my_quote_item']);
}
if ($parentQuoteItem = $quoteItem->getParentQuoteItem()) {
$requestArray['my_quote_item']['quoteItem']['clientNameJson'] = $parentQuoteItem->getClientNameJson();
$requestArray['my_quote_item']['quoteItem']['clientLastNameJson'] = $parentQuoteItem->getClientLastNameJson();
$request->request->set('my_quote_item', $requestArray['my_quote_item']);
}
$isALaCarteAgent=false;
if($this->isGranted("ROLE_GET_COMMISSION_FROM_QUOTE_CUSTOMER_ACCOUNT")){
$isALaCarteAgent=true;
$options['isALaCarteAgent']=$isALaCarteAgent;
$options['canEditClientName']=false;
$options['canEditBeds']=false;
$options['canEditMealPlan']=false;
$options['canEditSpecialRequests']=false;
}
if(!in_array($quoteItem->getType(),[QuoteItem::PRODUCT_TYPE_TRANSFER,QuoteItem::PRODUCT_TYPE_CAR_RENTAL])&& ($quoteItem->isBooked() or $quoteItem->isCancelled())){
$options['canEditCheckInCheckOut']=false;
}
$options['canEditManuallyConfirmationNumber']=false;
if($quoteItem->canEditManuallyConfirmationNumber()){
$options['canEditManuallyConfirmationNumber']=true;
}
$options['canOverrideSupplier']=$quoteItem->canOverriteSupplier($this->getUser());
$form = $this->createForm(MyQuoteItemType::class, $myQuoteItem, $options);
$form->handleRequest($request);
try {
$quoteItem = $myQuoteItem->getQuoteItem();
if($isALaCarteAgent){
//This user just can edit Resort Fees
if ($originalQuoteItem && ($originalQuoteItem->getResortFeesPaidOnSite() != $quoteItem->getResortFeesPaidOnSite())) {
//Update just Resort Fees
$em = $this->getDoctrine()->getManager();
$quoteItem->setResortFeesPaidOnSite($quoteItem->getResortFeesPaidOnSite());
$em->persist($quoteItem);
$em->flush();
$this->addFlash('success', 'Resort Fees has been updated');
return $this->redirectToRoute('my_quoteItem_edit', array('id' => $quoteItem->getId()));
}
}
else {
if ($quoteItem->getAdditionalInformation()) {
if (isset($quoteItem->getAdditionalInformation()['pickupTime']) && is_array($quoteItem->getAdditionalInformation()['pickupTime'])) {
$newDateTime = new \DateTime();
$quoteItem->setAdditionalInformation(['pickupTime' => null]);
}
}
if ($quoteItem->getAdditionalInformation()) {
if (isset($quoteItem->getAdditionalInformation()['dropoffTime']) && is_array($quoteItem->getAdditionalInformation()['dropoffTime'])) {
$newDateTime = new \DateTime();
$quoteItem->setAdditionalInformation(['dropoffTime' => null]);
}
}
$this->saveQuoteItem($request, $form, $quoteItem, $cancellationPolicyFrontEnd, $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds, $originalQuoteItem, 'updated', $quickbooksAPI, $reservationFactory, $notificationSystem, $coreApi, $hubSpotAPI, $reservationApi);
if ($quoteItem->getAdditionalInformation()) {
if (isset($quoteItem->getAdditionalInformation()['pickupTime']) && is_array($quoteItem->getAdditionalInformation()['pickupTime'])) {
$newDateTime = new \DateTime();
$quoteItem->setAdditionalInformation(['pickupTime' => null]);
}
}
if ($quoteItem->getAdditionalInformation()) {
if (isset($quoteItem->getAdditionalInformation()['dropoffTime']) && is_array($quoteItem->getAdditionalInformation()['dropoffTime'])) {
$newDateTime = new \DateTime();
$quoteItem->setAdditionalInformation(['dropoffTime' => null]);
}
}
if (array_key_exists('my_quote_item', $requestArray) && array_key_exists('vendorId', $requestArray['my_quote_item']['quoteItem']) && !is_numeric($requestArray['my_quote_item']['quoteItem']['vendorId'])) {
unset($requestArray['my_quote_item']['quoteItem']['vendorId']);
$request->request->set('my_quote_item', $requestArray['my_quote_item']);
}
if ($parentQuoteItem = $quoteItem->getParentQuoteItem()) {
$requestArray['my_quote_item']['quoteItem']['clientNameJson'] = $parentQuoteItem->getClientNameJson();
$requestArray['my_quote_item']['quoteItem']['clientLastNameJson'] = $parentQuoteItem->getClientLastNameJson();
$request->request->set('my_quote_item', $requestArray['my_quote_item']);
}
$cancellationPolicyFrontEnd = new CancellationPolicyModel();
$this->setCancellationPolicyFrontEnd($quoteItem, $cancellationPolicyFrontEnd);
$supplierCancellationPolicyFrontEnds = array();
$oxCancellationPolicyFrontEnds = array();
$this->setCancellationPolicyFrontEnds($quoteItem, $request, $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds);
$myQuoteItem = new MyQuoteItemModel($quoteItem, $cancellationPolicyFrontEnd, $supplierCancellationPolicyFrontEnds, $oxCancellationPolicyFrontEnds);
$form = $this->createForm(MyQuoteItemType::class, $myQuoteItem, $options);
$form->handleRequest($request);
if ($quoteItem->isHotel()) {
//Get Hotel Info
$quoteItem->setHotelInfo($coreApi->getHotelInfoByIdProduct($quoteItem->getIdProduct()));
$quoteItem->getQuote()->refreshQuoteDates();
}
}
} catch (\Exception $e) {
$this->addFlash('error', "<p>The Quote Item couldn't be saved.</p><p></p> Error: <br/>" . $e->getMessage() . "</p>");
//try to preserve any new rate data
$data = $request->request->all();
if (key_exists('ratesDetail', $data)) {
$netRateDetail = $quoteItem->getNetRateDetail();
$requestRateData = $data['ratesDetail'];
if (is_array($requestRateData) && count($requestRateData) > 0) {
foreach ($netRateDetail as $keyDate => &$netDetailRow) {
if (isset($requestRateData[$keyDate])) {
$netDetailRow['fee'] = $requestRateData[$keyDate]['netRateDetailFee'] ?? 0;
$netDetailRow['price'] = $requestRateData[$keyDate]['netRateDetailPrice'] ?? 0;
$netDetailRow['taxPercentage'] = $requestRateData['netTax'] ?? 0;
$netDetailRow['comPercentage'] = $requestRateData['netRateDetailNetComTotal'] ?? 0;
}
}
}
$quoteItem->setNetRateDetail($netRateDetail); //just for display... no need to persist
}
}
$activitySuppliers = $coreApi->getActivitySupplierList();
$em = $this->getDoctrine()->getManager();
$exchangeRateData = $em->getRepository(Currency::class)->getRatesByShortName();
$supplier = new Supplier();
$formSupplier = $this->createForm(SupplierType::class, $supplier);
$formSupplier->handleRequest($request);
$quoteItem->setCoreApi($coreApi);//Init var
self::ClearBadFiles($form);
if($isALaCarteAgent){
return $this->render('backOffice/myQuote/show/show.html.twig', [
'formMyQuoteItem' => $form->createView(),
'quoteItem' => $quoteItem,
'supplier' => $supplier,
'formSupplier' => $formSupplier->createView(),
'activitySuppliers' => $activitySuppliers,
'exchangeRateData' => $exchangeRateData,
'em' => $em,
'hasQuoteCommission' => !!$quoteItem->getQuote()->getCustomerAccountCommissionType(),
]);
}
return $this->render('backOffice/myQuote/edit.html.twig', [
'formMyQuoteItem' => $form->createView(),
'quoteItem' => $quoteItem,
'supplier' => $supplier,
'formSupplier' => $formSupplier->createView(),
'activitySuppliers' => $activitySuppliers,
'exchangeRateData' => $exchangeRateData,
'em' => $em,
'hasQuoteCommission' => !!$quoteItem->getQuote()->getCustomerAccountCommissionType(),
]);
}
/**
* @Route("/remove/{id}", name="my_quoteItem_remove", methods={"GET","POST"})
* @Security("is_granted('ROLE_USER_EDIT_CUSTOMER_ACCOUNT')")
* @param Request $request
* @param QuoteItem|null $quoteItem
* @param HubSpotAPI $hubSpotAPI
* @return Response
*/
public function removeQuoteItem(Request $request, HubSpotAPI $hubSpotAPI, QuoteItem $quoteItem = null): Response
{
try {
if (!$quoteItem) {
throw new \Exception('There is not a quote item to be deleted.');
}
if (!$quoteItem->canBeDeleted()) {
throw new \Exception("This quote item can't be deleted.");
}
$quote = $quoteItem->getQuote();
$em = $this->getDoctrine()->getManager();
if (count($quoteItem->getChildrenQuoteItems())) {
foreach ($quoteItem->getChildrenQuoteItems() as $childQuoteItem) {
$em->remove($childQuoteItem);
}
}
$em->remove($quoteItem);
$em->flush();
$quote->refreshQuoteReservationStatus();
$quote->refreshQuoteAccountingStatus();
$quote->refreshQuoteDates();
$em->flush();
if ($quote->getCustomerAccountCommissionType() == "usd") {
$quoteItem->setCustomerAccountCommissionPercentage($quote->getCustomerAccountCommission());
$em->flush();
}
$hubSpotAPI->deal($quote);
$this->addFlash('success', 'The Quote Item has been removed from the quote ' . $quote->getTitle());
} catch (\Exception $e) {
if (isset($quoteItem)) {
$this->addFlash('error', "The Quote Item couldn't be removed from the quote " . $quoteItem->getQuote()->getTitle());
} else {
$this->addFlash('error', $e->getMessage());
}
}
//Redirect to previous page
if ($url = $request->headers->get('referer')) {
$url = str_replace($request->getSchemeAndHttpHost(), "", $url);
return new RedirectResponse($url);
}
return $this->redirectToRoute('all_quotes_index');
}
/**
* @Route(path="/HideOrVisible/{quoteItem}", requirements={"quoteItem"="\d+"},name="my_quoteItem_hideOrVisible", methods={"POST"})
* @Security("is_granted('ROLE_USER_EDIT_CUSTOMER_ACCOUNT')")
* @param HubSpotAPI $hubSpotAPI
* @param QuoteItem|null $quoteItem
* @return JsonResponse
*/
public function setHideOrVisibleQuoteItem(HubSpotAPI $hubSpotAPI, QuoteItem $quoteItem = null): JsonResponse
{
try {
$em = $this->getDoctrine()->getManager();
if(!$quoteItem->canBeHideOrVisible()){
throw new \Exception($quoteItem->getMessageReasonCannotBeHideOrVisible());
}
$isHidden = false;
if ($quoteItem->getIsHidden()) {
$response = array(
"status" => "visible"
);
} else {
$isHidden = true;
$response = array(
"status" => "hide"
);
}
$quoteItem->setIsHidden($isHidden);
$em->persist($quoteItem);
$em->flush();
$em->refresh($quoteItem);
$quote = $quoteItem->getQuote();
$quote->refreshQuoteDates();
$em->persist($quote);
$em->flush();
$em->refresh($quote);
if ($quote->getCustomerAccountCommissionType() == "usd") {
$quoteItem->setCustomerAccountCommissionPercentage($quote->getCustomerAccountCommission());
}
$em->flush();
$startDate = $quote->getStartDate();
$startDate = $startDate != null ? $startDate->format('Y-m-d') : "";
$response['startDate'] = $startDate;
$endDate = $quote->getEndDate();
$endDate = $endDate != null ? $endDate->format('Y-m-d') : "";
$response['endDate'] = $endDate;
$response['messageReasonCannotBeHideOrVisible'] = $quoteItem->getMessageReasonCannotBeHideOrVisible();
$hubSpotAPI->deal($quote);
return $this->json($response, 200);
} catch (\Exception $e) {
return $this->json(['error' => $e->getMessage()], 400);
}
}
private function setOrHideVisibility(HubSpotAPI $hubSpotAPI, QuoteItem $quoteItem = null, $isHidden = false): array
{
$em = $this->getDoctrine()->getManager();
$response = array(
"status" => "visible"
);
if ($isHidden) {
$response = array(
"status" => "hide"
);
}
$quoteItem->setIsHidden($isHidden);
$em->persist($quoteItem);
$em->flush();
$em->refresh($quoteItem);
$quote = $quoteItem->getQuote();
$quote->refreshQuoteDates();
$em->persist($quote);
$em->flush();
$em->refresh($quote);
if($quote->getCustomerAccountCommissionType() == "usd"){
$quoteItem->setCustomerAccountCommissionPercentage($quote->getCustomerAccountCommission());
}
$em->flush();
$startDate = $quote->getStartDate();
$startDate = $startDate != null ? $startDate->format('Y-m-d'):"";
$response['startDate'] = $startDate;
$endDate = $quote->getEndDate();
$endDate = $endDate != null ? $endDate->format('Y-m-d'):"";
$response['endDate'] = $endDate;
$hubSpotAPI->deal($quote);
return $response;
}
/**
* @Route(path="/HideOrVisible/all", name="quote_set_hide_or_show_visibility", methods={"POST"})
* @Security("is_granted('ROLE_USER_EDIT_CUSTOMER_ACCOUNT')")
* @param Request $request
* @param HubSpotAPI $hubSpotAPI
* @param QuoteRepository $quoteRepository
* @param QuoteItemRepository $quoteItemRepository
* @return Response
*/
public function setHideOrVisibleBatchQuoteItem(Request $request, HubSpotAPI $hubSpotAPI, QuoteRepository $quoteRepository, QuoteItemRepository $quoteItemRepository): Response
{
try {
if (!$quote = $quoteRepository->find($request->request->get('idQuote'))) {
throw new \Exception("Quote is not valid.");
}
$quoteItems = $request->request->get('quoteItems') ?? [];
foreach ($quote->getQuoteItems() as $quoteItem) {
if (in_array($quoteItem->getId(), (array)$quoteItems)) {
$quoteItem = $quoteItemRepository->find($quoteItem->getId());
$this->setOrHideVisibility($hubSpotAPI, $quoteItem);
} else {
$this->setOrHideVisibility($hubSpotAPI, $quoteItem, true);
}
}
$msg = 'Your Quote Items have been change visibility';
$this->addFlash('success', $msg);
} catch (\Exception $e) {
$this->addFlash('error', $e->getMessage());
}
if (isset($quote)) {
return $this->redirectToRoute('quote_edit', array('id' => $quote->getId()));
}
return $this->redirectToRoute('all_quotes_index');
}
/**
* @param Request $request
* @param FormInterface $form
* @param QuoteItem $quoteItem
* @param CancellationPolicyModel|null $cancellationPolicyFrontEnd
* @param QuoteItem|null $originalQuoteItem
* @param string $actionString
* @param QuickbooksAPI|null $quickbooksAPI
* @param HubSpotAPI $hubSpotAPI
* @return \Symfony\Component\HttpFoundation\RedirectResponse|void
*/
private function saveQuoteItem(Request $request, FormInterface $form, QuoteItem &$quoteItem, CancellationPolicyModel $cancellationPolicyFrontEnd = null, array $supplierCancellationPolicyFrontEnds = [], array $oxCancellationPolicyFrontEnds = [], $originalQuoteItem = null, $actionString = 'updated', QuickbooksAPI $quickbooksAPI = null, ReservationFactory $reservationFactory = null, NotificationSystem $notificationSystem = null, CoreApi $coreApi = null, HubSpotAPI $hubSpotAPI, ReservationApi $reservationApi)
{
try {
if ($form->isSubmitted()) {
if (!$form->isValid()) {
/**
* @var FormErrorIterator $formErrors
* @var ConstraintViolation $cause
*/
$formErrors = $form->getErrors(true);
$errors = $formErrors->getChildren();
throw new \Exception($errors->getMessage());
}
$refreshQuoteStatus=false;
/**
* @var $file UploadedFile
*/
if ($file = $form->get('attachFile')->getData()) {
//Save the file
if (!$newFilename = $form->get('nameFile')->getData()) {
$newFilename = str_replace("." . $file->guessClientExtension(), "", $file->getClientOriginalName());
}
//test for valid file
$validFileTypes = array(
'image/ief',
'image/bmp',
'image/png',
'image/jpeg',
'image/tiff',
'application/pdf',
'application/x-pdf',
'text/csv',
'text/plain',
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.ms-excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
$validFileExtension = array(
'jpg',
'jpeg',
'png',
'bmp',
'tiff',
'pdf',
'txt',
'csv'
);
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$type = finfo_file($finfo, $file);
if (!in_array($type, $validFileTypes)) {
throw new \Exception("Invalid file type");
}
if (!in_array($file->guessClientExtension(), $validFileExtension)) {
throw new \Exception("Invalid file type");
}
///
$newFilename = str_replace("#", "", $newFilename);
$newFilename = preg_replace("/\s+/", "", $newFilename);
$newFilename = $newFilename . "_" . random_int(1000, PHP_INT_MAX) . '.' . $file->guessClientExtension();
$file->move(
$this->getParameter('quote_item_file_directory'),
$newFilename
);
//Save the file name
$quoteItem->addFile($newFilename);
}
if ($quoteItem->isTransfer()) {
if ($quoteItem->getAdditionalInformationTransferDate() != $originalQuoteItem->getAdditionalInformationTransferDate()) {
$quoteItem->setTransferDatesWithAdditionalInformation();
}
//Save the title from-to
$title[] = $quoteItem->getAdditionalInformationTransferPickupLocationName();
$title[] = $quoteItem->getAdditionalInformationTransferDropoffLocationName();
$quoteItem->setName(implode(" - ", $title));
}
if ($quoteItem->isCarRental()) {
if ($quoteItem->getRentalCarPickupDateTimeWithAdditionalInformation() != $originalQuoteItem->getRentalCarPickupDateTimeWithAdditionalInformation() ||
$quoteItem->getRentalCarDropoffDateTimeWithAdditionalInformation() != $originalQuoteItem->getRentalCarPickupDateTimeWithAdditionalInformation()) {
$quoteItem->setRentalCarDatesWithAdditionalInformation();
}
}
if ($quoteItem->getCheckIn() > $quoteItem->getCheckOut()) {
throw new \Exception("Check in date must be lower than check out date");
}
if ($cancellationPolicyFrontEnd) {
if ($quoteItem->getCheckIn()) {
$penaltyDate = null;
if (!is_null($cancellationPolicyFrontEnd->getD()) && $cancellationPolicyFrontEnd->getD() !== null) {
// days and time
$penaltyDateStr = $quoteItem->getCheckIn()->format('Y-m-d');
if ($cancellationPolicyFrontEnd->getH() === null) {
//Get time from check in ,if there is no select it
$penaltyDateStr = $quoteItem->getCheckIn()->format('Y-m-d\TH:i:s\Z');
} else {
$penaltyDateStr .= 'T' . $cancellationPolicyFrontEnd->getH() . ':00Z';
}
$penaltyDate = new \DateTime($penaltyDateStr);
$penaltyDate->sub(new \DateInterval("P" . $cancellationPolicyFrontEnd->getD() . "D"));
}
$quoteItem->setCancellationPenaltyDate($penaltyDate);
$cancellationPolicy = array();
if ($penaltyDate) {
$penaltyStr = "";
if ($cancellationPolicyFrontEnd->getPenalty() && $cancellationPolicyFrontEnd->getType()) {
$penaltyStr = $cancellationPolicyFrontEnd->getPenalty() . " " . $cancellationPolicyFrontEnd->getType();
}
$cancellationPolicy = $quoteItem->getCancellationPolicy();
if(!array_key_exists("0",$cancellationPolicy)){
$cancellationPolicy['id'] = 'manual';
$cancellationPolicy['name'] = $penaltyStr;
$cancellationPolicy['type'] = $cancellationPolicyFrontEnd->getType();
$cancellationPolicy['penalty'] = $cancellationPolicyFrontEnd->getPenalty();
$cancellationPolicy['description'] = $penaltyStr;
$cancellationPolicy['penaltyDate'] = $penaltyDate->format(\DATE_W3C);
} else { //clean up junk
$tempPolicy = [];
foreach($cancellationPolicy as $key => $row){
if(is_numeric($key)){
$tempPolicy[$key] = $row;
}
}
$cancellationPolicy = $tempPolicy;
}
}
if($quoteItem->canCancellationPolicyBeUpdated()){
$quoteItem->setCancellationPolicy($cancellationPolicy);
}
//setting the children
$childQuoteItem = $quoteItem->getChildrenQuoteItems();
foreach ($childQuoteItem as $childQuoteItem) {
if (in_array($childQuoteItem->getType(), ['resortFee', 'hotel_service'])) {
$childQuoteItem->setCancellationPolicy($cancellationPolicy);
}
}
}
}
if (count($supplierCancellationPolicyFrontEnds) > 0 && $quoteItem->canCancellationPolicyBeUpdated()) {
$supplierCancellationPolicies = array();
foreach ($supplierCancellationPolicyFrontEnds as $supplierCancellationPolicyFrontEnd) {
if ($supplierCancellationPolicyFrontEnd && $quoteItem->getCheckIn()) {
$penaltyDate = null;
if (!is_null($supplierCancellationPolicyFrontEnd->getD()) && $supplierCancellationPolicyFrontEnd->getD() !== null) {
// days and time
$penaltyDateStr = $quoteItem->getCheckIn()->format('Y-m-d');
if ($supplierCancellationPolicyFrontEnd->getH() === null) {
//Get time from check in ,if there is no select it
$penaltyDateStr = $quoteItem->getCheckIn()->format('Y-m-d\TH:i:s\Z');
} else {
$penaltyDateStr .= 'T' . $supplierCancellationPolicyFrontEnd->getH() . ':00Z';
}
$penaltyDate = new \DateTime($penaltyDateStr);
$penaltyDate->sub(new \DateInterval("P" . $supplierCancellationPolicyFrontEnd->getD() . "D"));
}
$cancellationPolicy = array();
if ($penaltyDate) {
$penaltyStr = "";
if ($supplierCancellationPolicyFrontEnd->getPenalty() && $supplierCancellationPolicyFrontEnd->getType()) {
$penaltyStr = $supplierCancellationPolicyFrontEnd->getPenalty() . " " . $supplierCancellationPolicyFrontEnd->getType();
}
$cancellationPolicy = $quoteItem->getCancellationPolicy();
$cancellationPolicy['id'] = 'manual';
$cancellationPolicy['name'] = $penaltyStr;
$cancellationPolicy['type'] = $supplierCancellationPolicyFrontEnd->getType();
$cancellationPolicy['penalty'] = $supplierCancellationPolicyFrontEnd->getPenalty();
$cancellationPolicy['description'] = $penaltyStr;
$cancellationPolicy['penaltyDate'] = $penaltyDate->format(\DATE_W3C);
}
$supplierCancellationPolicies[] = $cancellationPolicy;
}
}
$quoteItem->setCancellationPolicySupplier($supplierCancellationPolicies);
//setting the children
$childQuoteItems = $quoteItem->getChildrenQuoteItems();
foreach ($childQuoteItems as $childQuoteItem) {
if (in_array($childQuoteItem->getType(), ['resortFee', 'hotel_service'])) {
$childQuoteItem->setCancellationPolicySupplier($supplierCancellationPolicies);
$childQuoteItem->setUseOxCancellationPolicy($quoteItem->getUseOxCancellationPolicy() ?? false);
}
}
}
if (count($oxCancellationPolicyFrontEnds) > 0) {
$oxCancellationPolicies = array();
foreach ($oxCancellationPolicyFrontEnds as $oxCancellationPolicyFrontEnd) {
if ($oxCancellationPolicyFrontEnd && $quoteItem->getCheckIn()) {
$penaltyDate = null;
if (!is_null($oxCancellationPolicyFrontEnd->getD()) && $oxCancellationPolicyFrontEnd->getD() !== null) {
// days and time
$penaltyDateStr = $quoteItem->getCheckIn()->format('Y-m-d');
if ($oxCancellationPolicyFrontEnd->getH() === null) {
//Get time from check in ,if there is no select it
$penaltyDateStr = $quoteItem->getCheckIn()->format('Y-m-d\TH:i:s\Z');
} else {
$penaltyDateStr .= 'T' . $oxCancellationPolicyFrontEnd->getH() . ':00Z';
}
$penaltyDate = new \DateTime($penaltyDateStr);
$penaltyDate->sub(new \DateInterval("P" . $oxCancellationPolicyFrontEnd->getD() . "D"));
}
$cancellationPolicy = array();
if ($penaltyDate) {
$penaltyStr = "";
if ($oxCancellationPolicyFrontEnd->getPenalty() && $oxCancellationPolicyFrontEnd->getType()) {
$penaltyStr = $oxCancellationPolicyFrontEnd->getPenalty() . " " . $oxCancellationPolicyFrontEnd->getType();
}
$cancellationPolicy = $quoteItem->getCancellationPolicy();
$cancellationPolicy['id'] = 'manual';
$cancellationPolicy['name'] = $penaltyStr;
$cancellationPolicy['type'] = $oxCancellationPolicyFrontEnd->getType();
$cancellationPolicy['penalty'] = $oxCancellationPolicyFrontEnd->getPenalty();
$cancellationPolicy['description'] = $penaltyStr;
$cancellationPolicy['penaltyDate'] = $penaltyDate->format(\DATE_W3C);
}
$oxCancellationPolicies[] = $cancellationPolicy;
}
}
$quoteItem->setCancellationPolicyOx($oxCancellationPolicies);
//setting the children
$childQuoteItems = $quoteItem->getChildrenQuoteItems();
foreach ($childQuoteItems as $childQuoteItem) {
if (in_array($childQuoteItem->getType(), ['resortFee', 'hotel_service'])) {
$childQuoteItem->setCancellationPolicyOx($oxCancellationPolicies);
$childQuoteItem->setUseOxCancellationPolicy($quoteItem->getUseOxCancellationPolicy() ?? false);
}
}
}
$quoteItem->setCancellationPenaltyDate($quoteItem->getCancellationPolicyDate());
if($originalQuoteItem) {
if ($originalQuoteItem->getCancellationPolicy() != $quoteItem->getCancellationPolicy()) {
//todo BAV handle if manually entered supplier policy
//The cancellation policy was edited.
$quoteItem->setCancellationPolicyIsCustomized(true);
}
//If the supplier was changed, and the Quote Item was already invoiced, we have to make sure to cancel the bill in QBO
// for the original supplier and create a new bill for the new supplier.
if ($originalQuoteItem->requiresASupplier()) {
if ($originalQuoteItem->getVendorId() && ($originalQuoteItem->getVendorId() != $quoteItem->getVendorId())) {
//Supplies changes...
if (!$originalQuoteItem->canOverriteSupplier($this->getUser())) {
throw new \Exception("Supplier cannot be changed.");
}
//If the supplier was changed, and the Quote Item was already invoiced, we have to make sure to cancel the bill in QBO
// for the original supplier and create a new bill for the new supplier.
$quickbooksAPI->updateSupplier($quoteItem, $coreApi);
}
}
if ($originalQuoteItem && ($originalQuoteItem->getConfirmationNumber() != $quoteItem->getConfirmationNumber())
&& $quoteItem->getConfirmationNumber()) {
if($quoteItem->isRefused()){
//Confirmation number cannot be added to a refused quote item
throw new \Exception("This quote item has status REFUSED, confirmation number cannot be added.");
}
if ($quoteItem->canBeManuallyUpdatedConfNumberAndBook()) {
if ($quoteItem->getSource() == QuoteItem::PRODUCT_SOURCE_STATIC) {
if (empty($quoteItem->getApiReservationId())) {
$confNo = $quoteItem->getConfirmationNumber();
$reservationFactory->bookRequest($notificationSystem, $coreApi, $quoteItem, $this->generateUrl('quote_edit', array('id' => $quoteItem->getQuote()->getId())), true);
//The bookRequest process clears out the conf # so we need to set it back
$quoteItem->setConfirmationNumber($confNo);
}
$reservation = $reservationApi->getReservationById($quoteItem->getApiReservationId());
$reservationToken = $reservation['reservations'][0]['reservationNumber'] ?? "";
if ($reservationToken != "") {
$reservationApi->setReservationConfirmationNumber($reservationToken, $quoteItem->getApiReservationId(), $quoteItem->getConfirmationNumber());
}
$quoteItem->setReservationStatus(QuoteItem::RESERVATION_STATUS_BOOK);
$refreshQuoteStatus = true;
} else {
$reservationFactory->bookRequest($notificationSystem, $coreApi, $quoteItem, $this->generateUrl('quote_edit', array('id' => $quoteItem->getQuote()->getId())), true);
}
$this->addFlash('success', "Confirmation Number was updated. Reservation status changed to Booked");
}
// else{
// $quoteItem->setConfirmationNumber($originalQuoteItem->getConfirmationNumber());
// $this->addFlash('warning', "Confirmation Number cannot be updated.");
// }
}
}
$data = $request->request->all();
if (!array_key_exists("my_quote_item", $data)) { //$data['my_quote_item']["quoteItem"]["checkIn"]
$data["my_quote_item"] = array();
}
if (!array_key_exists("quoteItem", $data["my_quote_item"])) { //$data['my_quote_item']["quoteItem"]["checkIn"]
$data["my_quote_item"]["quoteItem"] = array();
}
if (empty($data['my_quote_item']["quoteItem"]["checkIn"])) {
$data['my_quote_item']["quoteItem"]["checkIn"] = $quoteItem->getCheckInString();
}
if (empty($data['my_quote_item']["quoteItem"]["checkOut"])) {
$data['my_quote_item']["quoteItem"]["checkOut"] = $quoteItem->getCheckOutString();
}
$quoteItem->setUseOxCancellationPolicy($data['my_quote_item']["useOxCancellationPolicy"] ?? false);
// if($quoteItem->getType()==QuoteItem::PRODUCT_TYPE_ACTIVITY){
// $quoteItem->setAdditionalInformation(array("dateKey"=>$quoteItem->getCheckIn(),"priceType"=>array()));
// }
$this->getCancellationPolicyLabel($quoteItem);
if (key_exists('my_quote_item', $data)) {
$dataMyQuoteItem = $data['my_quote_item'];
if (key_exists('newVoucherAdditionalNotes', $dataMyQuoteItem) && $dataMyQuoteItem['newVoucherAdditionalNotes']) {
$quoteItem->addVoucherAdditionalNote($dataMyQuoteItem['newVoucherAdditionalNotes']);
}
}
if (in_array($quoteItem->getType(), [QuoteItem::PRODUCT_TYPE_HOTEL_RESORT_FEE, QuoteItem::PRODUCT_TYPE_HOTEL_SERVICE])) {
$parentQuoteItem = $this->getDoctrine()->getRepository(QuoteItem::class)->findOneBy(array('id' => $quoteItem->getParentQuoteItem()->getId()));
$quoteItem->setOriginalCurrency($parentQuoteItem->getOriginalCurrency());
$quoteItem->setDisplayInOriginalCurrency($parentQuoteItem->getDisplayInOriginalCurrency() ?? false);
$quoteItem->setExchangeRate($parentQuoteItem->getExchangeRate());
}
if (key_exists('ratesDetail', $data)) {
if ($data['ratesDetail']['customerAccountCommissionPercentage'] != $quoteItem->getCustomerAccountCommissionPercentage()) {
$quoteItem->setCustomerAccountCommissionPercentage($data['ratesDetail']['customerAccountCommissionPercentage']);
}
if (key_exists('ratesDetail', $data) and is_array($data['ratesDetail'])) {
//Transform string to float values and reset to USD if needed:
foreach ($data['ratesDetail'] as $key => $value) {
if (strpos($key, '-') === false) {
$data['ratesDetail'][$key] = $this->convertStrToFloat($value);
if ($quoteItem->getDisplayInOriginalCurrency() && stripos($key, 'percent') === false && stripos($key, 'tax') === false && stripos($key, 'netRateDetailNetCom') === false) {
$data['ratesDetail'][$key] = floatval($data['ratesDetail'][$key] / $quoteItem->getExchangeRate());
}
} else {
foreach ($data['ratesDetail'][$key] as $keyDate => $valueDate) {
if (strpos($keyDate, '-') === false) {
$data['ratesDetail'][$key][$keyDate] = $this->convertStrToFloat($valueDate);
if ($quoteItem->getDisplayInOriginalCurrency() && stripos($keyDate, 'percent') === false && stripos($keyDate, 'tax') === false && stripos($keyDate, 'netRateDetailNetCom') === false) {
$data['ratesDetail'][$key][$keyDate] = floatval($data['ratesDetail'][$key][$keyDate] / $quoteItem->getExchangeRate());
}
}
}
$testDate = \DateTime::createFromFormat('m-d-Y', $key);
if ($testDate == null) {
$testDate = \DateTime::createFromFormat('d-m-Y', $key);
}
if ($testDate !== false) {
$correctedDate = $testDate->format('Y-m-d');
$data['ratesDetail'][$correctedDate] = $data['ratesDetail'][$key];
unset($data['ratesDetail'][$key]);
}
}
}
}
$correctedRatesTable = [];
$currentRatesTable = $quoteItem->getFullRateTableDetail() ?? [];
foreach ($currentRatesTable as $date => $row) {
$testDate = \DateTime::createFromFormat('m-d-Y', $date);
if ($testDate == null) {
$testDate = \DateTime::createFromFormat('d-m-Y', $date);
}
if ($testDate !== false) {
$correctedDate = $testDate->format('Y-m-d');
$correctedRatesTable[$correctedDate] = $row;
} else {
$correctedRatesTable[$date] = $row;
}
}
if (count($correctedRatesTable) > 0) {
$quoteItem->setFullRateTableDetail($correctedRatesTable);
}
$updatedRates = false;
//Check the rates
if ($quoteItem->canRatesBeUpdated()) { //Net rates cannot be edited when the source is dynamic
$netRateDetail = in_array($quoteItem->getType(), [QuoteItem::PRODUCT_TYPE_ACTIVITY, QuoteItem::PRODUCT_TYPE_VILLA]) ? false : $quoteItem->getNetRateDetail();
if ((in_array($quoteItem->getType(), [QuoteItem::PRODUCT_TYPE_HOTEL_SERVICE, QuoteItem::PRODUCT_TYPE_TRANSFER, QuoteItem::PRODUCT_TYPE_CAR_RENTAL])) && !empty($netRateDetail) && self::adjustRateDates($netRateDetail, $quoteItem->getCheckInAsDate(), $quoteItem->getCheckOutAsDate(), $request->request->all(), 'net')) {
$quoteItem->setNetRateDetail($netRateDetail);
}
$netRateDetailNetComKey = key_exists('netRateDetailNetComTotal', $data['ratesDetail']) ? 'netRateDetailNetComTotal' : 'netRateDetailNetCom';
if ($this->updateCustomRatesDetail($netRateDetail, $data, 'netTax', 'netRateDetailPrice', 'netRateDetailFee', 1, $netRateDetailNetComKey)) {
$updatedRates = true;
$quoteItem->setNetIsCustomized(true);
$quoteItem->setNetRateDetail($netRateDetail);
//Net Prices
$quoteItem->setNetTaxPercentage($data['ratesDetail']['netTax']);
$quoteItem->setNetBeforeTax($data['ratesDetail']['netRateDetailPriceTotal']);
$quoteItem->setNetTax($data['ratesDetail']['netTax'] * $quoteItem->getNetBeforeTax() / 100); //CHECK THIS VALUE
$quoteItem->setNetFee($data['ratesDetail']['netRateDetailFeeTotal']);
$quoteItem->setNetTotal($quoteItem->getNetTax() + $quoteItem->getNetFee() + $quoteItem->getNetBeforeTax()); //CHECK THIS VALUE
//$quoteItem->setNetAdditionalBeforeTax(0);
}
if ($quoteItem->getNetTotal() != $originalQuoteItem->getNetTotal() && $quoteItem->getQuickbookPayableReferenceId() && $quickbooksAPI) {
if ($parentQuoteItem = $quoteItem->getParentQuoteItem()) {
$quickbooksAPI->qbPayable($parentQuoteItem);
}else{
$quickbooksAPI->qbPayable($quoteItem);
}
}
}
$customerAccountCommissionPercentage = abs($data['ratesDetail']['customerAccountCommissionPercentage']);
$commissionRateDetail = in_array($quoteItem->getType(), [QuoteItem::PRODUCT_TYPE_ACTIVITY, QuoteItem::PRODUCT_TYPE_VILLA]) ? false : $quoteItem->getCommissionRateDetail();
if ((in_array($quoteItem->getType(), [QuoteItem::PRODUCT_TYPE_HOTEL_SERVICE, QuoteItem::PRODUCT_TYPE_TRANSFER, QuoteItem::PRODUCT_TYPE_CAR_RENTAL])) && !empty($commissionRateDetail) && self::adjustRateDates($commissionRateDetail, $quoteItem->getCheckInAsDate(), $quoteItem->getCheckOutAsDate(), $request->request->all(), 'commission')) {
$quoteItem->setCommissionRateDetail($commissionRateDetail);
}
if ($customerAccountCommissionPercentage != $originalQuoteItem->getCustomerAccountCommissionPercentage() | ($this->updateCustomRatesDetail($commissionRateDetail, $data, 'retailTax', 'retailRateDetailPrice', 'retailRateDetailFee'))) {
$updatedRates = true;
if (!$commissionRateDetail) {
$this->updateCustomRatesDetail($commissionRateDetail, $data, 'retailTax', 'retailRateDetailPrice', 'retailRateDetailFee');
}
$quoteItem->setRetailTaxPercentage($data['ratesDetail']['retailTax']);
//Commission Prices
$quoteItem->setCommissionIsCustomized(true);
$quoteItem->setCommissionRateDetail($commissionRateDetail ?? null);
$quoteItem->setCommissionFee($data['ratesDetail']['retailRateDetailFeeTotal']);
$quoteItem->setCommissionBeforeTax($data['ratesDetail']['retailRateDetailPriceTotal']);
$quoteItem->setCommissionTax($data['ratesDetail']['retailTax'] * $quoteItem->getCommissionBeforeTax() / 100);
$quoteItem->setCommissionTotal($quoteItem->getCommissionTax() + $quoteItem->getCommissionFee(false) + $quoteItem->getCommissionBeforeTax());
//Retail prices
$customerAccountCommissionPercentage = abs($data['ratesDetail']['customerAccountCommissionPercentage']);
$quoteItem->setCustomerAccountCommissionPercentage($customerAccountCommissionPercentage);
if (!$customerAccountCommissionPercentage) {
$updatedRates = true;
$quoteItem->setRetailIsCustomized(true);
$quoteItem->setRetailRateDetail($commissionRateDetail);
$quoteItem->setRetailFee($quoteItem->getCommissionFee(false));
$quoteItem->setRetailBeforeTax($quoteItem->getCommissionBeforeTax());
$quoteItem->setRetailTax($quoteItem->getCommissionTax());
$quoteItem->setRetailTotal($quoteItem->getCommissionTotal());
} else {
$retailRateDetail = in_array($quoteItem->getType(), [QuoteItem::PRODUCT_TYPE_ACTIVITY, QuoteItem::PRODUCT_TYPE_VILLA]) ? false : $quoteItem->getRetailRateDetail();
if (($quoteItem->getType() == QuoteItem::PRODUCT_TYPE_HOTEL_SERVICE) && self::adjustRateDates($retailRateDetail, $quoteItem->getCheckInAsDate(), $quoteItem->getCheckOutAsDate(), $request->request->all(), 'retail')) {
$quoteItem->setRetailRateDetail($retailRateDetail);
}
$customerAccountCommissionFactor = 1 - ($customerAccountCommissionPercentage / 100);
$this->updateCustomRatesDetail($retailRateDetail, $data, 'retailTax', 'retailRateDetailPrice', 'retailRateDetailFee', $customerAccountCommissionFactor);
$quoteItem->setRetailRateDetail($retailRateDetail);
$quoteItem->setRetailFee($quoteItem->getCommissionFee(false));
$quoteItem->setRetailBeforeTax($quoteItem->getCommissionBeforeTax() * $customerAccountCommissionFactor);
$quoteItem->setRetailTax($quoteItem->getCommissionTax() * $customerAccountCommissionFactor);
$quoteItem->setRetailTotal($quoteItem->getRetailTax() + $quoteItem->getRetailFee() + $quoteItem->getRetailBeforeTax());
}
}
if ($quoteItem->isTransfer()) {
$quoteItem->setAdditionalInformationTransferVehicleRates();
}
}
if ((key_exists('showRatesInOneLine', $data))) {
$quoteItem->setShowRatesInOneLine($data['showRatesInOneLine']);
} else {
$quoteItem->setShowRatesInOneLine(false);
}
$em = $this->getDoctrine()->getManager();
$em->persist($quoteItem);
//Refresh quote Start date and End date.
$quoteItem->getQuote()->refreshQuoteDates($quoteItem->getCheckInAsDate(), $quoteItem->getCheckOutAsDate());
$em->persist($quoteItem->getQuote());
$em->flush();
$em->refresh($quoteItem);
if ($originalQuoteItem &&
($originalQuoteItem->getCheckIn() != $quoteItem->getCheckIn() || $originalQuoteItem->getCheckOut() != $quoteItem->getCheckOut())) {
$this->addFlash('success', 'The Quote dates has been updated');
}
if ($actionString == 'added' || $refreshQuoteStatus) {
//Refresh status
$quoteItem->getQuote()->refreshQuoteReservationStatus();
$quoteItem->getQuote()->refreshQuoteAccountingStatus();
$em->persist($quoteItem->getQuote());
$em->flush();
$em->refresh($quoteItem);
if($actionString == 'added'){
if ($quoteItemsSorted = $em->getRepository(QuoteItem::class)->quoteItemsSorted($quoteItem->getQuote()->getId(), 'myQuotes')) {
if ($quoteItemsUpdate = $quoteItem->getQuote()->refreshSortQuoteItemsByNewQuoteItem($quoteItem, $quoteItemsSorted)) {
foreach ($quoteItemsUpdate as $quoteItemUpdate) {
$em->persist($quoteItemUpdate);
$em->flush();
}
}
}
}
}
if (count($quoteItem->getChildrenQuoteItems())) {
foreach ($quoteItem->getChildrenQuoteItems() as $childQuoteItem) {
$childQuoteItem->setClientNameJson($quoteItem->getClientNameJson())
->setClientLastNameJson($quoteItem->getClientLastNameJson());
if (in_array($childQuoteItem->getType(), array(QuoteItem::PRODUCT_TYPE_HOTEL_RESORT_FEE, QuoteItem::PRODUCT_TYPE_HOTEL_SERVICE))) {
//If the cancellation policy of the parent hotel is updated, we need to update the cancellation
// policy of the resort fee
$childQuoteItem->setCancellationPolicy($quoteItem->getCancellationPolicy());
$childQuoteItem->setCancellationPenaltyDate($quoteItem->getCancellationPenaltyDate());
$childQuoteItem->setCancellationPenaltyId($quoteItem->getCancellationPenaltyId());
$childQuoteItem->setCancellationPolicyLabel($quoteItem->getCancellationPolicyLabels());
$childQuoteItem->setUseOxCancellationPolicy($quoteItem->getUseOxCancellationPolicy());
$childQuoteItem->setCancellationPolicyOx($quoteItem->getCancellationPolicyOx());
$childQuoteItem->setCancellationPolicySupplier($quoteItem->getCancellationPolicySupplier());
$childQuoteItem->setOriginalCurrency($quoteItem->getOriginalCurrency());
$childQuoteItem->setDisplayInOriginalCurrency($quoteItem->getDisplayInOriginalCurrency() ?? false);
$childQuoteItem->setExchangeRate($quoteItem->getExchangeRate());
}
$em->persist($childQuoteItem);
}
$em->flush();
}
$billingSupplier = $request->request->get('additionalInformation_billing_supplier') ?? null;
if ($billingSupplier != null && $quoteItem->getSource() == QuoteItem::PRODUCT_SOURCE_MANUALLY) {
$billingSupplier = $billingSupplier > 0 ? $billingSupplier : null;
$quoteItem->setAdditionalInformation(['billing_supplier' => $billingSupplier]);
}
$quote = $quoteItem->getQuote();
$hubSpotAPI->deal($quote);
$this->addFlash('success', 'The Quote Item has been ' . $actionString);
return $this->redirectToRoute('my_quoteItem_edit', array('id' => $quoteItem->getId()));
}
} catch (\Exception $e) {
$this->addFlash('error', "<p>The Quote Item couldn't be saved.</p><p></p> Error: <br/>" . $e->getMessage() . "</p>");
return $form;
}
}
private function setCancellationPolicyFrontEnd(QuoteItem $quoteItem, &$cancellationPolicyFrontEnd)
{
if ($cancellationPolicyData = $quoteItem->getCancellationPolicy()) {
if (key_exists("penaltyDate", $cancellationPolicyData) && $cancellationPolicyData["penaltyDate"] && $quoteItem->getCheckIn()) {
//Get days and time
if(is_string($cancellationPolicyData["penaltyDate"])){
$cancellationPolicyData["penaltyDate"] = new \DateTime($cancellationPolicyData["penaltyDate"]);
}
$diff = $quoteItem->getCheckInAsDate()->diff($cancellationPolicyData["penaltyDate"]);
if($quoteItem->getType() == QuoteItem::PRODUCT_TYPE_HOTEL && $diff->h > 0){
$cancellationPolicyFrontEnd->setD($diff->days + 1); //add one to account for the hours
$cancellationPolicyFrontEnd->setH(0);
} else {
$cancellationPolicyFrontEnd->setD($diff->days);
$cancellationPolicyFrontEnd->setH($diff->h);
}
$cancellationPolicyFrontEnd->setTz($cancellationPolicyData["penaltyDate"]->getTimeZone());
$cancellationPolicyFrontEnd->setPenalty($cancellationPolicyData['penalty']);
$cancellationPolicyFrontEnd->setType($cancellationPolicyData['type']);
}
}
}
private function setCancellationPolicyFrontEnds(QuoteItem $quoteItem, Request $request, &$supplierCancellationPolicyFrontEnds, &$oxCancellationPolicyFrontEnds)
{
$originalCancellationPolicies = $quoteItem->getInitialCancellationPolicy();
$supplierCancellationPolicies = $quoteItem->getCancellationPolicySupplier();
if(null != $supplierCancellationPolicies && array_key_exists('penaltyDate',$supplierCancellationPolicies)){ //make it an array of 1
$tempCancellationPolicies = array($supplierCancellationPolicies);
$supplierCancellationPolicies = $tempCancellationPolicies;
}
$oxCancellationPolicies = $quoteItem->getCancellationPolicyOx();
if(null != $oxCancellationPolicies && array_key_exists('penaltyDate',$oxCancellationPolicies)){ //make it an array of 1
$tempCancellationPolicies = array($oxCancellationPolicies);
$oxCancellationPolicies = $tempCancellationPolicies;
}
foreach($supplierCancellationPolicies as $index => $supplierCancellationPolicy){
if($cancellationPolicyData = $supplierCancellationPolicy){
$cancellationPolicyFrontEnd = new CancellationPolicyModel();
if(key_exists("penaltyDate", $cancellationPolicyData) && $cancellationPolicyData["penaltyDate"] && $quoteItem->getCheckIn()){
//Get days and time
if(is_string($cancellationPolicyData["penaltyDate"])){
try{
$penaltyDate = date_create_from_format(\DATE_W3C, $cancellationPolicyData["penaltyDate"]);
if (!$penaltyDate) {
$penaltyDate = date_create_from_format('Y-m-d H:i:s', $cancellationPolicyData["penaltyDate"]);
//new \DateTime($cancellationPolicyData["penaltyDate"]);
}
$cancellationPolicyData["penaltyDate"] = $penaltyDate;
}catch(\Exception $e){
}
}
if(is_array($cancellationPolicyData["penaltyDate"])){
try{
$cancellationPolicyData["penaltyDate"] = new \DateTime($cancellationPolicyData["penaltyDate"]['date']);
}catch(\Exception $e){
}
}
$penaltyDayObj = new \DateTime($cancellationPolicyData["penaltyDate"]->format('Y-m-d'));//need just the date part
$diff = $quoteItem->getCheckInAsDate()->diff($penaltyDayObj);
$hour = $cancellationPolicyData?$cancellationPolicyData["penaltyDate"]->format('H'):0;
if($quoteItem->getType() == QuoteItem::PRODUCT_TYPE_HOTEL && $diff->h > 0){
$cancellationPolicyFrontEnd->setD($diff->days + 1); //add one to account for the hours
$cancellationPolicyFrontEnd->setH($hour);
}else{
$cancellationPolicyFrontEnd->setD($diff->days);
$cancellationPolicyFrontEnd->setH($hour);
}
$cancellationPolicyFrontEnd->setTz($cancellationPolicyData["penaltyDate"]->getTimeZone());
$cancellationPolicyFrontEnd->setPenalty($cancellationPolicyData['penalty']);
$cancellationPolicyFrontEnd->setType($cancellationPolicyData['type']);
}
$supplierCancellationPolicyFrontEnds[] = $cancellationPolicyFrontEnd;
}
}
foreach($oxCancellationPolicies as $oxCancellationPolicy){
if($cancellationPolicyData = $oxCancellationPolicy){
$cancellationPolicyFrontEnd = new CancellationPolicyModel();
if(key_exists("penaltyDate", $cancellationPolicyData) && $cancellationPolicyData["penaltyDate"] && $quoteItem->getCheckIn()){
//Get days and time
if(is_string($cancellationPolicyData["penaltyDate"])){
try{
$penaltyDate = date_create_from_format(\DATE_W3C, $cancellationPolicyData["penaltyDate"]);
if (!$penaltyDate) {
$penaltyDate = date_create_from_format('Y-m-d H:i:s', $cancellationPolicyData["penaltyDate"]);
//new \DateTime($cancellationPolicyData["penaltyDate"]);
}
$cancellationPolicyData["penaltyDate"] = $penaltyDate;
}catch(\Exception $e){
}
}
if(is_array($cancellationPolicyData["penaltyDate"])){
try{
$cancellationPolicyData["penaltyDate"] = new \DateTime($cancellationPolicyData["penaltyDate"]['date']);
}catch(\Exception $e){
}
}
$penaltyDayObj = new \DateTime($cancellationPolicyData["penaltyDate"]->format('Y-m-d'));//need just the date part
$diff = $quoteItem->getCheckInAsDate()->diff($penaltyDayObj);
$hour = $cancellationPolicyData?$cancellationPolicyData["penaltyDate"]->format('H'):0;
if($quoteItem->getType() == QuoteItem::PRODUCT_TYPE_HOTEL && $diff->h > 0){
$cancellationPolicyFrontEnd->setD($diff->days + 1); //add one to account for the hours
$cancellationPolicyFrontEnd->setH($hour);
}else{
$cancellationPolicyFrontEnd->setD($diff->days);
$cancellationPolicyFrontEnd->setH($hour);
}
$cancellationPolicyFrontEnd->setTz($cancellationPolicyData["penaltyDate"]->getTimeZone());
$cancellationPolicyFrontEnd->setPenalty($cancellationPolicyData['penalty']);
$cancellationPolicyFrontEnd->setType($cancellationPolicyData['type']);
}
$oxCancellationPolicyFrontEnds[] = $cancellationPolicyFrontEnd;
}
}
//add new cancellation policy rows if any were added
$requestQuoteItemData = $request->request->get('my_quote_item');
$countNewSupplierPolicies = isset($requestQuoteItemData) && isset($requestQuoteItemData['supplierCancellationPolicyFrontEnds']) ? count($requestQuoteItemData['supplierCancellationPolicyFrontEnds']):0;
if(isset($requestQuoteItemData) && isset($requestQuoteItemData['supplierCancellationPolicyFrontEnds']) && count($supplierCancellationPolicyFrontEnds) < $countNewSupplierPolicies){
//need to adjust the form
$nextIndex = count($supplierCancellationPolicyFrontEnds);
foreach( $requestQuoteItemData['supplierCancellationPolicyFrontEnds'] as $index => $supplierCancellationPolicyFrontEndData){
if($index >= $nextIndex){
$cancellationPolicyFrontEnd = new CancellationPolicyModel();
$cancellationPolicyFrontEnd->setD(intval($supplierCancellationPolicyFrontEndData['d']));
$cancellationPolicyFrontEnd->setH(intval($supplierCancellationPolicyFrontEndData['h']??0));
//$cancellationPolicyFrontEnd->setTz($cancellationPolicyData["penaltyDate"]->getTimeZone());
$cancellationPolicyFrontEnd->setPenalty(intval($supplierCancellationPolicyFrontEndData['penalty']));
$cancellationPolicyFrontEnd->setType($supplierCancellationPolicyFrontEndData['type']??"");
$supplierCancellationPolicyFrontEnds[] = $cancellationPolicyFrontEnd;
}
}
}
$countNewOxPolicies = isset($requestQuoteItemData) && isset($requestQuoteItemData['oxCancellationPolicyFrontEnds']) ? count($requestQuoteItemData['oxCancellationPolicyFrontEnds']):0;
if(isset($requestQuoteItemData) && isset($requestQuoteItemData['oxCancellationPolicyFrontEnds']) && count($oxCancellationPolicyFrontEnds) < $countNewOxPolicies){
//need to adjust the form
$nextIndex = count($oxCancellationPolicyFrontEnds);
foreach( $requestQuoteItemData['oxCancellationPolicyFrontEnds'] as $index => $oxCancellationPolicyFrontEndData){
if($index >= $nextIndex){
$cancellationPolicyFrontEnd = new CancellationPolicyModel();
$cancellationPolicyFrontEnd->setD(intval($oxCancellationPolicyFrontEndData['d']));
$cancellationPolicyFrontEnd->setH(intval($oxCancellationPolicyFrontEndData['h']??0));
//$cancellationPolicyFrontEnd->setTz($cancellationPolicyData["penaltyDate"]->getTimeZone());
$cancellationPolicyFrontEnd->setPenalty(intval($oxCancellationPolicyFrontEndData['penalty']));
$cancellationPolicyFrontEnd->setType($oxCancellationPolicyFrontEndData['type']??"");
$oxCancellationPolicyFrontEnds[] = $cancellationPolicyFrontEnd;
}
}
}
//
if(count($supplierCancellationPolicyFrontEnds) == 0){
$supplierCancellationPolicyFrontEnds[] = new CancellationPolicyModel();
}
if(count($oxCancellationPolicyFrontEnds) == 0){
$oxCancellationPolicyFrontEnds[] = new CancellationPolicyModel();
}
}
private function convertStrToFloat($str)
{
return (float)str_replace(",", "", $str);
}
private function updateCustomRatesDetail(&$specificRateDetail, $data, $taxTableName, $priceTableName, $feeTableName, $commissionFactor = 1, $hotelNetCommission = false)
{
$ratesDetailTable = $data['ratesDetail'];
$somethingChange = false;
if (!$specificRateDetail && $ratesDetailTable) {
foreach ($ratesDetailTable as $key => $rateDetail) {
$keyDate = \DateTime::createFromFormat('m-d-Y', $key);
if ($keyDate === false) {
$keyDate = \DateTime::createFromFormat('Y-m-d', $key);
if ($keyDate === false) {
$keyDate = \DateTime::createFromFormat("Y-m-d\TH:i:s\Z", $key);
}
}
if ($keyDate !== false) {
// it's a date
$specificRateDetail[$keyDate->format("Y-m-d")] = array(
"fee" => $ratesDetailTable[$key][$feeTableName],
"date" => $keyDate->format("Y-m-d\TH:i:s\Z"),
"price" => $ratesDetailTable[$key][$priceTableName],
"taxPercentage" => $ratesDetailTable[$taxTableName]);
if ($hotelNetCommission && key_exists($hotelNetCommission, $ratesDetailTable)) {
$specificRateDetail[$keyDate->format("Y-m-d")]["comPercentage"] = $ratesDetailTable[$hotelNetCommission];
}
$somethingChange = true;
}
}
} else {
foreach ($specificRateDetail as $key => $rateDetail) {
if (key_exists($key, $ratesDetailTable)) {
$keyDate = \DateTime::createFromFormat('d-m-Y', $key);
if ($keyDate === false) {
$keyDate = \DateTime::createFromFormat('Y-m-d', $key);
}
$keyDate = new \DateTime($keyDate->format('Y-m-d')); //strip off the hours
$checkInDT = new \DateTime($data['my_quote_item']["quoteItem"]["checkIn"]);
$checkOutDT = new \DateTime($data['my_quote_item']["quoteItem"]["checkOut"]);
if (($keyDate >= $checkInDT) && ($keyDate <= $checkOutDT)) { //If it's visible
$rateDetailTableByDate = $ratesDetailTable[$key];
if (($ratesDetailTable[$taxTableName]) != (string)$rateDetail['taxPercentage']) {
//Update taxPercentage
$specificRateDetail[$key]['taxPercentage'] = $ratesDetailTable[$taxTableName];
$somethingChange = true;
}
if (($rateDetailTableByDate[$priceTableName] * $commissionFactor) != (string)$rateDetail['price']) {
//Update price
$specificRateDetail[$key]['price'] = $rateDetailTableByDate[$priceTableName] * $commissionFactor;
$somethingChange = true;
}
if (($rateDetailTableByDate[$feeTableName]) != (string)$rateDetail['fee']) {
//Update fee
$specificRateDetail[$key]['fee'] = $rateDetailTableByDate[$feeTableName];
$somethingChange = true;
}
if ($hotelNetCommission) {
$netRateDetailNetComKey = key_exists('netRateDetailNetComTotal', $rateDetailTableByDate) ? 'netRateDetailNetComTotal' : 'netRateDetailNetCom';
if (
(!array_key_exists('comPercentage', $rateDetail) && array_key_exists($netRateDetailNetComKey, $rateDetailTableByDate))
||
(array_key_exists('comPercentage', $rateDetail) && array_key_exists($netRateDetailNetComKey, $rateDetailTableByDate) && $rateDetailTableByDate[$netRateDetailNetComKey] != (string)$rateDetail['comPercentage'])
) {
$specificRateDetail[$key]["comPercentage"] = $rateDetailTableByDate[$netRateDetailNetComKey];
$somethingChange = true;
}
}
} else {
$specificRateDetail[$key] = array(
"fee" => 0,
"date" => $keyDate->format("Y-m-d\TH:i:s\Z"),
"price" => 0,
"taxPercentage" => 0);
if ($hotelNetCommission && key_exists($hotelNetCommission, $ratesDetailTable)) {
$specificRateDetail[$key]["comPercentage"] = 0;
}
$somethingChange = true;
}
}
}
}
return $somethingChange;
}
/**
* @param QuoteItem $quoteItem
*/
private function getCancellationPolicyLabel(QuoteItem &$quoteItem)
{
//Get the array. Ex.:{"id": 24,"penaltyDate": "2021-04-27T00:00:00+00:00"}
if ($cancellationPolicy = $quoteItem->getCancellationPolicy()) {
if(key_exists('type',$cancellationPolicy)){
$cancellationType = $cancellationPolicy['type'];
if (($cancellationType == 'nights') && ($cancellationPolicy['penalty'] <= 1)) {
$cancellationType = 'night';
}
}
$quoteItem->setCancellationPolicyLabel("");
$quoteItem->setCancellationPolicy(array());
if(key_exists('penalty',$cancellationPolicy)){
if ($cancellationDescription = trim($cancellationPolicy['penalty'] . " " . $cancellationType)) {
$cancellationPolicy['name'] = $cancellationPolicy['description'] = $cancellationDescription;
$cancellationPenaltyString = "There is a penalty of " . $cancellationDescription;
if ($cancellationPolicy['penaltyDate']) {
$cancellationPenaltyString .= " when cancelling after " . $cancellationPolicy['penaltyDate']->format("M d, Y h:i A");
}
$quoteItem->setCancellationPenaltyDate($cancellationPolicy['penaltyDate']);
$quoteItem->setCancellationPolicyLabel($cancellationPenaltyString);
$penaltyDate = $cancellationPolicy['penaltyDate'];
$cancellationPolicy['penaltyDate'] = (string)$penaltyDate->format("Y-m-d\TH:i:s\Z");
}
} else {
$cancellationPolicy['penaltyDate'] = "";//null
$quoteItem->setCancellationPenaltyDate(null);
}
$quoteItem->setCancellationPolicy($cancellationPolicy);
}
}
/**
* @Route("/duplicate/{id}", name="my_quoteItem_duplicate", methods={"GET","POST"})
* @Security("is_granted('ROLE_USER_EDIT_CUSTOMER_ACCOUNT')")
* @param QuoteItem|null $quoteItem
* @return Response
*/
public function duplicateQuoteItem(Request $request, CoreApi $coreApi, QuoteItem $quoteItem = null): Response
{
try {
if (!$quoteItem) {
throw new \Exception('There is not a quote item to be duplicated.');
}
$newQuoteItem = $quoteItem->getDuplicate();
if ($newQuoteItem->isHotel() && !$newQuoteItem->isManuallyAdded()) {
//if the hotel is anything other than a manually added hotel, we will run a refresh price
//with the new dates, taking the latest prices from the API, if the price is not available
//anymore, we will set it as manual and set the princes to 0
if ($coreApi->refreshPrice($newQuoteItem)) {
//Change to manually
$newQuoteItem->setSource(QuoteItem::PRODUCT_SOURCE_MANUALLY);
$this->addFlash('warning', 'The rates were no longer available. This room has been set to manual rates');
}
}
$em = $this->getDoctrine()->getManager();
$em->persist($newQuoteItem);
$em->flush();
$em->refresh($quoteItem);
//Check if it has any children (i.e. hotel services)
if ($childrenQuoteItemList = $quoteItem->getChildrenQuoteItems()) {
foreach ($childrenQuoteItemList as $childrenQuoteItem) {
$duplicateChildrenQuoteItem = $childrenQuoteItem->getDuplicate();
$duplicateChildrenQuoteItem->setParentQuoteItem($newQuoteItem);
$em->persist($duplicateChildrenQuoteItem);
$em->flush();
$em->refresh($newQuoteItem);
}
}
$quoteItem->getQuote()->refreshQuoteDates();
$em->persist($quoteItem->getQuote());
$em->flush();
$em->refresh($quoteItem);
return $this->redirectToRoute('my_quoteItem_edit', array('id' => $newQuoteItem->getId()));
} catch (\Exception $e) {
$this->addFlash('error', "The Quote Item couldn't be duplicated");
}
return $this->redirectToRoute('my_quoteItem_edit', array('id' => $quoteItem->getId()));
}
private function getDataFormatString($date)
{
$keyDate = \DateTime::createFromFormat('d-m-Y', $date);
if ($keyDate === false) {
return 'Y-m-d';
} else {
return 'd-m-Y';
}
}
private function adjustRateDates(&$qiRateRows, $checkInDate, $checkOutDate, $requestData, $type): bool
{
$updated = false;
$newRateDetails = $requestData['ratesDetail'];
if ($checkInDate->format('Y-m-d') <= $checkOutDate->format('Y-m-d')) {
$qiDatesArray = array_keys($qiRateRows);
$dateFormat = self::getDataFormatString($qiDatesArray[0]);
$validDatesArray = array();
$testDate = clone $checkInDate;//new \DateTime($checkIn);
while ($testDate->format('Y-m-d') <= $checkOutDate->format('Y-m-d')) {
$validDatesArray[] = $testDate->format($dateFormat);
$testDate->modify('+1 day');
}
$qiRateDetailTemp = $qiRateRows;
$model = array();//Remove extraneous ones
foreach ($qiRateDetailTemp as $key => $data) {
$model = $data;
$testDate = \DateTime::createFromFormat($dateFormat, $key);
if ($testDate === false) {
$tempFormat = self::getDataFormatString($key);
$testDate = \DateTime::createFromFormat($tempFormat, $key);
}
if (!in_array($testDate->format($dateFormat), $validDatesArray)) {
unset($qiRateRows[$key]);
$updated = true;
}
}//add missing ones
foreach ($model as $key => $val) {
$model[$key] = 0.0;
}
$qiDatesArray = array_keys($qiRateRows);//Refresh
foreach ($validDatesArray as $key) {
$dateLikeDataFormat = \DateTime::createFromFormat($dateFormat, $key);
if (!in_array($dateLikeDataFormat->format($dateFormat), $qiDatesArray)) {
$newDate = $dateLikeDataFormat->format('d-m-Y');
if (!isset($newRateDetails[$newDate])) {
$newDate = $dateLikeDataFormat->format('Y-m-d/Z00:00:00/T');
}
switch ($type) {
case 'net':
$model['fee'] = $newRateDetails[$newDate]['netRateDetailFee'] ?? 0;
$model['price'] = $newRateDetails[$newDate]['netRateDetailPrice'] ?? 0;
$model['taxPercentage'] = $newRateDetails['netTax'] ?? 0;
$model['comPercentage'] = $newRateDetails[$newDate]['netRateDetailNetCom'] ?? 0;
break;
case 'commission':
case 'retail': //Todo Retail price is actually a bit different
$model['fee'] = $newRateDetails[$newDate]['retailRateDetailFee'] ?? 0;
$model['price'] = $newRateDetails[$newDate]['retailRateDetailPrice'] ?? 0;
$model['taxPercentage'] = $newRateDetails['retailTax'] ?? 0;
break;
}
$newDate = $dateLikeDataFormat->format($dateFormat);
$model['date'] = $newDate;
$qiRateRows[$newDate] = $model;
$updated = true;
}
}
}
return $updated;
}
/**
* @Route("/removeFile/{id}/{filename}", name="my_quoteItem_remove_file", methods={"GET","POST"})
* @Security("is_granted('ROLE_USER_EDIT_CUSTOMER_ACCOUNT')")
* @param QuoteItem|null $quoteItem
* @param null $filename
* @return Response
*/
public function removeFile(QuoteItem $quoteItem = null, $filename = null): Response
{
try {
if (!$quoteItem) {
throw new \Exception('There is not a quote item.');
}
if (!$filename) {
throw new \Exception("Filename is missing.");
}
//Get the dir and filename together
$filenameDir = $this->getParameter('quote_item_file_directory') . "/" . $filename;
//Delete file from dir
$filesystem = new Filesystem();
$filesystem->remove($filenameDir);
//Delete from json
if ($quoteItem->removeFile($filename)) {
$em = $this->getDoctrine()->getManager();
$em->persist($quoteItem);
$em->flush();
$this->addFlash('success', 'The file has been removed from the quote item');
}
} catch (\Exception $e) {
if (isset($quoteItem)) {
$this->addFlash('error', "The file couldn't be removed from the quote item");
} else {
$this->addFlash('error', $e->getMessage());
}
}
if ($quoteItem) {
return $this->redirectToRoute('my_quoteItem_edit', array('id' => $quoteItem->getId()));
}
return $this->redirectToRoute('all_quotes_index');
}
/**
* @Route("/addPolicyRow/{id}/{type}", name="add_policy_row", methods={"GET"})
* @Security("is_granted('ROLE_USER_EDIT_CUSTOMER_ACCOUNT')")
* @param Request $request
* @param QuoteItem|null $quoteItem
* @return Response
*/
public function addPolicyRow(Request $request, QuoteItem $quoteItem = null, $type): Response
{
if (null == $quoteItem) {
return $this->redirectToRoute('all_quotes_index');
}
if ($type == 'supplier') {
$supplierCancellationPolicies = $quoteItem->getCancellationPolicySupplier() ?? array();
if (null != $supplierCancellationPolicies && array_key_exists('penaltyDate', $supplierCancellationPolicies)) { //make it an array of 1
$tempCancellationPolicies = array($supplierCancellationPolicies);
$supplierCancellationPolicies = $tempCancellationPolicies;
}
if (count($supplierCancellationPolicies) > 0) {
//$newRow = array_fill_keys(array_keys($oxCancellationPolicies[0]),"");
$newRow = end($supplierCancellationPolicies);
} else {
$newRow = array("id" => "", "name" => "", "type" => "", "penalty" => "", "description" => "", "penaltyDate" => "");
}
$supplierCancellationPolicies[] = $newRow;
if (count($supplierCancellationPolicies) == 1) {
$supplierCancellationPolicies[] = $newRow; // add a second one
}
$quoteItem->setCancellationPolicySupplier($supplierCancellationPolicies);
}
$oxCancellationPolicies = $quoteItem->getCancellationPolicyOx() ?? array();
if (null != $oxCancellationPolicies && array_key_exists('penaltyDate', $oxCancellationPolicies)) { //make it an array of 1
$tempCancellationPolicies = array($oxCancellationPolicies);
$oxCancellationPolicies = $tempCancellationPolicies;
}
if (count($oxCancellationPolicies) > 0) {
//$newRow = array_fill_keys(array_keys($oxCancellationPolicies[0]),"");
$newRow = end($oxCancellationPolicies);
} else {
$newRow = array("id" => "", "name" => "", "type" => "", "penalty" => "", "description" => "", "penaltyDate" => "");
}
$oxCancellationPolicies[] = $newRow;
if (count($oxCancellationPolicies) == 1) {
$oxCancellationPolicies[] = $newRow; // add a second one
}
$quoteItem->setCancellationPolicyOx($oxCancellationPolicies);
$em = $this->getDoctrine()->getManager();
$em->persist($quoteItem);
$em->flush();
return $this->redirectToRoute('my_quoteItem_edit', array('id' => $quoteItem->getId()));
}
/**
* @Route("/setQcAgent/{id}/{qcAgent}", name="set_qc_agent", methods={"GET","POST"})
* @Security("is_granted('ROLE_USER_EDIT_CUSTOMER_ACCOUNT')")
* @param QuoteItem|null $quoteItem
* @param User|null $qcAgent
* @return Response
*/
public function SetQcAgent(EntityManagerInterface $em, QuoteItem $quoteItem = null, User $qcAgent = null): Response
{
if (isset($quoteItem)) {
$quoteItem->setAssignedQcAgent($qcAgent);
$em->persist($quoteItem);
$em->flush();
return new JsonResponse(array('success' => true));
} else {
return new JsonResponse(array('success' => false));
}
}
public function setOriginalCurrencyObj(&$request, &$quoteItem)
{
if ($request->request->get('displayInOriginalCurrency') != null) {
$quoteItem->setDisplayInOriginalCurrency($request->request->get('displayInOriginalCurrency') ?? false);
} elseif ($quoteItem->getDisplayInOriginalCurrency() == null) {
$quoteItem->setDisplayInOriginalCurrency(false);
}
$currencyShortName = $request->request->get('my_quote_item')['quoteItem']['originalCurrency'] ?? null;
if ($currencyShortName != null) {
$currencyObj = $this->getDoctrine()->getRepository(Currency::class)->findOneBy(['shortName' => $currencyShortName]);
$quoteItem->setOriginalCurrency($currencyObj);
$requestQuoteItem = $request->request->get('my_quote_item');
$requestQuoteItem['quoteItem']['originalCurrency'] = $currencyObj;
$request->request->set('my_quote_item', $requestQuoteItem);
}
}
private function ClearBadFiles(FormInterface &$form)
{
//If the form has an error on the attachFile, then removed to not show on the modal form.
if ($form->isSubmitted() && !$form->isValid()) {
/**
* @var FormErrorIterator $formErrors
* @var ConstraintViolation $cause
*/
$cause = $form->getErrors(true)->getChildren()->getCause();
if ($cause && method_exists($cause, "getPropertyPath")) {
if ($cause->getPropertyPath() == "children[attachFile].data") {
$form->get('attachFile')->clearErrors();
}
} elseif ($form->get('attachFile')->getErrors()) {
$form->get('attachFile')->clearErrors();
}
}
//END If the form has an error on the attachFile, then removed to not show on the modal form.
}
/**
* @Route("/changeQuote", name="quoteitem_change_quote", methods={"POST"})
*/
public function changeQuoteAction(Request $request, QuoteItemRepository $quoteItemRepository): Response
{
try {
$formSubmitted = false;
$em = $this->getDoctrine()->getManager();
if ($changeQuote = $request->get('changeQuote')) {
//Form sent
if (!$quoteItemId = $changeQuote['quoteItem']) {
throw new \Exception("Quote Item was not found");
}
if (!$quoteId = $changeQuote['quote']) {
throw new \Exception("Quote was not selected");
}
if (!$quote = $em->getRepository(Quote::class)->find($quoteId)) {
throw new \Exception("Quote selected was not found");
}
$formSubmitted = true;
} else {
//modal called first time
if (!$quoteItemId = $request->get('quoteItemId')) {
throw new \Exception("Quote Item was not found");
}
}
/**
* @var QuoteItem $quoteItem
*/
if (!$quoteItem = $em->getRepository(QuoteItem::class)->find($quoteItemId)) {
throw new \Exception("Quote Item was not found");
}
if (!$quoteItem->canQuoteBeChanged()) {
throw new \Exception("The quote cannot be changed for this quote item");
}
if ($formSubmitted) {
$quoteItem->setQuote($quote);
foreach ($quoteItem->getChildrenQuoteItems() as $childQuoteItem) {
$childQuoteItem->setQuote($quote);
$em->persist($childQuoteItem);
}
$em->persist($quoteItem);
$em->flush();
$this->addFlash('success', 'The Quote Item has been successfully moved to the quote selected');
return $this->redirectToRoute('all_quotes_index');
}
$quoteList = $em->getRepository(Quote::class)->findAllQuotesExcept($quoteItem->getQuote()->getId());
return $this->render('backOffice/quoteItem/_modalChangeQuoteContent.html.twig', [
'quoteItem' => $quoteItem,
'quoteList' => $quoteList
]);
} catch (\Exception $e) {
$this->addFlash('error', "The Quote Item couldn't be moved to the quote selected. Error: " . $e->getMessage());
return $this->redirectToRoute('all_quotes_index');
}
}
/**
* @Route("/paymentStatus/{id}", name="payment_status", methods={"GET","POST"})
* @Security("is_granted('ROLE_USER_EDIT_CUSTOMER_ACCOUNT')")
* @return Response
*/
public function getPaymentStatus(Request $request, QuoteItem $quoteItem, QuickbooksAPI $quickbooksAPI): Response
{
$payments = null;
try {
$payments = $quickbooksAPI->getPayment($quoteItem->getQuickbookPayableReferenceId());
$brian = $payments;
} catch (\Exception $e) {
$message = $e->getMessage();
return JsonResponse::fromJsonString($message);
}
return JsonResponse::fromJsonString('{"status": "ok"}');
}
}