Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PISHPS-360: fix order expiration #845

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions src/Components/OrderExpiration/ExpireAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php
declare(strict_types=1);

namespace Kiener\MolliePayments\Components\OrderExpiration;

use Kiener\MolliePayments\Repository\Order\OrderRepositoryInterface;
use Kiener\MolliePayments\Repository\SalesChannel\SalesChannelRepositoryInterface;
use Kiener\MolliePayments\Service\Order\OrderExpireService;
use Kiener\MolliePayments\Service\SettingsService;
use Psr\Log\LoggerInterface;
use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionStates;
use Shopware\Core\Checkout\Order\OrderCollection;
use Shopware\Core\Defaults;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\RangeFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Shopware\Core\System\SalesChannel\SalesChannelEntity;

class ExpireAction
{
private OrderRepositoryInterface $orderRepository;
private SalesChannelRepositoryInterface $salesChannelRepository;
private OrderExpireService $orderExpireService;
private SettingsService $settingsService;
private LoggerInterface $logger;

public function __construct(
OrderRepositoryInterface $orderRepository,
SalesChannelRepositoryInterface $salesChannelRepository,
OrderExpireService $orderExpireService,
SettingsService $settingsService,
LoggerInterface $logger
) {
$this->orderRepository = $orderRepository;
$this->salesChannelRepository = $salesChannelRepository;
$this->orderExpireService = $orderExpireService;
$this->settingsService = $settingsService;
$this->logger = $logger;
}

public function expireOrders(Context $context): void
{
$this->logger->debug('Start resetting in_progress orders');

$salesChannelsCriteria = new Criteria();
$salesChannelsCriteria->addFilter(new EqualsFilter('active', true));

$salesChannels = $this->salesChannelRepository->search($salesChannelsCriteria, $context);

if ($salesChannels->count() === 0) {
$this->logger->debug('No sales channels found');
return;
}

/**
* @var SalesChannelEntity $salesChannel
*/
foreach ($salesChannels->getIterator() as $salesChannel) {
$this->expireOrdersInSalesChannel($salesChannel, $context);
}
}

private function expireOrdersInSalesChannel(SalesChannelEntity $salesChannelEntity, Context $context): void
{
$settings = $this->settingsService->getSettings($salesChannelEntity->getId());

if ($settings->isAutomaticOrderExpire() === false) {
$this->logger->debug('Automatic order expire is disabled for this saleschannel', ['salesChannel' => $salesChannelEntity->getName()]);
return;
}

$this->logger->info('Start expire orders for saleschannel', ['salesChannel' => $salesChannelEntity->getName()]);

$date = new \DateTime();
$date->modify('-2 months');

$criteria = new Criteria();
$criteria->addAssociation('transactions.stateMachineState');
$criteria->addFilter(new EqualsFilter('transactions.stateMachineState.technicalName', OrderTransactionStates::STATE_IN_PROGRESS));
$criteria->addFilter(new EqualsFilter('salesChannelId', $salesChannelEntity->getId()));
$criteria->addFilter(new RangeFilter('orderDateTime', [RangeFilter::GTE => $date->format(Defaults::STORAGE_DATE_TIME_FORMAT)]));
$criteria->addSorting(new FieldSorting('orderDateTime', FieldSorting::DESCENDING));
$criteria->setLimit(10);

$this->logger->debug('Search for orders with payment status in progress');

$searchResult = $this->orderRepository->search($criteria, $context);
if ($searchResult->count() === 0) {
$this->logger->debug('No orders found with payment status in progress');
return;
}

$this->logger->info('Found orders which are in progress', ['foundOrders' => $searchResult->count()]);

/**
* @var OrderCollection $orders
*/
$orders = $searchResult->getEntities();
$expiredOrders = $this->orderExpireService->cancelExpiredOrders($orders, $context);

$this->logger->info('Expired orders with status in progress', ['expiredOrders' => $expiredOrders]);
}
}
8 changes: 8 additions & 0 deletions src/Components/OrderExpiration/ExpireActionResult.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
declare(strict_types=1);

namespace Kiener\MolliePayments\Components\OrderExpiration;

class ExpireActionResult
{
}
10 changes: 10 additions & 0 deletions src/Resources/config/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,16 @@
<helpText lang="de-DE">Wenn aktiviert, storniert das Plugin Mollie-Bestellungen automatisch, wenn sie in Shopware storniert werden. Nur Bestellungen, die erstellt, autorisiert oder teilweise versandt wurden, werden storniert. Bei teilweisem Versand werden nur Artikel storniert, die nicht versendet wurden.</helpText>
<helpText lang="nl-NL">Indien ingeschakeld, zal de plug-in automatisch Mollie-bestellingen annuleren wanneer ze worden geannuleerd in Shopware. Alleen bestellingen die zijn aangemaakt, geautoriseerd of gedeeltelijk zijn verzonden, worden geannuleerd. Indien gedeeltelijk verzonden, worden alleen artikelen geannuleerd die niet zijn verzonden.</helpText>
</input-field>
<input-field type="bool">
<name>automaticOrderExpire</name>
<defaultValue>false</defaultValue>
<label>Automatic Expiration</label>
<label lang="de-DE">Automatische Ablauf</label>
<label lang="nl-NL">Automatische vervaldatum</label>
<helpText>If enabled, the plugin will automatically expire orders with the payment status "In Progress".</helpText>
<helpText lang="de-DE">Wenn aktiviert, lässt das Plugin Bestellungen mit dem Status „In Bearbeitung“ und dem Zahlungsstatus „Offen“ oder „Autorisiert“ automatisch ablaufen.</helpText>
<helpText lang="nl-NL">Als deze optie is ingeschakeld, verlopen bestellingen met de status 'In uitvoering' en de betalingsstatus 'Open' of 'Geautoriseerd' automatisch.</helpText>
</input-field>
</card>
<card>
<title>Refund Manager</title>
Expand Down
3 changes: 1 addition & 2 deletions src/Resources/config/services/scheduled_tasks.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@

