<?php
/**
* Created by Elements.at New Media Solutions GmbH
*
*/
namespace App\EventListener;
use App\Marketplace\MarketplaceClient;
use App\Model\BookingApi\Order;
use App\Service\Shop\ShopService;
use App\Service\SiteConfigService;
use Carbon\Carbon;
use Elements\Bundle\TicketShopFrameworkBundle\Service\VoucherCodeService;
use GuzzleHttp\Exception\RequestException;
use Pimcore\Event\Model\DataObjectEvent;
use Pimcore\Log\ApplicationLogger;
use Pimcore\Model\DataObject\Objectbrick\Data\OrderCustomizedMarketplace;
use Pimcore\Model\DataObject\OnlineShopOrder;
use Pimcore\Model\DataObject\OnlineShopOrderItem;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Routing\RouterInterface;
class DataObjectListener
{
public function __construct(protected LoggerInterface $bookingapiLogger,
protected VoucherCodeService $voucherCodeService,
protected ShopService $shopService,
protected SiteConfigService $siteConfigService,
protected MarketplaceClient $marketplaceClient,
protected RouterInterface $router,
protected ApplicationLogger $applicationLogger,
private ParameterBagInterface $params)
{
}
public function onPostUpdate(DataObjectEvent $e): void
{
if ($e->getArguments() && isset($e->getArguments()['saveVersionOnly']) && $e->getArguments()['saveVersionOnly'] == true) {
//do nothing for drafts
return;
}
$object = $e->getObject();
if ($object instanceof OnlineShopOrder && $object->getTenant() == 'marketplace') {
//transfer complete orders to marketplace endpoint
$bookingApiOrder = new Order();
/** @phpstan-ignore-next-line */
$bookingApiOrder->setDataFromOnlineShopOrder($object, $this->voucherCodeService, $this->shopService, $this->siteConfigService, $this->router);
$orderCustomizedBrick = $object->getCustomized() && $object->getCustomized()->getOrderCustomizedMarketplace() ? $object->getCustomized()->getOrderCustomizedMarketplace() : new OrderCustomizedMarketplace($object);
if ($this->orderNeedsTransmission($object)) {
$this->transmitOrder($orderCustomizedBrick, $bookingApiOrder, $object);
}
} elseif ($object instanceof OnlineShopOrderItem
&& $object->getParent() instanceof OnlineShopOrder
&& $object->getParent()->getTenant() == 'marketplace'
&& $object->getProduct() instanceof \Pimcore\Model\DataObject\TicketProduct
&& $object->getCustomized()->getOrderItemCustomizedSkidata()
&& $object->getCustomized()->getOrderItemCustomizedSkidata()->getOrderItemUuid()) {
//in skidata ticket transmit, the order items seems to be save after the order. This is why we need this additional check on the order item
/**
* @var OnlineShopOrder $order
*/
$order = $object->getParent();
if($this->orderNeedsTransmission($order)) {
$bookingApiOrder = new Order();
/** @phpstan-ignore-next-line */
$bookingApiOrder->setDataFromOnlineShopOrder($order, $this->voucherCodeService, $this->shopService, $this->siteConfigService, $this->router);
$orderCustomizedBrick = $order->getCustomized() && $order->getCustomized()->getOrderCustomizedMarketplace() ? $order->getCustomized()->getOrderCustomizedMarketplace() : new OrderCustomizedMarketplace($order);
$this->transmitOrder($orderCustomizedBrick, $bookingApiOrder, $order);
}
}
}
protected function orderNeedsTransmission(OnlineShopOrder $order): bool
{
$bookingApiOrder = new Order();
/** @phpstan-ignore-next-line */
$bookingApiOrder->setDataFromOnlineShopOrder($order, $this->voucherCodeService, $this->shopService, $this->siteConfigService, $this->router);
$orderCustomizedBrick = $order->getCustomized() && $order->getCustomized()->getOrderCustomizedMarketplace() ? $order->getCustomized()->getOrderCustomizedMarketplace() : new OrderCustomizedMarketplace($order);
$needsTransmission = false;
if ($bookingApiOrder->getOrderFinished()) {
if ($order->getOrderState() == $order::ORDER_STATE_COMMITTED && !$orderCustomizedBrick->getTransmitted()) {
//new committed order not yet transmitted
$needsTransmission = true;
} elseif ($order->getOrderState() == $order::ORDER_STATE_CANCELLED
&& !$orderCustomizedBrick->getCancellationTransmissionPending()
&& !$orderCustomizedBrick->getTransmittedCancellation()) {
//transmit cancellation
$needsTransmission = true;
}
}
return $needsTransmission;
}
/**
* @param OrderCustomizedMarketplace|null $orderCustomizedBrick
* @param Order $bookingApiOrder
* @param OnlineShopOrder $object
*
* @return void
*/
public function transmitOrder(?OrderCustomizedMarketplace $orderCustomizedBrick, Order $bookingApiOrder, OnlineShopOrder $object): void
{
$orderCustomizedBrick->setLastTransmittedDate(Carbon::now());
$log = $orderCustomizedBrick->getTransmissionLog();
$success = false;
try {
$log .= "\r\n";
$log .= $this->params->get('marketplace_orderpush_endpoint');
$log .= "\r\n";
try {
$response = $this->marketplaceClient->pushOrderUpdate($bookingApiOrder);
$statusCode = $response->getStatusCode();
$bodyContent = $response->getBody()->getContents();
if ($statusCode == 200) {
$responseData = json_decode($bodyContent);
if (isset($responseData->ok) && $responseData->ok == true) {
$success = true;
$orderCustomizedBrick->setTransmitted(true);
if ($object->getOrderState() == $object::ORDER_STATE_CANCELLED) {
$orderCustomizedBrick->setTransmittedCancellation(true);
}
}
}
$log .= $statusCode . "\r\n";
$log .= $bodyContent . "\r\n";
$log .= "######### REQUEST CONTENT ##########\r\n";
$log .= '{"order": ' . json_encode($bookingApiOrder->jsonSerialize()) . '}';
} catch (RequestException $exception) {
$body = $exception->getRequest()->getBody();
$body->rewind();
$log .= $exception->getMessage();
$log .= "######### REQUEST CONTENT ##########\r\n";
$log .= $body->getContents();
}
} catch (\Throwable $throwable) {
$log .= "\r\n";
$log .= $throwable->getMessage();
}
$orderCustomizedBrick->setTransmissionLog($log);
$this->bookingapiLogger->info($log);
if (!$success) {
$this->applicationLogger->error('please check order Id' . $object->getId() . ' transmission of order data to markeplace endpoint failed');
}
try {
$object->getCustomized()->setOrderCustomizedMarketplace($orderCustomizedBrick);
$object->save();
} catch (\Throwable $throwable) {
$this->bookingapiLogger->emergency('Could not save order id after transmission to marketplace' . $object->getId());
}
}
}