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-253: extended logic of refundManager ConfigControllerBase #828

Merged
merged 1 commit into from
Sep 5, 2024
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
10 changes: 10 additions & 0 deletions src/Components/RefundManager/RefundData/OrderItem/ProductItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,14 @@ private function getProductNumber(): string

return (string)$this->lineItem->getPayload()['productNumber'];
}

public function getAlreadyRefundedQty(): int
{
return $this->alreadyRefundedQty;
}

public function getId(): string
{
return $this->lineItem->getId();
}
}
28 changes: 20 additions & 8 deletions src/Controller/Api/PluginConfig/ConfigControllerBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace Kiener\MolliePayments\Controller\Api\PluginConfig;

use Exception;
use Kiener\MolliePayments\Controller\Api\PluginConfig\Exceptions\MollieRefundConfigException;
use Kiener\MolliePayments\Controller\Api\PluginConfig\Services\MollieRefundConfigService;
use Kiener\MolliePayments\Service\MollieApi\ApiKeyValidator;
use Kiener\MolliePayments\Service\SettingsService;
use Kiener\MolliePayments\Setting\MollieSettingStruct;
Expand Down Expand Up @@ -30,16 +32,26 @@ class ConfigControllerBase extends AbstractController
*/
protected $apiKeyValidator;

/**
* @var MollieRefundConfigService
*/
private $configMollieRefundService;

