<?php declare(strict_types=1);
namespace CodevisionMiraklConnector\Subscriber;
use CodevisionMiraklConnector\CodevisionMiraklConnector;
use CodevisionMiraklConnector\Enum\Shopware\SalesChannel;
use CodevisionMiraklConnector\Event\MiraklProductExportInspectEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Webmozart\Assert\Assert;
use Webmozart\Assert\InvalidArgumentException;
class MiraklOfferExportEventsSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
MiraklProductExportInspectEvent::NAME => 'onOfferExport',
];
}
public function onOfferExport(MiraklProductExportInspectEvent $event): MiraklProductExportInspectEvent
{
$customFields = $event->getProductExportEntity()->getSalesChannel()->getCustomFields();
if ($customFields === null) {
return $event;
}
if (array_key_exists('codevisionMiraklConnectorChannel_type', $customFields) === false) {
return $event;
}
if ($customFields['codevisionMiraklConnectorChannel_type'] !== SalesChannel::OFFER_SELECT_TYPE()->getValue()) {
return $event;
}
$event->setIncludeInExport(true);
try {
$customFields = $event->getProductEntity()->getCustomFields();
if ($customFields === null) {
return $event;
}
/**
* Feature 2023-01-06: We do not want to disable offer export if products aren't synchronized
* they could have been synchronized outside of shopware already
*
* Assert::keyExists($customFields, 'codevisionMiraklConnectorProduct_syncDate');
*
* $lastImportErrorMessage = $customFields['codevisionMiraklConnectorProduct_errorMessage'] ?? '';
*
* Assert::length($lastImportErrorMessage, 0);
*/
if (array_key_exists('codevisionMiraklConnectorProduct_offerSyncDate', $customFields) === false) {
return $event;
}
$lastSyncDate = new \DateTimeImmutable($customFields['codevisionMiraklConnectorProduct_offerSyncDate']);
// 15 Minutes grace period
$minInterval = new \DateInterval('PT15M');
$gracePeriodTime = (new \DateTime())->sub($minInterval);
// we do not want to send the offer again within a 15 minute time frame
// only active in production mode
if (CodevisionMiraklConnector::DEBUG_MODE === false) {
Assert::greaterThan($gracePeriodTime, $lastSyncDate);
}
// this is neccessary as the update date can be slightly different than the lastSyncDate due to server
// performance reasons, thus we deduct a 30 second grace period which captures that
$minInterval = new \DateInterval('PT30S');
$graceUpdateTime = $event->getProductEntity()->getUpdatedAt()->sub($minInterval);
Assert::greaterThan($graceUpdateTime, $lastSyncDate);
} catch (InvalidArgumentException $exception) {
$event->setIncludeInExport(false);
}
return $event;
}
}