Skip to content

Commit 3d8a513

Browse files
Merge remote-tracking branch 'remotes/github/MAGETWO-97317' into EPAM-PR-55
2 parents 4203618 + 0b24157 commit 3d8a513

File tree

10 files changed

+502
-35
lines changed

10 files changed

+502
-35
lines changed

app/code/Magento/Quote/Model/QuoteManagement.php

Lines changed: 59 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
67

78
namespace Magento\Quote\Model;
89

@@ -267,6 +268,8 @@ public function createEmptyCartForCustomer($customerId)
267268
$storeId = $this->storeManager->getStore()->getStoreId();
268269
$quote = $this->createCustomerCart($customerId, $storeId);
269270

271+
$this->_prepareCustomerQuote($quote);
272+
270273
try {
271274
$this->quoteRepository->save($quote);
272275
} catch (\Exception $e) {
@@ -569,7 +572,7 @@ protected function submitQuote(QuoteEntity $quote, $orderData = [])
569572
}
570573

571574
/**
572-
* Prepare quote for customer order submit
575+
* Prepare address for customer quote.
573576
*
574577
* @param Quote $quote
575578
* @return void
@@ -589,41 +592,69 @@ protected function _prepareCustomerQuote($quote)
589592
if ($shipping && !$shipping->getSameAsBilling()
590593
&& (!$shipping->getCustomerId() || $shipping->getSaveInAddressBook())
591594
) {
592-
$shippingAddress = $shipping->exportCustomerAddress();
593-
if (!$hasDefaultShipping) {
594-
//Make provided address as default shipping address
595-
$shippingAddress->setIsDefaultShipping(true);
596-
$hasDefaultShipping = true;
597-
if (!$hasDefaultBilling && !$billing->getSaveInAddressBook()) {
598-
$shippingAddress->setIsDefaultBilling(true);
599-
$hasDefaultBilling = true;
595+
if ($shipping->getQuoteId()) {
596+
$shippingAddress = $shipping->exportCustomerAddress();
597+
} else {
598+
$defaultShipping = $this->customerRepository->getById($customer->getId())->getDefaultShipping();
599+
if ($defaultShipping) {
600+
try {
601+
$shippingAddress = $this->addressRepository->getById($defaultShipping);
602+
// phpcs:ignore Magento2.CodeAnalysis.EmptyBlock
603+
} catch (LocalizedException $e) {
604+
// no address
605+
}
606+
}
607+
}
608+
if (isset($shippingAddress)) {
609+
if (!$hasDefaultShipping) {
610+
//Make provided address as default shipping address
611+
$shippingAddress->setIsDefaultShipping(true);
612+
$hasDefaultShipping = true;
613+
if (!$hasDefaultBilling && !$billing->getSaveInAddressBook()) {
614+
$shippingAddress->setIsDefaultBilling(true);
615+
$hasDefaultBilling = true;
616+
}
600617
}
618+
//save here new customer address
619+
$shippingAddress->setCustomerId($quote->getCustomerId());
620+
$this->addressRepository->save($shippingAddress);
621+
$quote->addCustomerAddress($shippingAddress);
622+
$shipping->setCustomerAddressData($shippingAddress);
623+
$this->addressesToSync[] = $shippingAddress->getId();
624+
$shipping->setCustomerAddressId($shippingAddress->getId());
601625
}
602-
//save here new customer address
603-
$shippingAddress->setCustomerId($quote->getCustomerId());
604-
$this->addressRepository->save($shippingAddress);
605-
$quote->addCustomerAddress($shippingAddress);
606-
$shipping->setCustomerAddressData($shippingAddress);
607-
$this->addressesToSync[] = $shippingAddress->getId();
608-
$shipping->setCustomerAddressId($shippingAddress->getId());
609626
}
610627

611628
if (!$billing->getCustomerId() || $billing->getSaveInAddressBook()) {
612-
$billingAddress = $billing->exportCustomerAddress();
613-
if (!$hasDefaultBilling) {
614-
//Make provided address as default shipping address
615-
if (!$hasDefaultShipping) {
629+
if ($billing->getQuoteId()) {
630+
$billingAddress = $billing->exportCustomerAddress();
631+
} else {
632+
$defaultBilling = $this->customerRepository->getById($customer->getId())->getDefaultBilling();
633+
if ($defaultBilling) {
634+
try {
635+
$billingAddress = $this->addressRepository->getById($defaultBilling);
636+
// phpcs:ignore Magento2.CodeAnalysis.EmptyBlock
637+
} catch (LocalizedException $e) {
638+
// no address
639+
}
640+
}
641+
}
642+
if (isset($billingAddress)) {
643+
if (!$hasDefaultBilling) {
616644
//Make provided address as default shipping address
617-
$billingAddress->setIsDefaultShipping(true);
645+
if (!$hasDefaultShipping) {
646+
//Make provided address as default shipping address
647+
$billingAddress->setIsDefaultShipping(true);
648+
}
649+
$billingAddress->setIsDefaultBilling(true);
618650
}
619-
$billingAddress->setIsDefaultBilling(true);
651+
$billingAddress->setCustomerId($quote->getCustomerId());
652+
$this->addressRepository->save($billingAddress);
653+
$quote->addCustomerAddress($billingAddress);
654+
$billing->setCustomerAddressData($billingAddress);
655+
$this->addressesToSync[] = $billingAddress->getId();
656+
$billing->setCustomerAddressId($billingAddress->getId());
620657
}
621-
$billingAddress->setCustomerId($quote->getCustomerId());
622-
$this->addressRepository->save($billingAddress);
623-
$quote->addCustomerAddress($billingAddress);
624-
$billing->setCustomerAddressData($billingAddress);
625-
$this->addressesToSync[] = $billingAddress->getId();
626-
$billing->setCustomerAddressId($billingAddress->getId());
627658
}
628659
if ($shipping && !$shipping->getCustomerId() && !$hasDefaultBilling) {
629660
$shipping->setIsDefaultBilling(true);

app/code/Magento/Quote/Model/QuoteRepository/SaveHandler.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,20 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\Quote\Model\QuoteRepository;
79

810
use Magento\Quote\Api\Data\CartInterface;
911
use Magento\Customer\Api\AddressRepositoryInterface;
1012
use Magento\Framework\App\ObjectManager;
1113
use Magento\Framework\Exception\NoSuchEntityException;
1214
use Magento\Framework\Exception\InputException;
15+
use Magento\Quote\Api\Data\AddressInterfaceFactory;
1316

17+
/**
18+
* Handler for saving quote.
19+
*/
1420
class SaveHandler
1521
{
1622
/**
@@ -38,26 +44,35 @@ class SaveHandler
3844
*/
3945
private $addressRepository;
4046

47+
/**
48+
* @var AddressInterfaceFactory
49+
*/
50+
private $quoteAddressFactory;
51+
4152
/**
4253
* @param \Magento\Quote\Model\ResourceModel\Quote $quoteResource
4354
* @param \Magento\Quote\Model\Quote\Item\CartItemPersister $cartItemPersister
4455
* @param \Magento\Quote\Model\Quote\Address\BillingAddressPersister $billingAddressPersister
4556
* @param \Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentPersister $shippingAssignmentPersister
4657
* @param AddressRepositoryInterface $addressRepository
58+
* @param AddressInterfaceFactory|null $addressFactory
4759
*/
4860
public function __construct(
4961
\Magento\Quote\Model\ResourceModel\Quote $quoteResource,
5062
\Magento\Quote\Model\Quote\Item\CartItemPersister $cartItemPersister,
5163
\Magento\Quote\Model\Quote\Address\BillingAddressPersister $billingAddressPersister,
5264
\Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentPersister $shippingAssignmentPersister,
53-
AddressRepositoryInterface $addressRepository = null
65+
AddressRepositoryInterface $addressRepository = null,
66+
AddressInterfaceFactory $addressFactory = null
5467
) {
5568
$this->quoteResourceModel = $quoteResource;
5669
$this->cartItemPersister = $cartItemPersister;
5770
$this->billingAddressPersister = $billingAddressPersister;
5871
$this->shippingAssignmentPersister = $shippingAssignmentPersister;
5972
$this->addressRepository = $addressRepository
6073
?: ObjectManager::getInstance()->get(AddressRepositoryInterface::class);
74+
$this->quoteAddressFactory = $addressFactory ?:ObjectManager::getInstance()
75+
->get(AddressInterfaceFactory::class);
6176
}
6277

6378
/**
@@ -80,6 +95,9 @@ public function save(CartInterface $quote)
8095
/** @var \Magento\Quote\Model\Quote\Item $item */
8196
if (!$item->isDeleted()) {
8297
$quote->setLastAddedItem($this->cartItemPersister->save($quote, $item));
98+
} elseif (count($items) === 1) {
99+
$quote->setBillingAddress($this->quoteAddressFactory->create());
100+
$quote->setShippingAddress($this->quoteAddressFactory->create());
83101
}
84102
}
85103
}

