Skip to content

Commit f4769fb

Browse files
author
Jan Polak
committed
Customer can choose credit card for oto
1 parent 244f62d commit f4769fb

File tree

10 files changed

+196
-16
lines changed

10 files changed

+196
-16
lines changed

app/code/Magento/OneTouchOrdering/Controller/Button/Available.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Magento\Framework\Controller\ResultFactory;
1212
use Magento\OneTouchOrdering\Model\Config;
1313
use Magento\OneTouchOrdering\Model\CustomerAddressesFormatter;
14+
use Magento\OneTouchOrdering\Model\CustomerCardsFormatter;
1415
use Magento\OneTouchOrdering\Model\OneTouchOrdering;
1516
use Magento\Customer\Model\Session;
1617

@@ -27,24 +28,30 @@ class Available extends Action
2728
/**
2829
* @var CustomerAddressesFormatter
2930
*/
30-
private $customerAddressesFormater;
31+
private $customerAddressesFormatter;
3132
/**
3233
* @var Config
3334
*/
3435
private $oneTouchOrderingConfig;
36+
/**
37+
* @var CustomerCardsFormatter
38+
*/
39+
private $customerCardsFormatter;
3540

3641
public function __construct(
3742
Context $context,
3843
OneTouchOrdering $oneTouchOrdering,
3944
Session $customerSession,
40-
CustomerAddressesFormatter $customerAddressesFormater,
45+
CustomerAddressesFormatter $customerAddressesFormatter,
46+
CustomerCardsFormatter $customerCardsFormatter,
4147
Config $oneTouchOrderingConfig
4248
) {
4349
parent::__construct($context);
4450
$this->oneTouchOrdering = $oneTouchOrdering;
4551
$this->customerSession = $customerSession;
46-
$this->customerAddressesFormater = $customerAddressesFormater;
52+
$this->customerAddressesFormatter = $customerAddressesFormatter;
4753
$this->oneTouchOrderingConfig = $oneTouchOrderingConfig;
54+
$this->customerCardsFormatter = $customerCardsFormatter;
4855
}
4956

