Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 14256e2

Browse files
authored
Merge pull request payplug#138 from payplug/qa
Release 1.1.2
2 parents 1f21295 + 67d0488 commit 14256e2

27 files changed

Lines changed: 311 additions & 185 deletions

spec/Action/CaptureActionSpec.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@
1818
use Payum\Core\Security\TokenInterface;
1919
use PhpSpec\ObjectBehavior;
2020
use Psr\Log\LoggerInterface;
21+
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
22+
use Symfony\Contracts\Translation\TranslatorInterface;
2123

2224
final class CaptureActionSpec extends ObjectBehavior
2325
{
24-
function let(LoggerInterface $logger): void
26+
function let(LoggerInterface $logger, FlashBagInterface $flashBag, TranslatorInterface $translator): void
2527
{
26-
$this->beConstructedWith($logger);
28+
$this->beConstructedWith($logger, $flashBag, $translator);
2729
}
2830

2931
function it_is_initializable(): void

src/Action/CaptureAction.php

Lines changed: 95 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
namespace PayPlug\SyliusPayPlugPlugin\Action;
66

77
use ArrayAccess;
8+
use Payplug\Exception\BadRequestException;
89
use Payplug\Resource\Payment;
910
use PayPlug\SyliusPayPlugPlugin\Action\Api\ApiAwareTrait;
1011
use PayPlug\SyliusPayPlugPlugin\ApiClient\PayPlugApiClientInterface;
12+
use PayPlug\SyliusPayPlugPlugin\Exception\UnknownApiErrorException;
1113
use Payum\Core\Action\ActionInterface;
1214
use Payum\Core\ApiAwareInterface;
1315
use Payum\Core\Bridge\Spl\ArrayObject;
@@ -21,6 +23,8 @@
2123
use Payum\Core\Security\GenericTokenFactoryInterface;
2224
use Payum\Core\Security\TokenInterface;
2325
use Psr\Log\LoggerInterface;
26+
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
27+
use Symfony\Contracts\Translation\TranslatorInterface;
2428

2529
final class CaptureAction implements ActionInterface, ApiAwareInterface, GatewayAwareInterface, GenericTokenFactoryAwareInterface
2630
{
@@ -32,9 +36,20 @@ final class CaptureAction implements ActionInterface, ApiAwareInterface, Gateway
3236
/** @var LoggerInterface */
3337
private $logger;
3438

35-
public function __construct(LoggerInterface $logger)
36-
{
39+
/** @var FlashBagInterface */
40+
private $flashBag;
41+
42+
/** @var TranslatorInterface */
43+
private $translator;
44+
45+
public function __construct(
46+
LoggerInterface $logger,
47+
FlashBagInterface $flashBag,
48+
TranslatorInterface $translator
49+
) {
3750
$this->logger = $logger;
51+
$this->flashBag = $flashBag;
52+
$this->translator = $translator;
3853
}
3954

4055
public function setGenericTokenFactory(GenericTokenFactoryInterface $genericTokenFactory = null): void
@@ -48,6 +63,13 @@ public function execute($request): void
4863

4964
$details = ArrayObject::ensureArrayObject($request->getModel());
5065

66+
if (isset($details['status']) && PayPlugApiClientInterface::FAILED === $details['status']) {
67+
// Unset current status to allow to use payplug to change payment method
68+
unset($details['status']);
69+
70+
return;
71+
}
72+
5173
if (isset($details['status'], $details['payment_id'])) {
5274
if (PayPlugApiClientInterface::STATUS_CREATED !== $details['status']) {
5375
return;
@@ -88,11 +110,28 @@ public function execute($request): void
88110
unset($details['status']);
89111
}
90112

91-
$payment = $this->createPayment($details);
113+
try {
114+
$payment = $this->createPayment($details);
115+
$details['status'] = PayPlugApiClientInterface::STATUS_CREATED;
116+
117+
throw new HttpRedirect($payment->hosted_payment->payment_url);
118+
} catch (BadRequestException $badRequestException) {
119+
$errorObject = $badRequestException->getErrorObject();
120+
if (null === $errorObject || [] === $errorObject) {
121+
$this->flashBag->add('error', 'payplug_sylius_payplug_plugin.error.api_unknow_error');
122+
123+
return;
124+
}
92125

93-
$details['status'] = PayPlugApiClientInterface::STATUS_CREATED;
126+
$this->notifyErrors($details, $errorObject);
94127

95-
throw new HttpRedirect($payment->hosted_payment->payment_url);
128+
throw new HttpRedirect($details['hosted_payment']['cancel_url']);
129+
} catch (UnknownApiErrorException $unknownApiErrorException) {
130+
$details['status'] = PayPlugApiClientInterface::FAILED;
131+
$this->flashBag->add('error', $this->translator->trans('payplug_sylius_payplug_plugin.error.api_unknow_error'));
132+
133+
throw new HttpRedirect($details['hosted_payment']['cancel_url']);
134+
}
96135
}
97136

98137
public function supports($request): bool
@@ -120,14 +159,58 @@ private function addNotificationUrl(TokenInterface $token, ArrayObject $details)
120159

121160
private function createPayment(ArrayObject $details): Payment
122161
{
123-
$payment = $this->payPlugApiClient->createPayment($details->getArrayCopy());
124-
$details['payment_id'] = $payment->id;
125-
$details['is_live'] = $payment->is_live;
162+
try {
163+
$payment = $this->payPlugApiClient->createPayment($details->getArrayCopy());
164+
$details['payment_id'] = $payment->id;
165+
$details['is_live'] = $payment->is_live;
166+
167+
$this->logger->debug('[PayPlug] Create payment', [
168+
'payment_id' => $payment->id,
169+
]);
170+
171+
return $payment;
172+
} catch (BadRequestException $badRequestException) {
173+
$details['status'] = PayPlugApiClientInterface::FAILED;
174+
175+
throw $badRequestException;
176+
} catch (\Throwable $throwable) {
177+
$details['status'] = PayPlugApiClientInterface::FAILED;
178+
179+
throw new UnknownApiErrorException(
180+
'payplug_sylius_payplug_plugin.error.api_unknow_error',
181+
$throwable->getCode(),
182+
$throwable,
183+
);
184+
}
185+
}
186+
187+
private function notifyErrors(ArrayObject $details, array $errorDetails): void
188+
{
189+
if (!isset($errorDetails['details'])) {
190+
return;
191+
}
192+
193+
if (isset($errorDetails['details']['billing']['postcode'])) {
194+
$this->flashBag->add(
195+
'error',
196+
$this->translator->trans('payplug_sylius_payplug_plugin.ui.error.billing.postcode', [
197+
'%postalCode%' => $details['billing']['postcode'],
198+
])
199+
);
200+
}
126201

127-
$this->logger->debug('[PayPlug] Create payment', [
128-
'payment_id' => $payment->id,
129-
]);
202+
if (isset($errorDetails['details']['shipping']['postcode'])) {
203+
$this->flashBag->add(
204+
'error',
205+
$this->translator->trans('payplug_sylius_payplug_plugin.ui.error.shipping.postcode', [
206+
'%postalCode%' => $details['shipping']['postcode'],
207+
])
208+
);
209+
}
130210

131-
return $payment;
211+
if (!isset($errorDetails['details']['billing']['postcode']) &&
212+
!isset($errorDetails['details']['shipping']['postcode'])) {
213+
$this->flashBag->add('error', 'payplug_sylius_payplug_plugin.error.api_unknow_error');
214+
}
132215
}
133216
}

src/Controller/AbstractOneyController.php

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@
55
namespace PayPlug\SyliusPayPlugPlugin\Controller;
66

77
use PayPlug\SyliusPayPlugPlugin\Provider\OneySimulation\OneySimulationDataProviderInterface;
8-
use PayPlug\SyliusPayPlugPlugin\Repository\ProductVariantRepository;
98
use PayPlug\SyliusPayPlugPlugin\Twig\OneyRulesExtension;
109
use Sylius\Bundle\CoreBundle\Doctrine\ORM\ProductRepository;
10+
use Sylius\Bundle\CoreBundle\Doctrine\ORM\ProductVariantRepository;
1111
use Sylius\Component\Core\Model\ChannelInterface;
1212
use Sylius\Component\Core\Model\ChannelPricingInterface;
1313
use Sylius\Component\Core\Model\OrderInterface;
1414
use Sylius\Component\Core\Model\OrderItemInterface;
15-
use Sylius\Component\Core\Model\ProductInterface;
1615
use Sylius\Component\Core\Model\ProductVariantInterface;
1716
use Sylius\Component\Order\Context\CartContextInterface;
1817
use Sylius\Component\Order\Modifier\OrderItemQuantityModifierInterface;
@@ -29,7 +28,7 @@ abstract class AbstractOneyController extends AbstractController
2928
/** @var CartContextInterface */
3029
protected $cartContext;
3130

32-
/** @var ProductVariantRepository */
31+
/** @var \Sylius\Bundle\CoreBundle\Doctrine\ORM\ProductVariantRepository */
3332
protected $productVariantRepository;
3433

3534
/** @var FactoryInterface */
@@ -72,26 +71,6 @@ public function __construct(
7271
$this->productRepository = $productRepository;
7372
}
7473

75-
protected function getProductVariant(string $productCode, ?string $productOptionValue): ?ProductVariantInterface
76-
{
77-
$product = $this->productRepository->findOneByCode($productCode);
78-
Assert::isInstanceOf($product, ProductInterface::class);
79-
80-
$firstVariant = $product->getEnabledVariants()->first();
81-
Assert::isInstanceOf($firstVariant, ProductVariantInterface::class);
82-
83-
if ($product->isSimple()) {
84-
return $firstVariant;
85-
}
86-
87-
Assert::notNull($productOptionValue);
88-
89-
return $this->productVariantRepository->findVariantByProductCodeAndProductOptionValue(
90-
$productCode,
91-
$productOptionValue
92-
);
93-
}
94-
9574
protected function createTempCart(
9675
ProductVariantInterface $productVariant,
9776
int $quantity,

src/Controller/CompleteInfoController.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Doctrine\ORM\EntityManagerInterface;
88
use PayPlug\SyliusPayPlugPlugin\Model\OneyCompleteInfoDTO;
99
use PayPlug\SyliusPayPlugPlugin\Validator\OneyInvalidDataRetriever;
10+
use Sylius\Component\Core\Model\CustomerInterface;
1011
use Sylius\Component\Core\Model\OrderInterface;
1112
use Sylius\Component\Order\Context\CartContextInterface;
1213
use Sylius\Component\Resource\Repository\RepositoryInterface;
@@ -101,7 +102,7 @@ private function handleEmail(OrderInterface $order, string $email): void
101102
{
102103
$customer = $this->customerRepository->findOneBy(['email' => $email]);
103104

104-
if (null !== $customer) {
105+
if ($customer instanceof CustomerInterface) {
105106
$order->setCustomer($customer);
106107

107108
return;

src/Controller/OneyIsProductEligible.php

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,24 @@ public function __invoke(Request $request): JsonResponse
1818
/** @var OrderInterface $cart */
1919
$cart = $this->cartContext->getCart();
2020

21-
$productCode = $request->get('product');
22-
Assert::notNull($productCode);
23-
24-
/** @var string|null $productOptionValue */
25-
$productOptionValue = $request->get('option');
21+
$productVariantCode = $request->get('product_variant_code');
22+
Assert::notNull($productVariantCode);
2623

2724
/** @var int|null $quantity */
2825
$quantity = (int) $request->get('quantity');
2926
Assert::notNull($quantity);
3027

3128
return new JsonResponse([
32-
'isEligible' => $this->isProductEligible($cart, $productCode, $quantity, $productOptionValue),
29+
'isEligible' => $this->isProductEligible($cart, $productVariantCode, $quantity),
3330
]);
3431
}
3532

3633
private function isProductEligible(
3734
OrderInterface $cart,
38-
string $productCode,
39-
int $quantity,
40-
?string $productOptionValue
35+
string $productVariantCode,
36+
int $quantity
4137
): bool {
42-
$productVariant = $this->getProductVariant($productCode, $productOptionValue);
38+
$productVariant = $this->productVariantRepository->findOneBy(['code' => $productVariantCode]);
4339
Assert::isInstanceOf($productVariant, ProductVariantInterface::class);
4440

4541
$channel = $cart->getChannel();

src/Controller/OneySimulationPopin.php

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,13 @@ public function __invoke(Request $request): Response
1818
/** @var OrderInterface $cart */
1919
$cart = $this->cartContext->getCart();
2020

21-
/** @var string|null $productCode */
22-
$productCode = $request->get('product');
23-
24-
/** @var string|null $productOptionValue */
25-
$productOptionValue = $request->get('option');
21+
/** @var string|null $productVariantCode */
22+
$productVariantCode = $request->get('product_variant_code');
2623

2724
/** @var int|null $quantity */
2825
$quantity = (int) $request->get('quantity');
2926

30-
if (null === $productCode || null === $quantity) {
27+
if (null === $productVariantCode || null === $quantity) {
3128
$simulationData = $this->oneySimulationDataProvider->getForCart($cart);
3229

3330
return $this->render(
@@ -39,16 +36,15 @@ public function __invoke(Request $request): Response
3936
);
4037
}
4138

42-
return $this->renderSimulateForProductVariant($cart, $productCode, $quantity, $productOptionValue);
39+
return $this->renderSimulateForProductVariant($cart, $productVariantCode, $quantity);
4340
}
4441

4542
private function renderSimulateForProductVariant(
4643
OrderInterface $cart,
47-
string $productCode,
48-
int $quantity,
49-
?string $productOptionValue
44+
string $productVariantCode,
45+
int $quantity
5046
): Response {
51-
$productVariant = $this->getProductVariant($productCode, $productOptionValue);
47+
$productVariant = $this->productVariantRepository->findOneBy(['code' => $productVariantCode]);
5248
Assert::isInstanceOf($productVariant, ProductVariantInterface::class);
5349

5450
$channel = $cart->getChannel();
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PayPlug\SyliusPayPlugPlugin\Exception;
6+
7+
class UnknownApiErrorException extends \Exception
8+
{
9+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
namespace PayPlug\SyliusPayPlugPlugin\Gateway\Form\Type;
4+
5+
use Sylius\Bundle\PayumBundle\Model\GatewayConfigInterface;
6+
use Sylius\Component\Resource\Repository\RepositoryInterface;
7+
use Symfony\Component\Form\AbstractType;
8+
use Symfony\Component\Form\FormError;
9+
use Symfony\Component\Form\FormInterface;
10+
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
11+
use Symfony\Contracts\Translation\TranslatorInterface;
12+
13+
class AbstractGatewayConfigurationType extends AbstractType
14+
{
15+
/** @var TranslatorInterface */
16+
protected $translator;
17+
18+
/** @var FlashBagInterface */
19+
protected $flashBag;
20+
/**
21+
* @var RepositoryInterface
22+
*/
23+
private $gatewayConfigRepository;
24+
25+
public function __construct(
26+
TranslatorInterface $translator,
27+
FlashBagInterface $flashBag,
28+
RepositoryInterface $gatewayConfigRepository
29+
) {
30+
$this->translator = $translator;
31+
$this->flashBag = $flashBag;
32+
$this->gatewayConfigRepository = $gatewayConfigRepository;
33+
}
34+
35+
protected function canBeCreated(string $factoryName): bool
36+
{
37+
$alreadyExists = $this->gatewayConfigRepository->findOneBy(['factoryName' => $factoryName]);
38+
39+
return !$alreadyExists instanceof GatewayConfigInterface;
40+
}
41+
42+
protected function checkCreationRequirements(
43+
string $factoryTitle,
44+
string $factoryName,
45+
FormInterface $form
46+
): void {
47+
/** @phpstan-ignore-next-line */
48+
$paymentMethod = $form->getParent()->getParent()->getData();
49+
50+
51+
if (null !== $paymentMethod->getId()) {
52+
return;
53+
}
54+
55+
if ($this->canBeCreated($factoryName)) {
56+
return;
57+
}
58+
59+
$message = $this->translator->trans('payplug_sylius_payplug_plugin.form.only_one_gateway_allowed', ['%gateway_title%' => $factoryTitle]);
60+
/** @phpstan-ignore-next-line */
61+
$form->getParent()->getParent()->get('enabled')->addError(new FormError($message));
62+
}
63+
}

0 commit comments

Comments
 (0)