app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
67

78
namespace Magento\Quote\Test\Unit\Model;
89

@@ -312,13 +313,23 @@ public function testCreateEmptyCartForCustomer()
312313
->method('getActiveForCustomer')
313314
->with($userId)
314315
->willThrowException(new NoSuchEntityException());
316+
$customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)
317+
->setMethods(['getDefaultBilling'])->disableOriginalConstructor()->getMockForAbstractClass();
318+
$quoteAddress = $this->createPartialMock(
319+
\Magento\Quote\Model\Quote\Address::class,
320+
['getCustomerId']
321+
);
322+
$quoteAddress->expects($this->atLeastOnce())->method('getCustomerId')->willReturn(567);
323+
$quoteMock->expects($this->atLeastOnce())->method('getBillingAddress')->willReturn($quoteAddress);
315324

316325
$this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($quoteMock);
317326
$quoteMock->expects($this->any())->method('setStoreId')->with($storeId);
318327
$quoteMock->expects($this->any())->method('setCustomerIsGuest')->with(0);
319328

320329
$this->quoteRepositoryMock->expects($this->once())->method('save')->with($quoteMock);
321330
$quoteMock->expects($this->once())->method('getId')->willReturn($quoteId);
331+
$this->customerRepositoryMock->expects($this->atLeastOnce())->method('getById')->willReturn($customer);
332+
$customer->expects($this->atLeastOnce())->method('getDefaultBilling')->willReturn(0);
322333