<service id="Kiener\MolliePayments\ScheduledTask\OrderStatus\ExpireOrderTaskHandler">
<argument type="service" id="Kiener\MolliePayments\Repository\ScheduledTask\ScheduledTaskRepository"/>
<argument type="service" id="Kiener\MolliePayments\Repository\Order\OrderRepository"/>
<argument type="service" id="Kiener\MolliePayments\Service\Order\OrderExpireService"/>
<argument type="service" id="Kiener\MolliePayments\Components\OrderExpiration\ExpireAction"/>
<argument type="service" id="mollie_payments.logger"/>
<tag name="messenger.message_handler"/>
</service>
Expand Down
7 changes: 7 additions & 0 deletions src/Resources/config/services/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,13 @@
<tag name="mollie_payments.mail.attachment_generator"/>
</service>

<service id="Kiener\MolliePayments\Components\OrderExpiration\ExpireAction">
<argument type="service" id="Kiener\MolliePayments\Repository\Order\OrderRepository"/>
<argument type="service" id="Kiener\MolliePayments\Repository\SalesChannel\SalesChannelRepository"/>
<argument type="service" id="Kiener\MolliePayments\Service\Order\OrderExpireService"/>
<argument type="service" id="Kiener\MolliePayments\Service\SettingsService"/>
<argument type="service" id="mollie_payments.logger"/>
</service>



Expand Down
54 changes: 11 additions & 43 deletions src/ScheduledTask/OrderStatus/ExpireOrderTaskHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,64 +3,32 @@

namespace Kiener\MolliePayments\ScheduledTask\OrderStatus;

use Kiener\MolliePayments\Repository\Order\OrderRepositoryInterface;
use Kiener\MolliePayments\Components\OrderExpiration\ExpireAction;
use Kiener\MolliePayments\Repository\ScheduledTask\ScheduledTaskRepositoryInterface;
use Kiener\MolliePayments\Service\Order\OrderExpireService;
use Psr\Log\LoggerInterface;
use Shopware\Core\Checkout\Order\OrderCollection;
use Shopware\Core\Checkout\Order\OrderStates;
use Shopware\Core\Framework\Api\Context\SystemSource;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Shopware\Core\Framework\MessageQueue\ScheduledTask\ScheduledTaskHandler;

#[\Symfony\Component\Messenger\Attribute\AsMessageHandler(handles: ExpireOrderTask::class)]
class ExpireOrderTaskHandler extends ScheduledTaskHandler
{
private LoggerInterface $logger;
private OrderRepositoryInterface $orderRepository;
private OrderExpireService $orderExpireService;

public function __construct(ScheduledTaskRepositoryInterface $scheduledTaskRepository, OrderRepositoryInterface $orderRepository, OrderExpireService $orderExpireService, LoggerInterface $logger)
{
/** @phpstan-ignore-next-line */
private ExpireAction $expireAction;

public function __construct(
ScheduledTaskRepositoryInterface $scheduledTaskRepository,
ExpireAction $expireAction,
LoggerInterface $logger
) {
/** @phpstan-ignore-next-line */
parent::__construct($scheduledTaskRepository->getRepository(), $logger);
$this->logger = $logger;
$this->orderRepository = $orderRepository;
$this->orderExpireService = $orderExpireService;
$this->expireAction = $expireAction;
}

public function run(): void
{
$this->logger->debug('Start resetting in_progress orders');

$context = new Context(new SystemSource());

$criteria = new Criteria();
$criteria->addAssociation('transactions.stateMachineState');
$criteria->addFilter(new EqualsFilter('transactions.stateMachineState.technicalName', OrderStates::STATE_IN_PROGRESS));
$criteria->addSorting(new FieldSorting('orderDateTime', FieldSorting::DESCENDING));
$criteria->setLimit(10);

$this->logger->debug('Search for orders which are in progress state');

$searchResult = $this->orderRepository->search($criteria, $context);
if ($searchResult->count() === 0) {
$this->logger->debug('No in progress orders found');
return;
}

$this->logger->info('Found orders which are in progress', ['foundOrders' => $searchResult->count()]);

/**
* @var OrderCollection $orders
*/
$orders = $searchResult->getEntities();
$resetted = $this->orderExpireService->cancelExpiredOrders($orders, $context);

$this->logger->info('Rested expired orders', ['restedOrders' => $resetted]);
$this->expireAction->expireOrders($context);
}

/**
Expand Down
15 changes: 15 additions & 0 deletions src/Setting/MollieSettingStruct.php
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,11 @@ class MollieSettingStruct extends Struct
*/
protected $refundManagerCreateCreditNotesSuffix = '';

/**
* @var bool
*/
protected $automaticOrderExpire = false;

/**
* @return string
*/
Expand Down Expand Up @@ -1073,4 +1078,14 @@ public function setRefundManagerCreateCreditNotesSuffix(string $refundManagerCre
{
$this->refundManagerCreateCreditNotesSuffix = $refundManagerCreateCreditNotesSuffix;
}

public function isAutomaticOrderExpire(): bool
{
return $this->automaticOrderExpire;
}

public function setAutomaticOrderExpire(bool $automaticOrderExpire): void
{
$this->automaticOrderExpire = $automaticOrderExpire;
}
}
Loading