<?php declare(strict_types=1);
namespace MasterFFL\Checkout\Subscriber;
use Shopware\Core\Checkout\Order\OrderEvents;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Psr\Log\LoggerInterface;
class CheckoutSubscriber implements EventSubscriberInterface
{
private EntityRepositoryInterface $orderRepository;
private RequestStack $requestStack;
private LoggerInterface $logger;
public function __construct(
EntityRepositoryInterface $orderRepository,
RequestStack $requestStack,
LoggerInterface $logger
) {
$this->orderRepository = $orderRepository;
$this->requestStack = $requestStack;
$this->logger = $logger;
}
public static function getSubscribedEvents(): array
{
return [
'checkout.order.placed' => 'onOrderPlaced',
OrderEvents::ORDER_WRITTEN_EVENT => 'onOrderWritten'
];
}
public function onOrderPlaced($event): void
{
try {
$request = $this->requestStack->getCurrentRequest();
if (!$request) {
$this->logger->warning('FFL: No request found in onOrderPlaced');
return;
}
$session = $request->getSession();
// Check for FFL dealer info in multiple session keys
$fflDealerInfo = $session->get('ffl_dealer_info');
$fflDealerAddress = $session->get('ffl_dealer_address');
$this->logger->info('FFL: Order placed, checking for FFL data', [
'ffl_dealer_info' => $fflDealerInfo ? 'Present' : 'Not found',
'ffl_dealer_address' => $fflDealerAddress ? 'Present' : 'Not found'
]);
if ($fflDealerInfo || $fflDealerAddress) {
$orderId = method_exists($event, 'getOrderId') ? $event->getOrderId() : $event->getOrder()->getId();
$dealerData = $fflDealerInfo ? ($fflDealerInfo['dealerData'] ?? $fflDealerInfo) : $fflDealerAddress;
$this->updateOrderWithFFLData($orderId, $dealerData, $event->getContext());
// Keep FFL data in session for order confirmation page
$session->set('order_ffl_dealer', $dealerData);
$this->logger->info('FFL: Order updated with FFL data', [
'orderId' => $orderId,
'dealerId' => $dealerData['dealerId'] ?? 'unknown'
]);
} else {
$this->logger->info('FFL: No FFL data found for order');
}
} catch (\Exception $e) {
$this->logger->error('FFL: Error processing FFL order on placement', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
}
}
public function onOrderWritten(EntityWrittenEvent $event): void
{
try {
$request = $this->requestStack->getCurrentRequest();
if (!$request) return;
$session = $request->getSession();
$fflData = $session->get('ffl_dealer_info') ?: $session->get('ffl_dealer_address');
if (!$fflData) return;
foreach ($event->getWriteResults() as $writeResult) {
$payload = $writeResult->getPayload();
if ($writeResult->getOperation() === 'insert') {
$orderId = $payload['id'];
$dealerData = is_array($fflData) && isset($fflData['dealerData']) ? $fflData['dealerData'] : $fflData;
$this->updateOrderWithFFLData($orderId, $dealerData, $event->getContext());
$this->logger->info('FFL: Order written event processed', [
'orderId' => $orderId
]);
}
}
} catch (\Exception $e) {
$this->logger->error('FFL: Error in onOrderWritten', [
'error' => $e->getMessage()
]);
}
}
private function updateOrderWithFFLData(string $orderId, array $fflData, $context): void
{
try {
$customFields = [
'is_ffl_order' => true,
'ffl_dealer_id' => $fflData['dealerId'] ?? '',
'ffl_dealer_name' => $fflData['firstName'] ?? $fflData['company'] ?? '',
'ffl_dealer_company' => $fflData['company'] ?? '',
'ffl_dealer_street' => $fflData['street'] ?? '',
'ffl_dealer_city' => $fflData['city'] ?? '',
'ffl_dealer_state' => $fflData['regionCode'] ?? '',
'ffl_dealer_zipcode' => $fflData['zipcode'] ?? '',
'ffl_dealer_phone' => $fflData['phoneNumber'] ?? $fflData['telephone'] ?? '',
'ffl_processing_date' => date('Y-m-d H:i:s')
];
$this->orderRepository->update([
[
'id' => $orderId,
'customFields' => $customFields
]
], $context);
$this->logger->info('FFL: Order custom fields updated', [
'orderId' => $orderId,
'dealerId' => $fflData['dealerId'] ?? 'unknown'
]);
} catch (\Exception $e) {
$this->logger->error('FFL: Error updating order with FFL data', [
'orderId' => $orderId,
'error' => $e->getMessage()
]);
}
}
}