323334
$this->storeManagerMock->expects($this->once())->method('getStore')->willReturnSelf();
324335
$this->storeManagerMock->expects($this->once())->method('getStoreId')->willReturn($storeId);
@@ -338,6 +349,17 @@ public function testCreateEmptyCartForCustomerReturnExistsQuote()
338349
->method('getActiveForCustomer')
339350
->with($userId)->willReturn($quoteMock);
340351

352+
$customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)
353+
->setMethods(['getDefaultBilling'])->disableOriginalConstructor()->getMockForAbstractClass();
354+
$quoteAddress = $this->createPartialMock(
355+
\Magento\Quote\Model\Quote\Address::class,
356+
['getCustomerId']
357+
);
358+
$quoteAddress->expects($this->atLeastOnce())->method('getCustomerId')->willReturn(567);
359+
$quoteMock->expects($this->atLeastOnce())->method('getBillingAddress')->willReturn($quoteAddress);
360+
$this->customerRepositoryMock->expects($this->atLeastOnce())->method('getById')->willReturn($customer);
361+
$customer->expects($this->atLeastOnce())->method('getDefaultBilling')->willReturn(0);
362+
341363
$this->quoteFactoryMock->expects($this->never())->method('create')->willReturn($quoteMock);
342364
$this->quoteRepositoryMock->expects($this->once())->method('save')->with($quoteMock);
343365

@@ -569,7 +591,10 @@ public function testSubmit()
569591
$quoteId = 1;
570592
$quoteItem = $this->createMock(\Magento\Quote\Model\Quote\Item::class);
571593
$billingAddress = $this->createMock(\Magento\Quote\Model\Quote\Address::class);
572-
$shippingAddress = $this->createMock(\Magento\Quote\Model\Quote\Address::class);
594+
$shippingAddress = $this->createPartialMock(
595+
\Magento\Quote\Model\Quote\Address::class,
596+
['getQuoteId', 'getShippingMethod', 'getId']
597+
);
573598
$payment = $this->createMock(\Magento\Quote\Model\Quote\Payment::class);
574599
$baseOrder = $this->createMock(\Magento\Sales\Api\Data\OrderInterface::class);
575600
$convertedBilling = $this->createPartialMockForAbstractClass(OrderAddressInterface::class, ['setData']);
@@ -893,6 +918,7 @@ protected function getQuote(
893918
$quote->expects($this->any())
894919
->method('getShippingAddress')
895920
->willReturn($shippingAddress);
921+
$shippingAddress->expects($this->any())->method('getQuoteId')->willReturn($id);
896922
}
897923
$quote->expects($this->any())
898924
->method('getBillingAddress')
@@ -1037,7 +1063,9 @@ protected function setPropertyValue(&$object, $property, $value)
10371063
}
10381064

