<?php
declare(strict_types=1);
/*
* (c) shopware AG <info@shopware.com>
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Swag\AmazonPay\DataAbstractionLayer\EventListeners;
use Psr\Log\LoggerInterface;
use Shopware\Core\Checkout\Order\OrderEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\System\StateMachine\Aggregation\StateMachineState\StateMachineStateEntity;
use Shopware\Core\System\StateMachine\Event\StateMachineStateChangeEvent;
use Swag\AmazonPay\Components\Client\Service\ChargeServiceInterface;
use Swag\AmazonPay\Components\Config\ConfigServiceInterface;
use Swag\AmazonPay\Components\Config\Struct\AmazonPayConfigStruct;
use Swag\AmazonPay\Installer\CustomFieldsInstaller;
class AmazonPayTransitionListener
{
/**
* @var EntityRepositoryInterface
*/
private $orderRepository;
/**
* @var ChargeServiceInterface
*/
private $chargeService;
/**
* @var ConfigServiceInterface
*/
private $configService;
/**
* @var LoggerInterface
*/
private $logger;
public function __construct(
EntityRepositoryInterface $orderRepository,
ChargeServiceInterface $chargeService,
ConfigServiceInterface $configService,
LoggerInterface $logger
) {
$this->orderRepository = $orderRepository;
$this->chargeService = $chargeService;
$this->configService = $configService;
$this->logger = $logger;
}
public function onOrderStateChange(StateMachineStateChangeEvent $event): void
{
try {
$orderId = $event->getTransition()->getEntityId();
$order = $this->getOrderById($orderId, $event->getContext());
if (!$order) {
return;
}
$this->chargeOnOrderStateChange($order, $event->getNextState(), $event->getContext());
} catch (\Throwable $exception) {
$this->logger->error('An error occurred while charging on order state change', ['Exception' => $exception->getMessage()]);
}
}
private function getOrderById(string $orderId, Context $context): ?OrderEntity
{
$criteria = new Criteria([$orderId]);
$criteria->addAssociation('transactions');
$criteria->addAssociation('currency');
return $this->orderRepository->search(
$criteria,
$context
)->first();
}
private function chargeOnOrderStateChange(OrderEntity $order, StateMachineStateEntity $state, Context $context): void
{
$pluginConfig = $this->configService->getPluginConfig($order->getSalesChannelId());
$transactions = $order->getTransactions();
if ($pluginConfig->getChargeMode() !== AmazonPayConfigStruct::CHARGE_MODE_SHIPPING) {
return;
}
if ($transactions === null) {
return;
}
$transaction = $transactions->first();
if ($transaction === null) {
return;
}
$customFields = $transaction->getCustomFields();
if (empty($customFields) || empty($customFields[CustomFieldsInstaller::CUSTOM_FIELD_NAME_CHARGE_ID])) {
return;
}
$chargeId = $customFields[CustomFieldsInstaller::CUSTOM_FIELD_NAME_CHARGE_ID];
if ($state->getId() !== $pluginConfig->getOrderChargeTriggerState()) {
return;
}
$softDescriptor = $this->configService->getSoftDescriptor($order->getSalesChannelId());
$currency = $order->getCurrency();
$currencyCode = $currency ? $currency->getIsoCode() : null;
$this->chargeService->charge(
$chargeId,
$order->getAmountTotal(),
$softDescriptor,
$currencyCode,
$context
);
}
}