Skip to content

Commit 1c2bcb1

Browse files
authored
Merge pull request #4299 from magento-epam/EPAM-PR-55
[epam] Bugfixes - fixed MAGETWO-94004 Magento Admin can not configure properly bundle/grouped/configurable product with shared catalog enabled and if they were added by sku to an order - fixed MAGETWO-97317 [Magento Cloud] price missing when adding product via API to previously emptied cart - fixed MAGETWO-80120 Magento\Framework\App\Test\Unit\BootstrapTest reset error handler to \Exception - fixed MAGETWO-70681 Store View name DB field is too short - fixed MAGETWO-36337 Not user-friendly behaviour of "Save in address book" check-box inside "Shipping Address" section on "create Order" Admin page
2 parents 553946c + 033cc31 commit 1c2bcb1

File tree

24 files changed

+699
-40
lines changed

24 files changed

+699
-40
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AdminOrderConfigureBundleProduct">
12+
<arguments>
13+
<argument name="productName" type="string" defaultValue="{{SimpleProduct.sku}}"/>
14+
<argument name="productNumber" type="string" defaultValue="1"/>
15+
<argument name="productQty" type="string" defaultValue="1"/>
16+
</arguments>
17+
<click selector="{{AdminOrderFormItemsOrderedSection.configureButtonBySku}}" stepKey="clickConfigure"/>
18+
<waitForPageLoad stepKey="waitForConfigurePageLoad"/>
19+
<checkOption selector="{{AdminOrderBundleProductSection.bundleProductCheckbox(productNumber)}}" stepKey="checkProduct"/>
20+
<fillField selector="{{AdminOrderFormConfigureProductSection.quantity}}" userInput="{{productQty}}" stepKey="fillProductQty"/>
21+
<click selector="{{AdminOrderFormConfigureProductSection.ok}}" stepKey="clickOk"/>
22+
</actionGroup>
23+
</actionGroups>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
11+
<section name="AdminOrderBundleProductSection">
12+
<element name="bundleProductCheckbox" type="checkbox" selector="(//input[contains(@class, 'admin__control-checkbox') and contains(@class, 'bundle-option')])[{{productNumber}}]" parameterized="true"/>
13+
</section>
14+
</sections>

app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,9 @@
240240
<requiredEntity type="product_extension_attribute">EavStockItem</requiredEntity>
241241
<requiredEntity type="custom_attribute">CustomAttributeProductAttribute</requiredEntity>
242242
</entity>
243+
<entity name="ApiSimpleProductWithShortSKU" type="product2" extends="ApiSimpleOne">
244+
<data key="sku" unique="suffix">pr</data>
245+
</entity>
243246
<entity name="ApiSimpleOneHidden" type="product2">
244247
<data key="sku" unique="suffix">api-simple-product</data>
245248
<data key="type_id">simple</data>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AdminOrderConfigureConfigurableProduct">
12+
<arguments>
13+
<argument name="optionName" type="string" defaultValue="option1"/>
14+
<argument name="productQty" type="string" defaultValue="1"/>
15+
</arguments>
16+
<click selector="{{AdminOrderFormItemsOrderedSection.configureButtonBySku}}" stepKey="clickConfigure"/>
17+
<waitForPageLoad stepKey="waitForConfigurePageLoad"/>
18+
<selectOption selector="{{AdminOrderFormConfigureProductSection.selectOption}}" userInput="{{optionName}}" stepKey="selectOption"/>
19+
<fillField selector="{{AdminOrderFormConfigureProductSection.quantity}}" userInput="{{productQty}}" stepKey="fillProductQty"/>
20+
<click selector="{{AdminOrderFormConfigureProductSection.ok}}" stepKey="clickOk"/>
21+
</actionGroup>
22+
</actionGroups>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AdminOrderConfigureGroupedProduct">
12+
<arguments>
13+
<argument name="productSku" type="string" defaultValue="{{SimpleProduct.sku}}"/>
14+
<argument name="productQty" type="string" defaultValue="1"/>
15+
</arguments>
16+
<click selector="{{AdminOrderFormItemsOrderedSection.configureButtonBySku}}" stepKey="clickConfigure"/>
17+
<waitForPageLoad stepKey="waitForConfigurePageLoad"/>
18+
<fillField selector="{{AdminOrderFormGroupedProductSection.optionQty(productSku)}}" userInput="{{productQty}}" stepKey="fillOptionQuantity"/>
19+
<click selector="{{AdminOrderFormConfigureProductSection.ok}}" stepKey="clickOk"/>
20+
</actionGroup>
21+
</actionGroups>

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']);

0 commit comments

Comments
 (0)