Skip to content

Commit

Permalink
Merge pull request #115 from kellerkinderDE/feature/PAYONE-92
Browse files Browse the repository at this point in the history
[PAYONE-92] payment method specific status mapping
  • Loading branch information
jvarelmann authored Aug 30, 2021
2 parents d301ff9 + 27a26e7 commit 518d8d0
Show file tree
Hide file tree
Showing 10 changed files with 1,497 additions and 144 deletions.
100 changes: 17 additions & 83 deletions src/Components/TransactionStatus/TransactionStatusService.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use PayonePayment\Components\ConfigReader\ConfigReaderInterface;
use PayonePayment\Components\Currency\CurrencyPrecisionInterface;
use PayonePayment\Configuration\ConfigurationPrefixes;
use PayonePayment\Installer\CustomFieldInstaller;
use PayonePayment\Struct\PaymentTransaction;
use Psr\Log\LoggerInterface;
Expand Down Expand Up @@ -84,8 +85,10 @@ public function transitionByConfigMapping(SalesChannelContext $salesChannelConte
return;
}

$configuration = $this->configReader->read($salesChannelContext->getSalesChannel()->getId());
$currency = $paymentTransaction->getOrder()->getCurrency();
$configuration = $this->configReader->read($salesChannelContext->getSalesChannel()->getId());
$currency = $paymentTransaction->getOrder()->getCurrency();
$orderTransaction = $paymentTransaction->getOrderTransaction();
$paymentMethod = $orderTransaction->getPaymentMethod();

