Skip to content

Commit

Permalink
PAYOSWXP-113: Move validation of different shipping address to defaul…
Browse files Browse the repository at this point in the history
…t filter service
  • Loading branch information
Moritz Müller authored and rommelfreddy committed Feb 28, 2024
1 parent 3a0c434 commit d48977f
Show file tree
Hide file tree
Showing 16 changed files with 230 additions and 287 deletions.
1 change: 1 addition & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
colors="true">
<php>
<ini name="error_reporting" value="-1"/>
<env name="KERNEL_CLASS" value="Shopware\Core\Kernel" />
<env name="APP_ENV" value="test"/>
<env name="APP_DEBUG" value="1"/>
<env name="APP_SECRET" value="s$cretf0rt3st"/>
Expand Down
5 changes: 5 additions & 0 deletions src/Components/ConfigReader/ConfigReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace PayonePayment\Components\ConfigReader;

use PayonePayment\Components\ConfigReader\Exception\ConfigurationPrefixMissingException;
use PayonePayment\Configuration\ConfigurationPrefixes;
use PayonePayment\Struct\Configuration;
use Shopware\Core\System\SystemConfig\SystemConfigService;
Expand All @@ -18,6 +19,10 @@ public function __construct(private readonly SystemConfigService $systemConfigSe

public static function getConfigKeyByPaymentHandler(string $paymentHandler, string $configuration): string
{
if (!isset(ConfigurationPrefixes::CONFIGURATION_PREFIXES[$paymentHandler])) {
throw new ConfigurationPrefixMissingException(sprintf('No configuration prefix for payment handler "%s" found!', $paymentHandler));
}

return self::SYSTEM_CONFIG_DOMAIN . ConfigurationPrefixes::CONFIGURATION_PREFIXES[$paymentHandler] . $configuration;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace PayonePayment\Components\ConfigReader\Exception;

class ConfigurationPrefixMissingException extends \Exception
{
}
59 changes: 54 additions & 5 deletions src/Components/PaymentFilter/DefaultPaymentFilterService.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,24 @@

namespace PayonePayment\Components\PaymentFilter;

use PayonePayment\Components\ConfigReader\ConfigReader;
use PayonePayment\Components\ConfigReader\Exception\ConfigurationPrefixMissingException;
use PayonePayment\Components\PaymentFilter\Exception\PaymentMethodNotAllowedException;
use PayonePayment\PaymentHandler\AbstractPayonePaymentHandler;
use Shopware\Core\Checkout\Customer\Aggregate\CustomerAddress\CustomerAddressEntity;
use Shopware\Core\Checkout\Order\Aggregate\OrderAddress\OrderAddressEntity;
use Shopware\Core\Checkout\Payment\PaymentMethodCollection;
use Shopware\Core\Checkout\Payment\PaymentMethodEntity;
use Shopware\Core\System\Currency\CurrencyEntity;
use Shopware\Core\System\SystemConfig\SystemConfigService;

class DefaultPaymentFilterService implements PaymentFilterServiceInterface
{
/**
* @param class-string<AbstractPayonePaymentHandler> $paymentHandlerClass
*/
public function __construct(
private readonly SystemConfigService $systemConfigService,
private readonly string $paymentHandlerClass,
private readonly ?array $allowedCountries = null,
private readonly ?array $allowedB2bCountries = null,
Expand All @@ -31,7 +35,8 @@ final public function filterPaymentMethods(
PaymentMethodCollection $methodCollection,
PaymentFilterContext $filterContext
): PaymentMethodCollection {
if ($this->getSupportedPaymentMethods($methodCollection)->getElements() === []) {
$supportedPaymentMethods = $this->getSupportedPaymentMethods($methodCollection);
if ($supportedPaymentMethods->getElements() === []) {
return $methodCollection;
}

Expand All @@ -45,6 +50,7 @@ final public function filterPaymentMethods(
$currentValue = $filterContext->getOrder()->getPrice()->getTotalPrice();
}

// Validate and remove all supported payment methods if necessary
try {
$this->validateCurrency($currency);
$this->validateAddress($billingAddress);
Expand All @@ -53,9 +59,13 @@ final public function filterPaymentMethods(
$this->validateMinValue($currentValue);
$this->validateMaxValue($currentValue);
}

// Validate and remove a specific payment method if necessary
$this->validateDifferentShippingAddress($supportedPaymentMethods, $filterContext);

$this->additionalChecks($methodCollection, $filterContext);
} catch (PaymentMethodNotAllowedException) {
$methodCollection = $this->removePaymentMethods($methodCollection);
} catch (PaymentMethodNotAllowedException $paymentMethodNotAllowedException) {
$methodCollection = $this->removePaymentMethods($methodCollection, $paymentMethodNotAllowedException->getDisallowedPaymentMethodCollection());
}

return $methodCollection;
Expand All @@ -76,9 +86,9 @@ private function getSupportedPaymentMethods(PaymentMethodCollection $paymentMeth
: $paymentMethod->getHandlerIdentifier() === $this->paymentHandlerClass);
}

private function removePaymentMethods(PaymentMethodCollection $paymentMethodCollection): PaymentMethodCollection
private function removePaymentMethods(PaymentMethodCollection $paymentMethodCollection, ?PaymentMethodCollection $itemsToRemove = null): PaymentMethodCollection
{
$itemsToRemove = $this->getSupportedPaymentMethods($paymentMethodCollection);
$itemsToRemove = $itemsToRemove ?: $this->getSupportedPaymentMethods($paymentMethodCollection);

return $paymentMethodCollection->filter(static fn (PaymentMethodEntity $entity) => !$itemsToRemove->has($entity->getUniqueIdentifier()));
}
Expand Down Expand Up @@ -123,4 +133,43 @@ private function validateMaxValue(float $currentValue): void
throw new PaymentMethodNotAllowedException('The current cart/order value is higher than the allowed max value');
}
}

private function validateDifferentShippingAddress(PaymentMethodCollection $paymentMethods, PaymentFilterContext $filterContext): void
{
// addresses are already identical - it is not required to check if it is allowed if they are identical or not
if ($filterContext->areAddressesIdentical()) {
return;
}

$disallowedPaymentMethods = [];

foreach ($paymentMethods as $paymentMethod) {
try {
$configKey = ConfigReader::getConfigKeyByPaymentHandler(
$paymentMethod->getHandlerIdentifier(),
'AllowDifferentShippingAddress'
);
} catch (ConfigurationPrefixMissingException) {
continue;
}

/** @var boolean|null $differentShippingAddressAllowed */
$differentShippingAddressAllowed = $this->systemConfigService->get(
$configKey,
$filterContext->getSalesChannelContext()->getSalesChannelId()
);

// if configuration value is null, the payment method should be removed.
if ($differentShippingAddressAllowed === false) {
$disallowedPaymentMethods[] = $paymentMethod;
}
}

if ($disallowedPaymentMethods !== []) {
throw new PaymentMethodNotAllowedException(
'It is not permitted to use a different shipping address',
new PaymentMethodCollection($disallowedPaymentMethods)
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@

namespace PayonePayment\Components\PaymentFilter\Exception;

use Shopware\Core\Checkout\Payment\PaymentMethodCollection;

class PaymentMethodNotAllowedException extends \Exception
{
public function __construct(
string $message,
private readonly ?PaymentMethodCollection $disallowedPaymentMethodCollection = null
) {
parent::__construct($message);
}

public function getDisallowedPaymentMethodCollection(): ?PaymentMethodCollection
{
return $this->disallowedPaymentMethodCollection;
}
}
30 changes: 30 additions & 0 deletions src/Components/PaymentFilter/PaymentFilterContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace PayonePayment\Components\PaymentFilter;

use PayonePayment\Core\Utils\AddressCompare;
use Shopware\Core\Checkout\Cart\Cart;
use Shopware\Core\Checkout\Customer\Aggregate\CustomerAddress\CustomerAddressEntity;
use Shopware\Core\Checkout\Order\Aggregate\OrderAddress\OrderAddressEntity;
Expand All @@ -14,6 +15,8 @@

class PaymentFilterContext extends Struct
{
private bool $_areAddressesIdentical;

public function __construct(
private readonly SalesChannelContext $salesChannelContext,
private readonly CustomerAddressEntity|OrderAddressEntity|null $billingAddress = null,
Expand Down Expand Up @@ -53,4 +56,31 @@ public function getCart(): ?Cart
{
return $this->cart;
}

public function areAddressesIdentical(): bool
{
if (isset($this->_areAddressesIdentical)) {
return $this->_areAddressesIdentical;
}

$billingAddress = $this->getBillingAddress();
$shippingAddress = $this->getShippingAddress();

if ($billingAddress instanceof OrderAddressEntity
&& $shippingAddress instanceof OrderAddressEntity
&& $billingAddress->getId() !== $shippingAddress->getId()
&& !AddressCompare::areOrderAddressesIdentical($billingAddress, $shippingAddress)
) {
return $this->_areAddressesIdentical = false;
}

if ($billingAddress instanceof CustomerAddressEntity
&& $shippingAddress instanceof CustomerAddressEntity
&& $billingAddress->getId() !== $shippingAddress->getId()
&& !AddressCompare::areCustomerAddressesIdentical($billingAddress, $shippingAddress)) {
return $this->_areAddressesIdentical = false;
}

return $this->_areAddressesIdentical = true;
}
}
60 changes: 0 additions & 60 deletions src/Components/PaymentFilter/PayoneBNPLPaymentMethodFilter.php

This file was deleted.

9 changes: 6 additions & 3 deletions src/DependencyInjection/payment_method_filter.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
</service>

<service id="payone.payment_filter_method.klarna" class="PayonePayment\Components\PaymentFilter\KlarnaPaymentMethodFilter">
<argument key="$systemConfigService" type="service" id="Shopware\Core\System\SystemConfig\SystemConfigService" />
<argument key="$paymentHandlerClass">PayonePayment\PaymentHandler\AbstractKlarnaPaymentHandler</argument>
<argument key="$allowedCountries" type="collection">
<argument>AT</argument>
Expand Down Expand Up @@ -61,6 +62,7 @@
</service>

<service id="payone.payment_filter_method.postfinance" class="PayonePayment\Components\PaymentFilter\DefaultPaymentFilterService">
<argument key="$systemConfigService" type="service" id="Shopware\Core\System\SystemConfig\SystemConfigService" />
<argument key="$paymentHandlerClass">PayonePayment\PaymentHandler\AbstractPostfinancePaymentHandler</argument>
<argument key="$allowedCountries" type="collection">
<argument>CH</argument>
Expand All @@ -75,6 +77,7 @@
</service>

<service id="payone.payment_filter_method.przelewy24" class="PayonePayment\Components\PaymentFilter\DefaultPaymentFilterService">
<argument key="$systemConfigService" type="service" id="Shopware\Core\System\SystemConfig\SystemConfigService" />
<argument key="$paymentHandlerClass">PayonePayment\PaymentHandler\PayonePrzelewy24PaymentHandler</argument>
<argument key="$allowedCountries" type="collection">
<argument>PL</argument>
Expand All @@ -89,7 +92,7 @@
</service>

<service id="payone.payment_filter_method.secured_invoice"
class="PayonePayment\Components\PaymentFilter\PayoneBNPLPaymentMethodFilter">
class="PayonePayment\Components\PaymentFilter\DefaultPaymentFilterService">
<argument key="$systemConfigService" type="service" id="Shopware\Core\System\SystemConfig\SystemConfigService" />
<argument key="$paymentHandlerClass">PayonePayment\PaymentHandler\PayoneSecuredInvoicePaymentHandler</argument>
<argument key="$allowedCountries" type="collection">
Expand All @@ -109,7 +112,7 @@
</service>

<service id="payone.payment_filter_method.secured_installment"
class="PayonePayment\Components\PaymentFilter\PayoneBNPLPaymentMethodFilter">
class="PayonePayment\Components\PaymentFilter\DefaultPaymentFilterService">
<argument key="$systemConfigService" type="service" id="Shopware\Core\System\SystemConfig\SystemConfigService" />
<argument key="$paymentHandlerClass">PayonePayment\PaymentHandler\PayoneSecuredInstallmentPaymentHandler</argument>
<argument key="$allowedCountries" type="collection">
Expand All @@ -127,7 +130,7 @@
</service>

<service id="payone.payment_filter_method.secured_direct_debit"
class="PayonePayment\Components\PaymentFilter\PayoneBNPLPaymentMethodFilter">
class="PayonePayment\Components\PaymentFilter\DefaultPaymentFilterService">
<argument key="$systemConfigService" type="service" id="Shopware\Core\System\SystemConfig\SystemConfigService" />
<argument key="$paymentHandlerClass">PayonePayment\PaymentHandler\PayoneSecuredDirectDebitPaymentHandler</argument>
<argument key="$allowedCountries" type="collection">
Expand Down
4 changes: 1 addition & 3 deletions tests/Components/PaymentFilter/AbstractPaymentFilterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

declare(strict_types=1);

namespace PayonePayment\EventListener;
namespace PayonePayment\Components\PaymentFilter;

use PayonePayment\Components\PaymentFilter\PaymentFilterContext;
use PayonePayment\Components\PaymentFilter\PaymentFilterServiceInterface;
use PayonePayment\TestCaseBase\ConfigurationHelper;
use PayonePayment\TestCaseBase\Mock\PaymentHandler\PaymentHandlerMock;
use PayonePayment\TestCaseBase\PayoneTestBehavior;
Expand Down
Loading

0 comments on commit d48977f

Please sign in to comment.