Skip to content

Commit

Permalink
UNZER-542 --draft-- Fixing ordersnr in admin b2b/b2c paylater
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniil Tkachev committed Feb 14, 2025
1 parent 33f632c commit 0ee2533
Show file tree
Hide file tree
Showing 27 changed files with 1,720 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/Controller/Admin/AdminOrderController.php
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ protected function addAuthorizationViewData(Authorization $authorization): void
protected function getCustomerTypeAndCurrencyFromTransaction(): array
{
$transactionService = $this->getServiceFromContainer(TransactionService::class);
return $transactionService->getCustomerTypeAndCurrencyFromTransactionByOrderId($this->getEditObjectId());
return $transactionService->getCustomerTypeAndCurrencyByOrderId($this->getEditObjectId());
}

/**
Expand Down
3 changes: 3 additions & 0 deletions src/Model/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ public function finalizeUnzerOrderAfterRedirect(
$this->setTmpOrderStatus($unzerOrderId, 'FINISHED');
$iRet = $this->sendOrderConfirmationEmail($oUser, $oBasket, $oUserPayment);
} else {
if ($unzerPaymentStatus !== PaymentService::STATUS_NOT_FINISHED) {
Registry::getSession()->setVariable('orderCancellationProcessed', true);
}
$isError = $unzerPaymentStatus === PaymentService::STATUS_ERROR;
if (!$isError && !isset($params['finalizeCancellation'])) {
$this->sendOrderConfirmationEmail($oUser, $oBasket, $oUserPayment);
Expand Down
5 changes: 4 additions & 1 deletion src/Service/Payment.php
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,8 @@ public function doUnzerAuthorizationCancel(

/**
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @throws \Doctrine\DBAL\Driver\Exception
* @throws \Doctrine\DBAL\Exception
*/
public function sendShipmentNotification(
?Order $oOrder,
Expand All @@ -483,8 +485,9 @@ public function sendShipmentNotification(
}

$sPaymentId = $sPaymentId ?? $this->transactionService->getPaymentIdByOrderId($oOrder->getId());

$transactionDetails = $this->transactionService
->getCustomerTypeAndCurrencyFromTransactionByOrderId($oOrder->getId());
->getCustomerTypeAndCurrencyByOrderId($oOrder->getId());

$blSuccess = false;

Expand Down
25 changes: 25 additions & 0 deletions src/Service/RequestService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace OxidSolutionCatalysts\Unzer\Service;

use OxidEsales\Eshop\Core\Request;

class RequestService
{
/** @var Request $oxidRequest */
private $oxidRequest;

public function __construct(Request $oxidRequest)
{
$this->oxidRequest = $oxidRequest;
}
public function isSavePaymentSelectedByUserInRequest(): bool
{
return $this->getUnzerBoolRequestParameter('oscunzersavepayment');
}

private function getUnzerBoolRequestParameter(string $varName): bool
{
return (bool) $this->oxidRequest->getRequestParameter($varName);
}
}
73 changes: 73 additions & 0 deletions src/Service/SavedPayment/SavedPaymentFetchPaymentTypeService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

namespace OxidSolutionCatalysts\Unzer\Service\SavedPayment;

use OxidSolutionCatalysts\Unzer\Exception\UnzerException;
use OxidSolutionCatalysts\Unzer\Service\DebugHandler;
use OxidSolutionCatalysts\Unzer\Service\UnzerSDKLoader;
use UnzerSDK\Exceptions\UnzerApiException;
use UnzerSDK\Resources\PaymentTypes\Card;
use UnzerSDK\Resources\PaymentTypes\Paypal;
use UnzerSDK\Resources\PaymentTypes\SepaDirectDebit;

class SavedPaymentFetchPaymentTypeService
{
private UnzerSDKLoader $unzerSDKLoader;
private DebugHandler $debugHandler;

public function __construct(UnzerSDKLoader $unzerSDKLoader, DebugHandler $debugHandler)
{
$this->unzerSDKLoader = $unzerSDKLoader;
$this->debugHandler = $debugHandler;
}

/**
* @param array $transactions transactions got from
* SavedPaymentFetchPaymentTypeService::getSavedPaymentTransactions
*/
public function fetchPaymentTypes(array $transactions): array
{
$paymentTypes = [];
foreach ($transactions as $transaction) {
$paymentTypeId = $transaction['PAYMENTTYPEID'];
$paymentId = (string)$transaction['OXPAYMENTTYPE'];
$currency = $transaction['CURRENCY'];
$customerType = $transaction['CUSTOMERTYPE'];
$transactionOxId = $transaction['OXID'];

if (empty($paymentTypeId)) {
continue;
}

try {
$unzerSDK = $this->unzerSDKLoader->getUnzerSDK(
$paymentId,
$currency,
$customerType
);
$paymentType = $unzerSDK->fetchPaymentType($paymentTypeId);
if ($paymentType instanceof Card) {
$paymentTypes[$paymentType->getBrand()][$transactionOxId] = $paymentType->expose();
}
if ($paymentType instanceof Paypal) {
$paymentTypes['paypal'][$transactionOxId] = $paymentType->expose();
}
if ($paymentType instanceof SepaDirectDebit) {
$paymentTypes['sepa'][$transactionOxId] = $paymentType->expose();
}
} catch (UnzerApiException | UnzerException | \Throwable $e) {
if ($e->getCode() !== 'API.500.100.001') {
$logEntry = sprintf(
'Unknown error code while creating the PaymentList: "%s", message: "%s" ',
$e->getCode(),
$e->getMessage()
);
$this->debugHandler->log($logEntry);
continue;
}
}
}

return $paymentTypes;
}
}
38 changes: 38 additions & 0 deletions src/Service/SavedPayment/SavedPaymentLoadFilterService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace OxidSolutionCatalysts\Unzer\Service\SavedPayment;

use OxidSolutionCatalysts\Unzer\Service\SavedPaymentLoadService;
use InvalidArgumentException;

class SavedPaymentLoadFilterService
{
/** @var SavedPaymentMethodValidator $methodValidator */
private $methodValidator;

public function __construct(SavedPaymentMethodValidator $methodValidator)
{
$this->methodValidator = $methodValidator;
}

public function getPaymentTypeIdLikeExpression(string $savedPaymentMethod): string
{
if (!$this->methodValidator->validate(($savedPaymentMethod))) {
throw new InvalidArgumentException(
"Invalid savedPaymentMethod SavedPaymentService::getLastSavedPaymentTransaction"
. ": $savedPaymentMethod"
);
}

if (SavedPaymentLoadService::SAVED_PAYMENT_ALL === $savedPaymentMethod) {
return "transactionAfterOrder.PAYMENTTYPEID LIKE 's-"
. SavedPaymentLoadService::SAVED_PAYMENT_PAYPAL . "%'"
. " OR transactionAfterOrder.PAYMENTTYPEID LIKE 's-"
. SavedPaymentLoadService::SAVED_PAYMENT_CREDIT_CARD . "%'"
. " OR transactionAfterOrder.PAYMENTTYPEID LIKE 's-"
. SavedPaymentLoadService::SAVED_PAYMENT_SEPA_DIRECT_DEBIT . "%'";
}

return "transactionAfterOrder.PAYMENTTYPEID LIKE 's-{$savedPaymentMethod}%'";
}
}
26 changes: 26 additions & 0 deletions src/Service/SavedPayment/SavedPaymentLoadGroupService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace OxidSolutionCatalysts\Unzer\Service\SavedPayment;

use OxidSolutionCatalysts\Unzer\Service\SavedPaymentLoadService;

/**
* @SuppressWarnings(PHPMD.LongVariable)
*/
class SavedPaymentLoadGroupService
{
/**
* in case of sepa both the transaction before and the transaction after order get
* SAVEPAYMENT = 1 because only in case of sepa it's the same request, because of that we group
* here by PAYMENTTYPEID
*/
public function groupByPaymentTypeId(array $ungroupedTransactions): array
{
$groupedTransactions = [];
foreach ($ungroupedTransactions as $ungroupedTransaction) {
$groupedTransactions[$ungroupedTransaction['PAYMENTTYPEID']] = $ungroupedTransaction;
}

return array_values($groupedTransactions);
}
}
84 changes: 84 additions & 0 deletions src/Service/SavedPayment/SavedPaymentMapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

namespace OxidSolutionCatalysts\Unzer\Service\SavedPayment;

/**
* This service is used to filter out those PaymentTypes from the amount of the given PaymentTypes,
* so that only one PaymentType per PayPal account or credit card remains.
*/
class SavedPaymentMapper
{
private const GROUPING_KEY_PAYPAL = 'email';
private const GROUPING_KEY_CARD = 'number|expiryDate';
private const GROUPING_KEY_SEPA = 'iban';

public function groupPaymentTypes(array $paymentTypes): array
{
$groupedPaymentTypes = [];
foreach ($paymentTypes as $paymentMethod => $paymentTypesOfMethod) {
$groupedPaymentTypes[$paymentMethod] = $this->groupPaymentTypesInner(
$paymentTypesOfMethod
);
}

return $groupedPaymentTypes;
}

private function groupPaymentTypesInner(array $paymentTypes): array
{
$groupedPaymentTypes = [];
foreach ($paymentTypes as $paymentType) {
$groupingKeyBy = $this->getGroupingKey($paymentType);
if ($groupingKeyBy && $this->paymentTypeMatchesGroupingKey($paymentType, $groupingKeyBy)) {
$groupedPaymentTypes[$this->getGroupingValue($paymentType, $groupingKeyBy)] = $paymentType;
}
}

return $groupedPaymentTypes;
}

private function paymentTypeMatchesGroupingKey(array $paymentType, string $groupingKey): bool
{
if (stripos($groupingKey, '|')) {
$paymentTypeKeys = explode('|', $groupingKey);

return $this->areKeysDefined($paymentTypeKeys, $paymentType);
}
return isset($paymentType[$groupingKey]);
}

/**
* the order of if statements is important because email is defined in all payment types, number only for
* credit card and iban only for sepa payments
*/
private function getGroupingKey(array $paymentType): ?string
{
if ($this->paymentTypeMatchesGroupingKey($paymentType, self::GROUPING_KEY_CARD)) {
return self::GROUPING_KEY_CARD;
} elseif (isset($paymentType[self::GROUPING_KEY_SEPA])) {
return self::GROUPING_KEY_SEPA;
} elseif (isset($paymentType[self::GROUPING_KEY_PAYPAL])) {
return self::GROUPING_KEY_PAYPAL;
}

return null;
}

private function getGroupingValue(array $paymentType, string $groupingKeyBy): string
{
if ($this->paymentTypeMatchesGroupingKey($paymentType, self::GROUPING_KEY_CARD)) {
$paymentTypeKeys = explode('|', self::GROUPING_KEY_CARD);
return $paymentType[$paymentTypeKeys[0]] . '|' . $paymentType[$paymentTypeKeys[1]];
}

return $paymentType[$groupingKeyBy];
}

private function areKeysDefined(array $requiredKeys, array $array): bool
{
$arrayKeys = array_keys($array);
$missingKeys = array_diff($requiredKeys, $arrayKeys);

return empty($missingKeys);
}
}
21 changes: 21 additions & 0 deletions src/Service/SavedPayment/SavedPaymentMethodValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace OxidSolutionCatalysts\Unzer\Service\SavedPayment;

use OxidSolutionCatalysts\Unzer\Service\SavedPaymentLoadService;

class SavedPaymentMethodValidator
{
public function validate(string $savedPaymentMethod): bool
{
switch ($savedPaymentMethod) {
case SavedPaymentLoadService::SAVED_PAYMENT_PAYPAL:
case SavedPaymentLoadService::SAVED_PAYMENT_CREDIT_CARD:
case SavedPaymentLoadService::SAVED_PAYMENT_SEPA_DIRECT_DEBIT:
case SavedPaymentLoadService::SAVED_PAYMENT_ALL:
return true;
default:
return false;
}
}
}
43 changes: 43 additions & 0 deletions src/Service/SavedPayment/SavedPaymentSessionService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace OxidSolutionCatalysts\Unzer\Service\SavedPayment;

use OxidEsales\Eshop\Core\Session;
use OxidSolutionCatalysts\Unzer\Service\RequestService;

class SavedPaymentSessionService
{
private Session $session;
private RequestService $requestService;

public function __construct(Session $session, RequestService $requestService)
{
$this->session = $session;
$this->requestService = $requestService;
}

public function isSavedPayment(): bool
{
return (bool) $this->session->getVariable($this->getSessionVariableName());
}

public function setSavedPayment(): void
{
$this->session->setVariable(
$this->getSessionVariableName(),
$this->requestService->isSavePaymentSelectedByUserInRequest()
);
}

public function unsetSavedPayment(): void
{
$this->session->deleteVariable(
$this->getSessionVariableName()
);
}

private function getSessionVariableName(): string
{
return self::class . '_userClickedSavePaymentCheckbox';
}
}
24 changes: 24 additions & 0 deletions src/Service/SavedPayment/UserIdService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace OxidSolutionCatalysts\Unzer\Service\SavedPayment;

use UnzerSDK\Resources\PaymentTypes\BasePaymentType;
use UnzerSDK\Resources\PaymentTypes\Card;
use UnzerSDK\Resources\PaymentTypes\Paypal;
use UnzerSDK\Resources\PaymentTypes\SepaDirectDebit;

class UserIdService
{
public function getUserIdByPaymentType(BasePaymentType $paymentType): string
{
if ($paymentType instanceof Paypal) {
return $paymentType->getEmail() ?? '';
} elseif ($paymentType instanceof Card) {
return $paymentType->getNumber() . '|' . $paymentType->getExpiryDate();
} elseif ($paymentType instanceof SepaDirectDebit) {
return $paymentType->getIban() ?? '';
}

return '';
}
}
Loading

0 comments on commit 0ee2533

Please sign in to comment.