if (null === $currency) {
return;
Expand All @@ -101,27 +104,24 @@ public function transitionByConfigMapping(SalesChannelContext $salesChannelConte

$transitionName = $configuration->getString($configurationKey);

if (empty($transitionName)) {
if ($this->isTransactionOpen($transactionData)) {
$transitionName = StateMachineTransitionActions::ACTION_REOPEN;
} elseif ($this->isTransactionPartialPaid($transactionData, $currency)) {
$transitionName = StateMachineTransitionActions::ACTION_PAID_PARTIALLY;
} elseif ($this->isTransactionPaid($transactionData, $currency)) {
$transitionName = StateMachineTransitionActions::ACTION_PAID;
} elseif ($this->isTransactionPartialRefund($transactionData, $currency)) {
$transitionName = StateMachineTransitionActions::ACTION_REFUND_PARTIALLY;
} elseif ($this->isTransactionRefund($transactionData, $currency)) {
$transitionName = StateMachineTransitionActions::ACTION_REFUND;
} elseif ($this->isTransactionCancelled($transactionData)) {
$transitionName = StateMachineTransitionActions::ACTION_CANCEL;
}
if (null !== $paymentMethod) {
$configurationPrefix = ConfigurationPrefixes::CONFIGURATION_PREFIXES[$paymentMethod->getHandlerIdentifier()];
/** @var string $transitionName */
$transitionName = $configuration->getByPrefix($configurationKey, $configurationPrefix, $configuration->getString($configurationKey));
}

if (empty($transitionName)) {
$this->logger->info('No status transition configured',
[
'configurationKey' => $configurationKey,
'paymentMethod' => (null !== $paymentMethod) ? $paymentMethod->getHandlerIdentifier() : 'unknown',
]
);

return;
}

$this->executeTransition($salesChannelContext->getContext(), $paymentTransaction->getOrderTransaction()->getId(), strtolower($transitionName), $transactionData);
$this->executeTransition($salesChannelContext->getContext(), $orderTransaction->getId(), strtolower($transitionName), $transactionData);
}

public function transitionByName(Context $context, string $transactionId, string $transitionName, array $parameter = []): void
Expand Down Expand Up @@ -161,44 +161,6 @@ private function executeTransition(Context $context, string $transactionId, stri
}
}

private function isTransactionOpen(array $transactionData): bool
{
return strtolower($transactionData['txaction']) === self::ACTION_APPOINTED;
}

private function isTransactionPaid(array $transactionData, CurrencyEntity $currency): bool
{
if (in_array(strtolower($transactionData['txaction']), [self::ACTION_PAID, self::ACTION_COMPLETED], true)) {
return true;
}

if (!in_array(strtolower($transactionData['txaction']), [self::ACTION_DEBIT, self::ACTION_CAPTURE, self::ACTION_INVOICE], true)) {
return false;
}

if (array_key_exists('transactiontype', $transactionData) && $transactionData['transactiontype'] === self::TRANSACTION_TYPE_GT) {
return false;
}

$precision = $this->currencyPrecision->getTotalRoundingPrecision($currency);

if (array_key_exists('price', $transactionData) && array_key_exists('receivable', $transactionData) &&
(int) round(((float) $transactionData['receivable'] * (10 ** $precision))) === (int) round(((float) $transactionData['price'] * (10 ** $precision)))) {
return true;
}

if (array_key_exists('price', $transactionData) && array_key_exists('invoice_grossamount', $transactionData) &&
(int) round(((float) $transactionData['invoice_grossamount'] * (10 ** $precision))) === (int) round(((float) $transactionData['price'] * (10 ** $precision)))) {
return true;
}

if ((int) round(((float) $transactionData['receivable'] * (10 ** $precision))) === 0) {
return true;
}

return false;
}

private function isTransactionPartialPaid(array $transactionData, CurrencyEntity $currency): bool
{
if (!in_array(strtolower($transactionData['txaction']), [self::ACTION_DEBIT, self::ACTION_CAPTURE, self::ACTION_INVOICE], true)) {
Expand Down Expand Up @@ -228,29 +190,6 @@ private function isTransactionPartialPaid(array $transactionData, CurrencyEntity
return true;
}

private function isTransactionRefund(array $transactionData, CurrencyEntity $currency): bool
{
$precision = $this->currencyPrecision->getTotalRoundingPrecision($currency);

if (strtolower($transactionData['txaction']) !== self::ACTION_DEBIT) {
return false;
}

if (!array_key_exists('receivable', $transactionData)) {
return false;
}

if (array_key_exists('transactiontype', $transactionData) && $transactionData['transactiontype'] !== self::TRANSACTION_TYPE_GT) {
return false;
}

if ((int) round(((float) $transactionData['receivable'] * (10 ** $precision))) !== 0) {
return false;
}

return true;
}

private function isTransactionPartialRefund(array $transactionData, CurrencyEntity $currency): bool
{
$precision = $this->currencyPrecision->getTotalRoundingPrecision($currency);
Expand All @@ -274,11 +213,6 @@ private function isTransactionPartialRefund(array $transactionData, CurrencyEnti
return true;
}

private function isTransactionCancelled(array $transactionData): bool
{
return in_array(strtolower($transactionData['txaction']), [self::ACTION_CANCELATION, self::ACTION_FAILED], true);
}

private function isAsyncCancelled(PaymentTransaction $paymentTransaction, array $transactionData): bool
{
$customFields = $paymentTransaction->getCustomFields();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Component.register('payone-settings', {
showValidationErrors: false,
isSupportModalOpen: false,
stateMachineTransitionActions: [],
displayStatusMapping: {},
collapsibleState: {
'status_mapping': true,
'payment_credit_card': true,
Expand Down Expand Up @@ -106,6 +107,10 @@ Component.register('payone-settings', {
];
},

isVisiblePaymentMethodCard(card) {
return card.name.startsWith('payment') && !this.isCollapsed(card);
},

isCollapsible(card) {
return card.name in this.collapsibleState;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,33 @@
/>

<sw-form-field-renderer
v-else
v-else-if="!element.name.includes('PaymentStatus')"
v-bind="getElementBind(getBind(element, config))"
v-model="config[element.name]"
/>
</div>
</template>

<template #afterElements="{card, config}">
<sw-switch-field v-if="isVisiblePaymentMethodCard(card)"
v-model="displayStatusMapping[card.name]"
:label="$tc('payone-payment.settingsForm.labelShowSpecificStatusMapping')"
:helpText="$tc('payone-payment.settingsForm.helpTextShowSpecificStatusMapping')"></sw-switch-field>

<div v-if="config">
<template v-for="element in card.elements">
<sw-form-field-renderer
v-if="element.name.includes('PaymentStatus') && displayStatusMapping[card.name]"
:config="{
componentName: 'sw-single-select',
label: getInlineSnippet(getElementBind(getBind(element, config)).config.label),
helpText: getInlineSnippet(getElementBind(getBind(element, config)).config.helpText),
options: stateMachineTransitionActions,
}"
v-model="config[element.name]" />
</template>
</div>
</template>
</sw-system-config>
</sw-card-view>
</template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
"test": "API-Zugangsdaten testen",
"titleSuccess": "Erfolg",
"titleError": "Fehler",
"labelShowSpecificStatusMapping": "Statusmappingkonfiguration einblenden",
"helpTextShowSpecificStatusMapping": "Sie können für jede Zahlungsart ein spezifisches Statusmapping konfigurieren. Existiert eine solche Konfiguration nicht, wird auf die allgemeine Konfiguration zurückgegriffen.",
"messageTestSuccess": "Die API-Zugangsdaten wurden erfolgreich validiert.",
"messageTestNoTestedPayments": "Bei der Prüfung wurden keine Zahlarten getestet, weil keine der PAYONE Zahlarten aktiviert ist. Bitte aktivieren Sie mindestens eine PAYONE Zahlart unter Einstellungen --> Shop --> Zahlungsarten.",
"messageTestError": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
"test": "Test API Credentials",
"titleSuccess": "Success",
"titleError": "Error",
"labelShowSpecificStatusMapping": "Display state mapping configuration",
"helpTextShowSpecificStatusMapping": "If not configured the general status mapping config will be applied.",
"messageTestSuccess": "The API credentials were verified successfully.",
"messageTestNoTestedPayments": "No payment methods were tested during the check because none of the PAYONE payment methods are activated. Please activate at least one PAYONE payment method under Settings --> Shop --> Payment.",
"messageTestError": {
Expand Down
Loading

0 comments on commit 518d8d0

Please sign in to comment.