<?php declare(strict_types=1);
namespace MasterFFL\Checkout\Subscriber;
use Shopware\Core\Checkout\Cart\Event\CheckoutOrderPlacedEvent;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Psr\Log\LoggerInterface;
class DeleteFflAddressSubscriber implements EventSubscriberInterface
{
public function __construct(
private readonly EntityRepository $customerAddressRepository,
private readonly EntityRepository $customerRepository,
private readonly LoggerInterface $logger
) {}
public static function getSubscribedEvents(): array
{
return [CheckoutOrderPlacedEvent::class => 'onCheckoutOrderPlaced'];
}
public function onCheckoutOrderPlaced(CheckoutOrderPlacedEvent $event): void
{
$order = $event->getOrder();
$context = $event->getContext();
$customerId = $order->getOrderCustomer()?->getCustomerId();
// Get shipping address
$shippingAddress = $order->getDeliveries()->first()?->getShippingOrderAddress();
if (!$shippingAddress) {
$this->logger->info('[FFL] No shipping address found in order');
return;
}
// Check if this is an FFL address - FIXED LOGIC
$customFields = $shippingAddress->getCustomFields() ?? [];
$isFflAddress = $customFields['is_ffl_address'] ?? false;
// Log for debugging
$this->logger->info('[FFL] Order placed - checking address type', [
'order_id' => $order->getId(),
'custom_fields' => $customFields,
'is_ffl_address' => $isFflAddress
]);
// If NOT an FFL address, skip processing
if (!$isFflAddress || $isFflAddress !== true) {
$this->logger->info('[FFL] Not an FFL address, skipping cleanup', [
'order_id' => $order->getId(),
'is_ffl_address' => $isFflAddress
]);
return;
}
if ($customerId === null) {
$this->logger->warning('[FFL] No customer ID found in order');
return;
}
$this->processFflAddressCleanup($customerId, $order->getId(), $context);
}
private function processFflAddressCleanup(string $customerId, string $orderId, $context): void
{
try {
// Get all customer addresses
$addresses = $this->customerAddressRepository->search(
(new Criteria())->addFilter(new EqualsFilter('customerId', $customerId)),
$context
)->getEntities();
$fflAddressIds = [];
$regularAddressIds = [];
// Separate FFL and regular addresses
foreach ($addresses as $address) {
$customFields = $address->getCustomFields() ?? [];
$isFflAddress = $customFields['is_ffl_address'] ?? false;
if ($isFflAddress === true || $isFflAddress === 1 || $isFflAddress === '1') {
$fflAddressIds[] = $address->getId();
} else {
$regularAddressIds[] = $address->getId();
}
}
$this->logger->info('[FFL] Address analysis', [
'customer_id' => $customerId,
'order_id' => $orderId,
'ffl_addresses' => count($fflAddressIds),
'regular_addresses' => count($regularAddressIds)
]);
// If no FFL addresses to clean up, return
if (empty($fflAddressIds)) {
$this->logger->info('[FFL] No FFL addresses found to cleanup');
return;
}
// If customer has regular addresses, delete FFL addresses and set new default
if (!empty($regularAddressIds)) {
$this->safeDeleteFflAddresses($fflAddressIds, $regularAddressIds[0], $customerId, $context);
$this->logger->info('[FFL] FFL addresses cleaned up successfully', [
'customer_id' => $customerId,
'order_id' => $orderId,
'deleted_ffl_addresses' => $fflAddressIds,
'new_default_address' => $regularAddressIds[0]
]);
} else {
// Customer only has FFL addresses - keep one and mark it as regular
$this->convertFflAddressToRegular($fflAddressIds[0], $context);
$this->logger->warning('[FFL] Customer only had FFL addresses, converted one to regular', [
'customer_id' => $customerId,
'order_id' => $orderId,
'converted_address' => $fflAddressIds[0]
]);
}
} catch (\Exception $e) {
$this->logger->error('[FFL] Error during FFL address cleanup', [
'customer_id' => $customerId,
'order_id' => $orderId,
'error' => $e->getMessage()
]);
}
}
private function safeDeleteFflAddresses(array $fflAddressIds, string $newDefaultId, string $customerId, $context): void
{
// Update customer default addresses first
$this->customerRepository->update([[
'id' => $customerId,
'defaultShippingAddressId' => $newDefaultId,
'defaultBillingAddressId' => $newDefaultId,
]], $context);
// Delete FFL addresses
$payload = array_map(fn ($id) => ['id' => $id], $fflAddressIds);
$this->customerAddressRepository->delete($payload, $context);
}
private function convertFflAddressToRegular(string $addressId, $context): void
{
// Remove FFL flag from address
$this->customerAddressRepository->update([[
'id' => $addressId,
'customFields' => [
'is_ffl_address' => false,
'converted_from_ffl' => true,
'converted_at' => date('Y-m-d H:i:s')
]
]], $context);
}
}