5057
public function execute()
@@ -59,9 +66,10 @@ public function execute()
5966
$customer = $this->customerSession->getCustomer();
6067
$available = $this->oneTouchOrdering->isAvailableForCustomer($customer);
6168
$resultData['available'] = $available;
69+
$resultData['cards'] = $this->customerCardsFormatter->getFormattedCards($customer);
6270
if ($this->oneTouchOrderingConfig->isSelectAddressEnabled()) {
6371
$resultData += [
64-
'addresses' => $this->customerAddressesFormater->getFormattedAddresses($customer),
72+
'addresses' => $this->customerAddressesFormatter->getFormattedAddresses($customer),
6573
'defaultAddress' => $customer->getDefaultShippingAddress()->getId()
6674
];
6775
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\OneTouchOrdering\Model;
7+
8+
use Magento\Customer\Model\Customer;
9+
10+
class CustomerCardsFormatter
11+
{
12+
public static $baseCardTypes = [
13+
'AE' => 'American Express',
14+
'VI' => 'Visa',
15+
'MC' => 'MasterCard',
16+
'DI' => 'Discover',
17+
'JBC' => 'JBC',
18+
'CUP' => 'China Union Pay',
19+
'MI' => 'Maestro',
20+
];
21+
22+
/**
23+
* @var CustomerCreditCardManager
24+
*/
25+
private $customerCreditCardManager;
26+
27+
/**
28+
* CustomerCardsFormatter constructor.
29+
* @param CustomerCreditCardManager $customerCreditCardManager
30+
*/
31+
public function __construct(
32+
CustomerCreditCardManager $customerCreditCardManager
33+
) {
34+
$this->customerCreditCardManager = $customerCreditCardManager;
35+
}
36+
37+
/**
38+
* @param Customer $customer
39+
* @return array
40+
*/
41+
public function getFormattedCards(Customer $customer): array
42+
{
43+
$cardsFormatted = [];
44+
$customerCc = $this->customerCreditCardManager->getVisibleAvailableTokens($customer->getId());
45+
foreach ($customerCc as $cc) {
46+
$cardsFormatted[] = [
47+
'card' => $this->formatCc($cc),
48+
'id' => $cc->getEntityId()
49+
];
50+
}
51+
52+
return $cardsFormatted;
53+
}
54+
55+
/**
56+
* @param \Magento\Vault\Api\Data\PaymentTokenInterface $cc
57+
* @return string
58+
*/
59+
private function formatCc(\Magento\Vault\Api\Data\PaymentTokenInterface $cc): string
60+
{
61+
$details = json_decode($cc->getTokenDetails(), true);
62+
return sprintf(
63+
'%s: %s, %s: %s (%s: %s)',
64+
_('Type'),
65+
self::$baseCardTypes[$details['type']],
66+
__('ending'),
67+
$details['maskedCC'],
68+
_('expires'),
69+
$details['expirationDate']
70+
);
71+
}
72+
}

app/code/Magento/OneTouchOrdering/Model/CustomerCreditCardManager.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,16 @@ public function __construct(
6161
* @return \Magento\Vault\Api\Data\PaymentTokenInterface
6262
* @throws LocalizedException
6363
*/
64-
public function getCustomerCreditCard($customerId)
64+
public function getCustomerCreditCard($customerId, $cardId)
6565
{
6666
$tokens = $this->getVisibleAvailableTokens($customerId);
67-
if (empty($tokens)) {
67+
if (empty($tokens) || !$cardId ||!isset($tokens[$cardId])) {
6868
throw new LocalizedException(
6969
__('There are no credit cards available.')
7070
);
7171
}
7272

73-
return array_shift($tokens);
73+
return $tokens[$cardId];
7474
}
7575

7676
/**

app/code/Magento/OneTouchOrdering/Model/PlaceOrder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public function placeOrder(Product $product, CustomerData $customerData, array $
6868
$quote = $this->prepareQuote->prepare($customerData, $paramsObject);
6969
$quote->addProduct($product, $paramsObject);
7070
$this->shippingRateChooser->choose($quote);
71-
$this->prepareQuote->preparePayment($quote, $customerData->getCustomerId());
71+
$this->prepareQuote->preparePayment($quote, $customerData->getCustomerId(), $paramsObject->getCustomerCc());
7272
$this->quoteRepository->save($quote);
7373
return $this->cartManagementInterface->placeOrder($quote->getId());
7474
}

app/code/Magento/OneTouchOrdering/Model/PrepareQuote.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@ public function prepare(CustomerData $customerData, DataObject $params): Quote
7878
* @param Quote $quote
7979
* @throws Exception
8080
*/
81-
public function preparePayment(Quote $quote, $customerId)
81+
public function preparePayment(Quote $quote, $customerId, $ccId)
8282
{
83-
$cc = $this->customerCreditCardManager->getCustomerCreditCard($customerId);
83+
$cc = $this->customerCreditCardManager->getCustomerCreditCard($customerId, $ccId);
8484
$publicHash = $cc->getPublicHash();
8585
$quote->getPayment()->setQuote($quote)->importData(
8686
['method' => BrainTreeConfigProvider::CC_VAULT_CODE]
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: jpolak
5+
* Date: 9/21/17
6+
* Time: 2:16 PM
7+
*/
8+
9+
namespace Magento\OneTouchOrdering\Test\Unit\Model;
10+
11+
use Magento\Customer\Model\Customer;
12+
use Magento\OneTouchOrdering\Model\CustomerCardsFormatter;
13+
use Magento\OneTouchOrdering\Model\CustomerCreditCardManager;
14+
use PHPUnit\Framework\TestCase;
15+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
16+
17+
class CustomerCardsFormatterTest extends TestCase
18+
{
19+
/**
20+
* @var \PHPUnit_Framework_MockObject_MockObject
21+
*/
22+
private $cardToken;
23+
/**
24+
* @var \PHPUnit_Framework_MockObject_MockObject
25+
*/
26+
private $customerCreditCardManager;
27+
/**
28+
* @var \PHPUnit_Framework_MockObject_MockObject|Customer
29+
*/
30+
private $customer;
31+
/**
32+
* @var CustomerCardsFormatter
33+
*/
34+
private $customerCards;
35+
36+
public function setUp()
37+
{
38+
$objectManager = new ObjectManager($this);
39+
$this->cardToken = $this->createMock(\Magento\Vault\Api\Data\PaymentTokenInterface::class);
40+
$this->customerCreditCardManager = $this->createMock(CustomerCreditCardManager::class);
41+
$this->customer = $this->createMock(Customer::class);
42+
$this->customerCards = $objectManager->getObject(
43+
CustomerCardsFormatter::class,
44+
[
45+
'customerCreditCardManager' => $this->customerCreditCardManager
46+
]
47+
);
48+
}
49+
50+
public function testGetFormattedCards()
51+
{
52+
$cardId = 2;
53+
$customerId = 321;
54+
$cardDetails = '{"type": "VI", "maskedCC": "1234", "expirationDate": "12/20"}';
55+
$cardFormatted = 'Type: Visa, ending: 1234 (expires: 12/20)';
56+
57+
$this->customerCreditCardManager
58+
->expects($this->once())
59+
->method('getVisibleAvailableTokens')
60+
->with($customerId)
61+
->willReturn([$cardId => $this->cardToken]);
62+
63+
$this->customer->expects($this->once())->method('getId')->willReturn($customerId);
64+
$this->cardToken->expects($this->once())->method('getTokenDetails')->willReturn($cardDetails);
65+
$this->cardToken->expects($this->once())->method('getEntityId')->willReturn($cardId);
66+
67+
$result = $this->customerCards->getFormattedCards($this->customer);
68+
$this->assertSame($result[0]['card'], $cardFormatted);
69+
$this->assertSame($result[0]['id'], $cardId);
70+
}
71+
}

app/code/Magento/OneTouchOrdering/Test/Unit/Model/CustomerCreditCardManagerTest.php

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public function setUp()
7373
public function testGetVisibleAvailableTokens()
7474
{
7575
$customerId = 21;
76-
76+
$ccId = 2;
7777
$this->filterBuilder->method('setField')->withConsecutive($this->logicalOr(
7878
[\Magento\Vault\Api\Data\PaymentTokenInterface::CUSTOMER_ID],
7979
[\Magento\Vault\Api\Data\PaymentTokenInterface::IS_VISIBLE],
@@ -104,10 +104,10 @@ public function testGetVisibleAvailableTokens()
104104
$paymentTokenSearchResult = $this->getMockForAbstractClass(
105105
\Magento\Vault\Api\Data\PaymentTokenSearchResultsInterface::class
106106
);
107-
$paymentTokenSearchResult->method('getItems')->willReturn([true]);
107+
$paymentTokenSearchResult->method('getItems')->willReturn([$ccId => true]);
108108
$this->paymentTokenRepository->method('getList')->willReturn($paymentTokenSearchResult);
109109

110-
$result = $this->customerCreditCardManager->getCustomerCreditCard($customerId);
110+
$result = $this->customerCreditCardManager->getCustomerCreditCard($customerId, $ccId);
111111
$this->assertTrue($result);
112112
}
113113

@@ -122,6 +122,20 @@ public function testGetCustomerCreditCardNoCC()
122122
$this->paymentTokenRepository->method('getList')->willReturn($paymentTokenSearchResult);
123123
$this->expectException(LocalizedException::class);
124124

125-
$this->customerCreditCardManager->getCustomerCreditCard($customerId);
125+
$this->customerCreditCardManager->getCustomerCreditCard($customerId, 2);
126+
}
127+
128+
public function testGetCustomerCreditCardNoRequestedCC()
129+
{
130+
$customerId = 21;
131+
132+
$paymentTokenSearchResult = $this->getMockForAbstractClass(
133+
\Magento\Vault\Api\Data\PaymentTokenSearchResultsInterface::class
134+
);
135+
$paymentTokenSearchResult->method('getItems')->willReturn([3 => true]);
136+
$this->paymentTokenRepository->method('getList')->willReturn($paymentTokenSearchResult);
137+
$this->expectException(LocalizedException::class);
138+
139+
$this->customerCreditCardManager->getCustomerCreditCard($customerId, 2);
126140
}
127141
}

app/code/Magento/OneTouchOrdering/Test/Unit/Model/PrepareQuotePaymentTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public function setUp()
5858
public function testPreparePayment()
5959
{
6060
$customerId = 32;
61+
$ccId = 2;
6162
$publicHash = '123456789';
6263
$nonce = '987654321';
6364

@@ -88,7 +89,7 @@ public function testPreparePayment()
8889
->with($publicHash, $customerId)
8990
->willReturn($nonce);
9091
$this->quote->expects($this->once())->method('collectTotals');
91-
$this->prepareQuote->preparePayment($this->quote, $customerId);
92+
$this->prepareQuote->preparePayment($this->quote, $customerId, $ccId);
9293

9394
$this->assertArraySubset($paymentAdditionalInformation, $payment->getAdditionalInformation());
9495
}

app/code/Magento/OneTouchOrdering/view/frontend/web/js/view/one-touch-order.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ define(
3030
message: $.mage.__('Are you sure you want to place order and pay?'),
3131
formSelector: '#product_addtocart_form',
3232
addresses: ko.observable([]),
33+
cards: ko.observable([]),
3334
defaultAddress: ko.observable(0)
3435
},
3536

@@ -43,10 +44,14 @@ define(
4344
self.showButton(data.available);
4445
}
4546

46-
if(typeof data.addresses !== 'undefined' && typeof data.defaultAddress !== 'undefined') {
47+
if (typeof data.addresses !== 'undefined' && typeof data.defaultAddress !== 'undefined') {
4748
self.options.addresses(data.addresses);
4849
self.options.defaultAddress(data.defaultAddress);
4950
}
51+
52+
if (typeof data.cards !== 'undefined') {
53+
self.options.cards(data.cards);
54+
}
5055
});
5156
},
5257

app/code/Magento/OneTouchOrdering/view/frontend/web/template/one-touch-order.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,13 @@
1515
</div>
1616
<!-- /ko -->
1717

18+
<!-- ko if: options.cards().length > 0 -->
19+
<div class="field">
20+
<label for="address-selector"><!-- ko i18n: 'Select credit card' --><!-- /ko -->:</label>
21+
<select name="customer_cc" id="cc-selector"
22+
data-bind="options: options.cards, optionsText: 'card', optionsValue: 'id'">
23+
</select>
24+
</div>
25+
<!-- /ko -->
26+
1827
<!-- /ko -->

0 commit comments

Comments
 (0)