10391065
/**
1040-
* @throws \Magento\Framework\Exception\LocalizedException
1066+
* Test submit for customer
1067+
*
1068+
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
10411069
*/
10421070
public function testSubmitForCustomer()
10431071
{
@@ -1048,7 +1076,10 @@ public function testSubmitForCustomer()
10481076
$quoteId = 1;
10491077
$quoteItem = $this->createMock(\Magento\Quote\Model\Quote\Item::class);
10501078
$billingAddress = $this->createMock(\Magento\Quote\Model\Quote\Address::class);
1051-
$shippingAddress = $this->createMock(\Magento\Quote\Model\Quote\Address::class);
1079+
$shippingAddress = $this->createPartialMock(
1080+
\Magento\Quote\Model\Quote\Address::class,
1081+
['getQuoteId', 'getShippingMethod', 'getId', 'exportCustomerAddress']
1082+
);
10521083
$payment = $this->createMock(\Magento\Quote\Model\Quote\Payment::class);
10531084
$baseOrder = $this->createMock(\Magento\Sales\Api\Data\OrderInterface::class);
10541085
$convertedBilling = $this->createPartialMockForAbstractClass(OrderAddressInterface::class, ['setData']);
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Quote\Api;
9+
10+
use Magento\TestFramework\TestCase\WebapiAbstract;
11+
12+
/**
13+
* Class for payment info in quote for registered customer.
14+
*/
15+
class CartAddingItemsTest extends WebapiAbstract
16+
{
17+
/**
18+
* @var \Magento\TestFramework\ObjectManager
19+
*/
20+
protected $objectManager;
21+
22+
protected function setUp()
23+
{
24+
$this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
25+
}
26+
27+
/**
28+
* Test price for cart after adding product to.
29+
*
30+
* @magentoApiDataFixture Magento/Catalog/_files/product_without_options_with_stock_data.php
31+
* @magentoApiDataFixture Magento/Customer/_files/customer_one_address.php
32+
* @return void
33+
*/
34+
public function testPriceForCreatingQuoteFromEmptyCart()
35+
{
36+
$this->_markTestAsRestOnly();
37+
38+
// Get customer ID token
39+
/** @var \Magento\Integration\Api\CustomerTokenServiceInterface $customerTokenService */
40+
$customerTokenService = $this->objectManager->create(
41+
\Magento\Integration\Api\CustomerTokenServiceInterface::class
42+
);
43+
$token = $customerTokenService->createCustomerAccessToken(
44+
'customer_one_address@test.com',
45+
'password'
46+
);
47+
48+
// Creating empty cart for registered customer.
49+
$serviceInfo = [
50+
'rest' => [
51+
'resourcePath' => '/V1/carts/mine',
52+
'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
53+
'token' => $token
54+
]
55+
];
56+
57+
$quoteId = $this->_webApiCall($serviceInfo, ['customerId' => 999]); // customerId 999 will get overridden
58+
$this->assertGreaterThan(0, $quoteId);
59+
60+
// Adding item to the cart
61+
$serviceInfoForAddingProduct = [
62+
'rest' => [
63+
'resourcePath' => '/V1/carts/mine/items',
64+
'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
65+
'token' => $token
66+
]
67+
];
68+
$requestData = [
69+
'cartItem' => [
70+
'quote_id' => $quoteId,
71+
'sku' => 'simple',
72+
'qty' => 1
73+
]
74+
];
75+
$item = $this->_webApiCall($serviceInfoForAddingProduct, $requestData);
76+
$this->assertNotEmpty($item);
77+
$this->assertEquals(10, $item['price']);
78+
79+
// Get payment information
80+
$serviceInfoForGettingPaymentInfo = [
81+
'rest' => [
82+
'resourcePath' => '/V1/carts/mine/payment-information',
83+
'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
84+
'token' => $token
85+
]
86+
];
87+
$paymentInfo = $this->_webApiCall($serviceInfoForGettingPaymentInfo);
88+
$this->assertEquals($paymentInfo['totals']['grand_total'], 10);
89+
90+
/** @var \Magento\Quote\Model\Quote $quote */
91+
$quote = $this->objectManager->create(\Magento\Quote\Model\Quote::class);
92+
$quote->load($quoteId);
93+
$quote->delete();
94+
}
95+
}

0 commit comments

Comments
 (0)