/**
* @param SettingsService $settings
* @param SnippetFinderInterface $snippetFinder
* @param ApiKeyValidator $apiKeyValidator
*/
public function __construct(SettingsService $settings, SnippetFinderInterface $snippetFinder, ApiKeyValidator $apiKeyValidator)
{
public function __construct(
SettingsService $settings,
SnippetFinderInterface $snippetFinder,
ApiKeyValidator $apiKeyValidator,
MollieRefundConfigService $configMollieRefundService
) {
$this->settings = $settings;
$this->snippetFinder = $snippetFinder;
$this->apiKeyValidator = $apiKeyValidator;
$this->configMollieRefundService = $configMollieRefundService;
}

/**
Expand Down Expand Up @@ -174,19 +186,19 @@ public function getRefundManagerConfig(Request $request, Context $context): Json
// employees of the merchant.
// so depending on the order, we grab the matching sales channel configuration.
$salesChannelID = (string)$request->get('salesChannelId');
$orderId = (string)$request->get('orderId');

if (empty($salesChannelID)) {
$config = $this->settings->getSettings('');
} else {
$config = $this->settings->getSettings($salesChannelID);
}

return new JsonResponse([
'enabled' => $config->isRefundManagerEnabled(),
'autoStockReset' => $config->isRefundManagerAutoStockReset(),
'verifyRefund' => $config->isRefundManagerVerifyRefund(),
'showInstructions' => $config->isRefundManagerShowInstructions(),
]);
try {
return $this->configMollieRefundService->createConfigControllerResponse($orderId, $config, $salesChannelID, $context);
} catch (MollieRefundConfigException $exception) {
return ConfigControllerResponse::createFromMollieSettingStruct($config);
}
}

/**
Expand Down
35 changes: 35 additions & 0 deletions src/Controller/Api/PluginConfig/ConfigControllerResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php
declare(strict_types=1);

namespace Kiener\MolliePayments\Controller\Api\PluginConfig;

use Kiener\MolliePayments\Setting\MollieSettingStruct;
use Symfony\Component\HttpFoundation\JsonResponse;

class ConfigControllerResponse extends JsonResponse
{
final private function __construct(bool $enabled, bool $autoStockReset, bool $verifyRefund, bool $showInstructions)
{
parent::__construct([
'enabled' => $enabled,
'autoStockReset' => $autoStockReset,
'verifyRefund' => $verifyRefund,
'showInstructions' => $showInstructions,
], self::HTTP_OK);
}

public static function createFromMollieSettingStruct(MollieSettingStruct $config): self
{
return self::createFromValues(
$config->isRefundManagerEnabled(),
$config->isRefundManagerAutoStockReset(),
$config->isRefundManagerVerifyRefund(),
$config->isRefundManagerShowInstructions()
);
}

public static function createFromValues(bool $enabled, bool $autoStockReset, bool $verifyRefund, bool $showInstructions): self
{
return new self($enabled, $autoStockReset, $verifyRefund, $showInstructions);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);

namespace Kiener\MolliePayments\Controller\Api\PluginConfig\Exceptions;

class EmptyOrderIdProvidedConfigException extends MollieRefundConfigException
{
public static function create(): self
{
return new self('No order id provided');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);

namespace Kiener\MolliePayments\Controller\Api\PluginConfig\Exceptions;

class LineItemNotPartOfCollectionConfigException extends MollieRefundConfigException
{
public static function create(string $id): self
{
$message = sprintf('The line item with ID "%s" is not part of the collection.', $id);
return new self($message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);

namespace Kiener\MolliePayments\Controller\Api\PluginConfig\Exceptions;

class MetaDataNotFoundInRefundConfigException extends MollieRefundConfigException
{
public static function create(): self
{
return new self('The meta data for the refund could not be found.');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);

namespace Kiener\MolliePayments\Controller\Api\PluginConfig\Exceptions;

class MollieOrderNotFoundConfigException extends MollieRefundConfigException
{
public static function create(string $orderId): self
{
$message = sprintf('Order with ID "%s" not found', $orderId);
return new self($message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);

namespace Kiener\MolliePayments\Controller\Api\PluginConfig\Exceptions;

use Throwable;

class MollieRefundConfigException extends \Exception
{
public const CODE = 1000;
final protected function __construct(string $message, Throwable $previous = null)
{
parent::__construct($message, self::CODE, $previous);
}

public static function fromException(Throwable $exception): self
{
return new self($exception->getMessage(), $exception);
}
}
124 changes: 124 additions & 0 deletions src/Controller/Api/PluginConfig/Services/MollieRefundConfigService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<?php
declare(strict_types=1);

namespace Kiener\MolliePayments\Controller\Api\PluginConfig\Services;

use Kiener\MolliePayments\Components\RefundManager\RefundManagerInterface;
use Kiener\MolliePayments\Controller\Api\PluginConfig\ConfigControllerResponse;
use Kiener\MolliePayments\Controller\Api\PluginConfig\Exceptions\EmptyOrderIdProvidedConfigException;
use Kiener\MolliePayments\Controller\Api\PluginConfig\Exceptions\MetaDataNotFoundInRefundConfigException;
use Kiener\MolliePayments\Controller\Api\PluginConfig\Exceptions\MollieOrderNotFoundConfigException;
use Kiener\MolliePayments\Controller\Api\PluginConfig\Exceptions\MollieRefundConfigException;
use Kiener\MolliePayments\Controller\Api\PluginConfig\Structs\Collections\OrderLineItemStructCollection;
use Kiener\MolliePayments\Controller\Api\PluginConfig\Structs\OrderLineItemStruct;
use Kiener\MolliePayments\Service\MollieApi\Order as MollieOrderService;
use Kiener\MolliePayments\Service\OrderService;
use Kiener\MolliePayments\Setting\MollieSettingStruct;
use Kiener\MolliePayments\Struct\Order\OrderAttributes;
use Shopware\Core\Checkout\Cart\Exception\OrderNotFoundException;
use Shopware\Core\Framework\Context;

class MollieRefundConfigService
{
/**
* @var OrderService
*/
private $orderService;

/**
* @var RefundManagerInterface
*/
private $refundManager;

/**
* @var MollieOrderService
*/
private $mollieOrderService;

public function __construct(
OrderService $orderService,
RefundManagerInterface $refundManager,
MollieOrderService $mollieOrderService
) {
$this->orderService = $orderService;
$this->refundManager = $refundManager;
$this->mollieOrderService = $mollieOrderService;
}

/**
* @throws MollieRefundConfigException
*/
public function createConfigControllerResponse(string $orderId, MollieSettingStruct $config, string $salesChannelId, Context $context): ConfigControllerResponse
{
if (empty($orderId)) {
throw EmptyOrderIdProvidedConfigException::create();
}

try {
$order = $this->orderService->getOrder($orderId, $context);
$orderAttributes = new OrderAttributes($order);
$refundData = $this->refundManager->getData($order, $context);
$refunds = $refundData->getRefunds();
$mollieOrder = $this->mollieOrderService->getMollieOrder($orderAttributes->getMollieOrderId(), $salesChannelId);

$structs = [];

foreach ($mollieOrder->lines() as $line) {
$structs[] = OrderLineItemStruct::createWithId($line->metadata->orderLineItemId)
->setIsShipped($line->quantityShipped >= 1)
->setOrderedQuantity($line->quantity);
}

$structs = OrderLineItemStructCollection::create(...$structs);

foreach ($refunds as $refund) {
if (!isset($refund['metadata'], $refund['metadata']->composition)) {
throw MetaDataNotFoundInRefundConfigException::create();
}

$composition = $refund['metadata']->composition;
foreach ($composition as $item) {
$structs->getById($item['swLineId'])
->setHasPendingRefund($refund['isPending'])
->setRefundedCount($item['quantity']);
}
}

return $this->createResponse($structs, $config);
} catch (OrderNotFoundException $exception) {
throw MollieOrderNotFoundConfigException::create($orderId);
} catch (MollieRefundConfigException $exception) {
throw $exception;
} catch (\Exception $exception) {
throw MollieRefundConfigException::fromException($exception);
}
}

public function createResponse(OrderLineItemStructCollection $lineItems, MollieSettingStruct $config): ConfigControllerResponse
{
$hasRefundableItems = false;

foreach ($lineItems as $lineItem) {
// when the line item has a pending refund, the merchant
// needs to be able to open the refund manager to cancel the refund
if ($lineItem->hasPendingRefund()) {
$hasRefundableItems = true;
break;
}

// only shipped items can be refunded
// only items that have not been fully refunded can be refunded
if ($lineItem->isShipped() && $lineItem->getRefundedCount() < $lineItem->getOrderedQuantity()) {
$hasRefundableItems = true;
break;
}
}

return ConfigControllerResponse::createFromValues(
$config->isRefundManagerEnabled() && $hasRefundableItems,
$config->isRefundManagerAutoStockReset(),
$config->isRefundManagerVerifyRefund(),
$config->isRefundManagerShowInstructions()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);

namespace Kiener\MolliePayments\Controller\Api\PluginConfig\Structs\Collections;

use Kiener\MolliePayments\Controller\Api\PluginConfig\Exceptions\LineItemNotPartOfCollectionConfigException;
use Kiener\MolliePayments\Controller\Api\PluginConfig\Structs\OrderLineItemStruct;
use Shopware\Core\Framework\Struct\StructCollection;

/**
* @extends StructCollection<OrderLineItemStruct>
*/
class OrderLineItemStructCollection extends StructCollection
{
final private function __construct(iterable $elements)
{
parent::__construct($elements);
}

public static function create(OrderLineItemStruct ...$structs): self
{
return new self($structs);
}

/**
* @throws LineItemNotPartOfCollectionConfigException
*/
public function getById(string $id): OrderLineItemStruct
{
foreach ($this as $item) {
if ($item->getId() === $id) {
return $item;
}
}

throw LineItemNotPartOfCollectionConfigException::create($id);
}
}
Loading
Loading