<?php declare(strict_types=1);
namespace WebkulBookingReservation\Subscriber;
use Shopware\Core\Checkout\Order\OrderEvents;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Content\Product\ProductEvents;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use DateTime;
use DateTimeZone;
use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
use Shopware\Core\Defaults;
use Shopware\Core\Framework\Uuid\Uuid;
use Shopware\Storefront\Page\Account\Order\AccountOrderPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Finish\CheckoutFinishPageLoadedEvent;
use WebkulBookingReservation\Service\BookingReservationService;
use Shopware\Storefront\Page\Checkout\Offcanvas\OffcanvasCartPageLoadedEvent;
use Symfony\Component\HttpFoundation\Session\Session;
use Shopware\Core\Content\Product\Events\ProductSearchResultEvent;
use Shopware\Storefront\Page\Account\Order\AccountEditOrderPageLoadedEvent;
class BookingSubscriber implements EventSubscriberInterface
{
/**
* @var EntityRepositoryInterface
*/
protected $oneBookingRepository;
/**
* @var EntityRepositoryInterface
*/
protected $manyBookingRepository;
/**
* @var EntityRepositoryInterface
*/
protected $oneBookingSlotRepository;
/**
* @var SystemConfigService
*/
protected $systemConfigService;
/**
* @var EntityRepositoryInterface
*/
protected $orderCustomerRepository;
/**
* @var EntityRepositoryInterface
*/
protected $orderLineItemRepository;
/**
* @var BookingReservationService
*/
protected $bookingReservationService;
/**
* @var EntityRepositoryInterface
*/
protected $bookingOrderProductRepository;
/**
* @var EntityRepositoryInterface
*/
protected $tempCartRepository;
/**
* @var EntityRepositoryInterface
*/
protected $bookingOrderRepository;
public function __construct(
EntityRepositoryInterface $oneBookingRepository,
EntityRepositoryInterface $manyBookingRepository,
EntityRepositoryInterface $oneBookingSlotRepository,
SystemConfigService $systemConfigService,
EntityRepositoryInterface $orderCustomerRepository,
EntityRepositoryInterface $orderLineItemRepository,
BookingReservationService $bookingReservationService,
EntityRepositoryInterface $bookingOrderProductRepository,
EntityRepositoryInterface $tempCartRepository,
EntityRepositoryInterface $bookingOrderRepository
)
{
$this->oneBookingRepository = $oneBookingRepository;
$this->manyBookingRepository = $manyBookingRepository;
$this->oneBookingSlotRepository = $oneBookingSlotRepository;
$this->systemConfigService = $systemConfigService;
$this->orderCustomerRepository = $orderCustomerRepository;
$this->orderLineItemRepository = $orderLineItemRepository;
$this->bookingReservationService = $bookingReservationService;
$this->bookingOrderProductRepository = $bookingOrderProductRepository;
$this->tempCartRepository = $tempCartRepository;
$this->bookingOrderRepository = $bookingOrderRepository;
}
public static function getSubscribedEvents(): array
{
return [
ProductPageLoadedEvent::class => 'updateProductPage',
OrderEvents::ORDER_WRITTEN_EVENT => 'orderBooking',
OffcanvasCartPageLoadedEvent::class => 'updateOffCanvasCart',
CheckoutCartPageLoadedEvent::class => 'updateCheckoutCart',
CheckoutConfirmPageLoadedEvent::class => 'updateCheckoutConfrim',
ProductListingResultEvent::class => 'updateCms',
CheckoutFinishPageLoadedEvent::class => 'updateCheckoutFinish',
AccountOrderPageLoadedEvent::class => 'updateAccountOrder',
ProductSearchResultEvent::class => 'updateSearchResult',
AccountEditOrderPageLoadedEvent::class => 'updateEditOrder'
];
}
public function updateEditOrder(AccountEditOrderPageLoadedEvent $event) {
$products = $event->getPage()->getOrder()->getLineItems()->getElements();
$customerId = $event->getSalesChannelContext()->getCustomer()->getId();
foreach($products as $product) {
$productId = $product->getProductId();
$orderId = $product->getOrderId();
$productId = $product->getProductId();
$orderProducts = $this->bookingReservationService->getOrderProductDetail($productId, $customerId, $orderId);
if ($orderProducts) {
$cartUpdate = [];
foreach($orderProducts as $orderProduct) {
$cartUpdate [] = [
'bookingFrom' => $orderProduct->getStartDay()->format('Y-m-d H:i'),
'bookingTill' => $orderProduct->getEndDay()->format('Y-m-d H:i'),
'quantity' => $orderProduct->getQuantity(),
'id' => $orderProduct->getId(),
'edit' => true
];
}
$product->setExtensions([
'booking' => $cartUpdate
]);
}
}
}
public function updateSearchResult(ProductSearchResultEvent $event)
{
$products = $event->getResult()->getElements();
$showPrice = 'No';
foreach($products as $product) {
$productId = $product->getId();
$oneBooking = $this->bookingReservationService->getOneBookingByProductId($productId);
$manybooking = $this->bookingReservationService->getManyBookingByProductId($productId);
if ($oneBooking || $manybooking) {
$product->setExtensions([
'booking' => "Yes"
]);
}
}
}
public function updateAccountOrder(AccountOrderPageLoadedEvent $event) {
$orders = $event->getPage()->getOrders()->getElements();
foreach($orders as $order) {
$customerId = $order->getOrderCustomer()->getCustomerId();
$products = $order->getLineItems()->getElements();
foreach($products as $product) {
$orderId = $product->getOrderId();
$productId = $product->getProductId();
$orderProducts = $this->bookingReservationService->getOrderProductDetail($productId, $customerId, $orderId);
if ($orderProducts) {
$cartUpdate = [];
foreach($orderProducts as $orderProduct) {
$cartUpdate [] = [
'bookingFrom' => $orderProduct->getStartDay()->format('Y-m-d H:i'),
'bookingTill' => $orderProduct->getEndDay()->format('Y-m-d H:i'),
'quantity' => $orderProduct->getQuantity(),
'id' => $orderProduct->getId()
];
}
$product->setExtensions([
'booking' => $cartUpdate
]);
}
}
}
}
public function updateCheckoutFinish(CheckoutFinishPageLoadedEvent $event) {
$products = $event->getPage()->getOrder()->getLineItems()->getElements();
$customerId = $event->getPage()->getOrder()->getOrderCustomer()->getCustomerId();
foreach($products as $product) {
$productId = $product->getProductId();
$orderId = $product->getOrderId();
$orderProducts = $this->bookingReservationService->getOrderProductDetail($productId, $customerId, $orderId);
if ($orderProducts) {
$cartUpdate = [];
foreach($orderProducts as $orderProduct) {
$cartUpdate [] = [
'bookingFrom' => $orderProduct->getStartDay()->format('Y-m-d H:i'),
'bookingTill' => $orderProduct->getEndDay()->format('Y-m-d H:i'),
'quantity' => $orderProduct->getQuantity(),
'id' => $orderProduct->getId()
];
}
$product->setExtensions([
'booking' => $cartUpdate
]);
}
}
}
public function updateCms(ProductListingResultEvent $event) {
$products = $event->getResult()->getElements();
$showPrice = 'No';
foreach($products as $product) {
$productId = $product->getId();
$oneBooking = $this->bookingReservationService->getOneBookingByProductId($productId);
$manybooking = $this->bookingReservationService->getManyBookingByProductId($productId);
if ($oneBooking || $manybooking) {
$product->setExtensions([
'booking' => "Yes"
]);
}
}
}
public function updateCheckoutConfrim(CheckoutConfirmPageLoadedEvent $event)
{
$products = $event->getPage()->getCart()->getLineItems()->getElements();
$customerId = $event->getSalesChannelContext()->getCustomer()->getId();
$count = 0;
$item = 0;
foreach($products as $product) {
$productId = $product->getId();
$oneBooking = $this->bookingReservationService->getOneBookingByProductId($productId);
$manybooking = $this->bookingReservationService->getManyBookingByProductId($productId);
if ($oneBooking || $manybooking) {
$count++;
$tempCartDetails = $this->bookingReservationService->getTempCart($productId, $customerId, $event->getSalesChannelContext());
$cartUpdate = [];
foreach($tempCartDetails as $tempCartDetail) {
$cartUpdate [] = [
'bookingFrom' => $tempCartDetail->getBookingFrom(),
'bookingTill' => $tempCartDetail->getBookingTill(),
'quantity' => $tempCartDetail->getQuantity(),
'id' => $tempCartDetail->getId(),
'edit' => false
];
}
$product->setExtensions([
'booking' => $cartUpdate
]);
$item = $item + count($tempCartDetails);
}
}
}
public function updateCheckoutCart(CheckoutCartPageLoadedEvent $event) {
$products = $event->getPage()->getCart()->getLineItems()->getElements();
$cartToken = $event->getPage()->getCart()->getToken();
$customerId = $event->getSalesChannelContext()->getCustomer()? $event->getSalesChannelContext()->getCustomer()->getId() : null;
$count = 0;
$item = 0;
if ($customerId) {
foreach($products as $product) {
$productId = $product->getId();
$oneBooking = $this->bookingReservationService->getOneBookingByProductId($productId);
$manybooking = $this->bookingReservationService->getManyBookingByProductId($productId);
$cartUpdate = [];
if ($oneBooking || $manybooking) {
$count++;
$tempCartDetails = $this->bookingReservationService->getTempCart($productId, $customerId, $event->getSalesChannelContext());
foreach($tempCartDetails as $tempCartDetail) {
$cartUpdate [] = [
'bookingFrom' => $tempCartDetail->getBookingFrom(),
'bookingTill' => $tempCartDetail->getBookingTill(),
'quantity' => $tempCartDetail->getQuantity(),
'id' => $tempCartDetail->getId()
];
}
$product->setExtensions([
'booking' => $cartUpdate
]);
$item = $item + count($tempCartDetails);
}
}
}
}
public function updateOffCanvasCart(OffcanvasCartPageLoadedEvent $event)
{
$products = $event->getPage()->getCart()->getLineItems()->getElements();
$cartToken = $event->getPage()->getCart()->getToken();
if ($event->getSalesChannelContext()->getCustomer()) {
$customerId = $event->getSalesChannelContext()->getCustomer()->getId();
}
$count = 0;
$item = 0;
foreach($products as $product) {
$productId = $product->getId();
$oneBooking = $this->bookingReservationService->getOneBookingByProductId($productId);
$manybooking = $this->bookingReservationService->getManyBookingByProductId($productId);
$cartUpdate = [];
if ($oneBooking || $manybooking) {
$count++;
$tempCartDetails = $this->bookingReservationService->getTempCart($productId, $customerId, $event->getSalesChannelContext());
foreach($tempCartDetails as $tempCartDetail) {
$cartUpdate [] = [
'bookingFrom' => $tempCartDetail->getBookingFrom(),
'bookingTill' => $tempCartDetail->getBookingTill(),
'quantity' => $tempCartDetail->getQuantity(),
'id' => $tempCartDetail->getId()
];
}
$product->setExtensions([
'booking' => $cartUpdate
]);
$item = $item + count($tempCartDetails);
}
}
$totalLineItems = count($products);
$item = $item + ($totalLineItems - $count);
$event->getPage()->setExtensions([
'item' => $item
]);
}
public function updateProductPage(ProductPageLoadedEvent $event)
{
$config = $this->systemConfigService->get('WebkulBR')['config'];
$productId = $event->getPage()->getProduct()->getId();
// if ($event->getPage()->getProduct()->getParentId()) {
// $productId = $event->getPage()->getProduct()->getParentId();
// } else {
// }
if ($productId) {
$oneBooking = $this->oneBookingRepository->search(
(new Criteria())
->addFilter(new EqualsFilter('productId', $productId))
->addFilter(new EqualsFilter('status', true))
->addAssociation('slot'),
Context::createDefaultContext()
)->first();
$manybooking = $this->manyBookingRepository->search(
(new Criteria())
->addFilter(new EqualsFilter('productId', $productId))
->addFilter(new EqualsFilter('status', true)),
Context::createDefaultContext()
)->first();
if ($oneBooking) {
$dateFrom= $oneBooking->getDateFrom();
$dateFrom = $dateFrom->format(Defaults::STORAGE_DATE_TIME_FORMAT);
$dateFrom = new DateTime($dateFrom, new DateTimeZone('UTC'));
$dateFrom->setTimezone(new DateTimeZone($config['timeZone']));
$dateFrom = $dateFrom->format('Y-m-d');
$dateTo = $oneBooking->getDateTo();
$dateTo = $dateTo->format(Defaults::STORAGE_DATE_TIME_FORMAT);
$dateTo = new DateTime($dateTo, new DateTimeZone('UTC'));
$dateTo->setTimezone(new DateTimeZone($config['timeZone']));
$dateTo = $dateTo->format('Y-m-d');
$sundayStatus = false;
$mondayStatus = false;
$tuesdayStatus = false;
$wednesdayStatus = false;
$thursdayStatus = false;
$fridayStatus = false;
$saturdayStatus = false;
if ($oneBooking->getSlot()->getElements()) {
foreach($oneBooking->getSlot()->getElements() as $slot) {
switch ($slot->getStartDay()) {
case "Sunday":
$sundayStatus = true;
break;
case "Monday":
$mondayStatus = true;
break;
case "Tuesday":
$tuesdayStatus = true;
break;
case "Wednesday":
$wednesdayStatus = true;
break;
case "Thursday":
$thursdayStatus = true;
break;
case "Friday":
$fridayStatus = true;
break;
case "Saturday":
$saturdayStatus = true;
break;
}
}
}
$event->getPage()->setExtensions([
'booking' => 'oneBooking',
'productId' => $oneBooking->getProductId(),
'dateFrom' => $dateFrom,
'dateTo' => $dateTo,
'sundayStatus' => $sundayStatus,
'mondayStatus' => $mondayStatus,
'tuesdayStatus' => $tuesdayStatus,
'wednesdayStatus' => $wednesdayStatus,
'thursdayStatus' => $thursdayStatus,
'fridayStatus' => $fridayStatus,
'saturdayStatus' => $saturdayStatus
]);
} else if ($manybooking) {
$dateFrom= $manybooking->getDateFrom();
$dateFrom = $dateFrom->format(Defaults::STORAGE_DATE_TIME_FORMAT);
$dateFrom = new DateTime($dateFrom, new DateTimeZone('UTC'));
$dateFrom->setTimezone(new DateTimeZone($config['timeZone']));
$dateFrom = $dateFrom->format('Y-m-d');
$dateTo = $manybooking->getDateTo();
$dateTo = $dateTo->format(Defaults::STORAGE_DATE_TIME_FORMAT);
$dateTo = new DateTime($dateTo, new DateTimeZone('UTC'));
$dateTo->setTimezone(new DateTimeZone($config['timeZone']));
$dateTo = $dateTo->format('Y-m-d');
$event->getPage()->setExtensions([
'booking' => 'manyBooking',
'productId' => $manybooking->getProductId(),
'dateFrom' => $dateFrom,
'dateTo' => $dateTo,
'sundayStatus' => $manybooking->getSundayStatus(),
'mondayStatus' => $manybooking->getMondayStatus(),
'tuesdayStatus' => $manybooking->getTuesdayStatus(),
'wednesdayStatus' => $manybooking->getWednesdayStatus(),
'thursdayStatus' => $manybooking->getThursdayStatus(),
'fridayStatus' => $manybooking->getFridayStatus(),
'saturdayStatus' => $manybooking->getSaturdayStatus()
]);
}
}
}
public function orderBooking(EntityWrittenEvent $event)
{
$session = new Session();
$results = $event->getWriteResults();
$manybooking = null;
$oneBooking = null;
foreach($results as $key => $result) {
if ($result->getOperation() == 'insert') {
$orderId = $result->getPrimaryKey();
$payload = $result->getPayload();
if ($payload) {
$count = 0;
$orderCustomer = $this->orderCustomerRepository->search(
(new Criteria())
->addFilter(new EqualsFilter('orderId', $orderId)),
Context::createDefaultContext()
)->first();
$customerId = $orderCustomer->getCustomerId();
if ($session->has($customerId)) {
$token = $session->get($customerId);
}
$orderLineItems = $this->orderLineItemRepository->search(
(new Criteria())
->addFilter(new EqualsFilter('orderId', $orderId))
->addAssociation('product'),
Context::createDefaultContext()
)->getEntities()->getElements();
foreach($orderLineItems as $orderLineItem) {
$productId = $orderLineItem->getIdentifier();
$oneBooking = $this->bookingReservationService->getOneBookingByProductId($productId);
$manybooking = $this->bookingReservationService->getManyBookingByProductId($productId);
if ($oneBooking) {
$bookType = 2;
} else if ($manybooking) {
$bookType = 1;
}
if ($oneBooking || $manybooking) {
$tempCartDetails = $this->tempCartRepository->search(
(new Criteria())
->addFilter(new EqualsFilter('productId', $productId))
->addFilter(new EqualsFilter('customerId', $customerId))
->addFilter(new EqualsFilter('cartToken', $token))
->addAssociation('product')
->addAssociation('customer'),
Context::createDefaultContext()
)->getElements();
if ($tempCartDetails) {
foreach($tempCartDetails as $key => $tempCartDetail) {
$count++;
$startDay = new DateTime($tempCartDetail->getBookingFrom());
$endDay = new DateTime($tempCartDetail->getBookingTill());
$status = false;
if ($bookType == 2 || $bookType == 1) {
$bookingOrder = [
'id' => Uuid::randomHex(),
'productId' => $productId,
'orderId' => $orderId,
'customerId' => $customerId,
'quantity' => $tempCartDetail->getQuantity(),
'bookType' => $bookType,
'startDay' => $startDay,
'endDay' => $endDay,
'status' => $status,
'approvedDate' => new DateTime(date('Y-m-d'))
];
$this->bookingOrderProductRepository->create(
[$bookingOrder],
Context::createDefaultContext()
);
}
$this->tempCartRepository->delete([['id' => $tempCartDetail->getId()]], Context::createDefaultContext());
}
}
}
}
if ($manybooking || $oneBooking) {
$order = [
'id' => Uuid::randomHex(),
'orderId' => $orderId,
'customerId' => $customerId,
'noOfProduct' => $count
];
$this->bookingOrderRepository->create([$order], Context::createDefaultContext());
$this->bookingReservationService->bookingMail($orderId);
$session->remove($customerId);
}
}
}
}
}
}