Skip to content

Commit b8ec1a3

Browse files
MC-38498: "Save to Address Book" in Admin checkout causes duplicate address book entries
1 parent 0f9ac99 commit b8ec1a3

File tree

4 files changed

+164
-20
lines changed

4 files changed

+164
-20
lines changed

app/code/Magento/Sales/ViewModel/Customer/Address/Billing/Address.php renamed to app/code/Magento/Sales/ViewModel/Customer/Address/Billing/AddressDataProvider.php

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,16 @@
99

1010
use Magento\Framework\View\Element\Block\ArgumentInterface;
1111
use Magento\Sales\Model\AdminOrder\Create;
12-
use Magento\Quote\Model\Quote\Address as QuoteAddress;
1312

1413
/**
15-
* Customer address formatter
14+
* Customer billing address data provider
1615
*/
17-
class Address implements ArgumentInterface
16+
class AddressDataProvider implements ArgumentInterface
1817
{
1918
/**
2019
* @var Create
2120
*/
22-
protected $orderCreate;
21+
private $orderCreate;
2322

2423
/**
2524
* Customer billing address
@@ -32,23 +31,13 @@ public function __construct(
3231
$this->orderCreate = $orderCreate;
3332
}
3433

35-
/**
36-
* Return billing address object
37-
*
38-
* @return QuoteAddress
39-
*/
40-
public function getAddress(): QuoteAddress
41-
{
42-
return $this->orderCreate->getBillingAddress();
43-
}
44-
4534
/**
4635
* Get save billing address in the address book
4736
*
4837
* @return int
4938
*/
5039
public function getSaveInAddressBook(): int
5140
{
52-
return (int)$this->getAddress()->getSaveInAddressBook();
41+
return (int)$this->orderCreate->getBillingAddress()->getSaveInAddressBook();
5342
}
5443
}

app/code/Magento/Sales/view/adminhtml/layout/sales_order_create_load_block_billing_address.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<arguments>
1313
<argument name="customerAddressFormatter" xsi:type="object">Magento\Sales\ViewModel\Customer\AddressFormatter</argument>
1414
<argument name="customerAddressCollection" xsi:type="object">Magento\Customer\Model\ResourceModel\Address\Collection</argument>
15-
<argument name="customerBillingAddress" xsi:type="object">Magento\Sales\ViewModel\Customer\Address\Billing\Address</argument>
15+
<argument name="billingAddressDataProvider" xsi:type="object">Magento\Sales\ViewModel\Customer\Address\Billing\AddressDataProvider</argument>
1616
</arguments>
1717
</block>
1818
</referenceContainer>

app/code/Magento/Sales/view/adminhtml/templates/order/create/form/address.phtml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ endif;
2525
$customerAddressFormatter = $block->getData('customerAddressFormatter');
2626

2727
/**
28-
* @var \Magento\Sales\ViewModel\Customer\Address\Billing\Address $billingAddress
28+
* @var \Magento\Sales\ViewModel\Customer\Address\Billing\AddressDataProvider $billingAddressDataProvider
2929
*/
30-
$billingAddress = $block->getData('customerBillingAddress');
30+
$billingAddressDataProvider = $block->getData('billingAddressDataProvider');
3131

3232
/**
3333
* @var \Magento\Sales\Block\Adminhtml\Order\Create\Billing\Address|
@@ -119,9 +119,11 @@ endif; ?>
119119
type="checkbox"
120120
id="<?= $block->escapeHtmlAttr($block->getForm()->getHtmlIdPrefix()) ?>save_in_address_book"
121121
value="1"
122-
<?php if ($billingAddress && $billingAddress->getSaveInAddressBook()): ?>
122+
<?php if ($billingAddressDataProvider && $billingAddressDataProvider->getSaveInAddressBook()): ?>
123123
checked="checked"
124-
<?php elseif ($block->getIsShipping() && !$block->getDontSaveInAddressBook() && !$block->getAddressId()): ?>
124+
<?php elseif ($block->getIsShipping()
125+
&& !$block->getDontSaveInAddressBook()
126+
&& !$block->getAddressId()): ?>
125127
checked="checked"
126128
<?php endif; ?>
127129
class="admin__control-checkbox"/>
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
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\Sales\Controller\Adminhtml\Order\Create;
9+
10+
use Magento\Backend\Model\Session\Quote;
11+
use Magento\Customer\Api\AccountManagementInterface;
12+
use Magento\Customer\Api\Data\CustomerInterface;
13+
use Magento\Customer\Api\Data\CustomerInterfaceFactory;
14+
use Magento\Framework\App\Request\Http;
15+
use Magento\Framework\Registry;
16+
use Magento\Sales\Api\OrderRepositoryInterface;
17+
use Magento\Sales\Model\Order;
18+
use Magento\Sales\Model\OrderFactory;
19+
use Magento\Store\Model\StoreManagerInterface;
20+
use Magento\TestFramework\Helper\Xpath;
21+
use Magento\TestFramework\TestCase\AbstractBackendController;
22+
use Magento\Sales\Api\Data\OrderInterface;
23+
use Magento\Customer\Api\CustomerRepositoryInterface;
24+
use Magento\Framework\Exception\NoSuchEntityException;
25+
26+
/**
27+
* Test load block for order create controller.
28+
*
29+
* @see \Magento\Sales\Controller\Adminhtml\Order\Create\Index
30+
*
31+
* @magentoAppArea adminhtml
32+
* @magentoDbIsolation enabled
33+
*/
34+
class ReorderTest extends AbstractBackendController
35+
{
36+
/**
37+
* @var OrderRepositoryInterface
38+
*/
39+
private $orderRepository;
40+
41+
/**
42+
* @var CustomerInterfaceFactory
43+
*/
44+
private $customerFactory;
45+
46+
/**
47+
* @var AccountManagementInterface
48+
*/
49+
private $accountManagement;
50+
51+
/**
52+
* @var OrderFactory
53+
*/
54+
private $orderFactory;
55+
56+
/**
57+
* @var CustomerRepositoryInterface
58+
*/
59+
private $customerRepository;
60+
61+
/**
62+
* @var array
63+
*/
64+
private $customerIds = [];
65+
66+
/**
67+
* @inheritdoc
68+
*/
69+
protected function setUp(): void
70+
{
71+
parent::setUp();
72+
$this->orderRepository = $this->_objectManager->get(OrderRepositoryInterface::class);
73+
$this->customerFactory = $this->_objectManager->get(CustomerInterfaceFactory::class);
74+
$this->accountManagement = $this->_objectManager->get(AccountManagementInterface::class);
75+
$this->orderFactory = $this->_objectManager->get(OrderFactory::class);
76+
$this->customerRepository = $this->_objectManager->get(CustomerRepositoryInterface::class);
77+
}
78+
79+
/**
80+
* @inheritdoc
81+
*/
82+
protected function tearDown(): void
83+
{
84+
parent::tearDown();
85+
foreach ($this->customerIds as $customerId) {
86+
try {
87+
$this->customerRepository->deleteById($customerId);
88+
} catch (NoSuchEntityException $e) {
89+
//customer already deleted
90+
}
91+
}
92+
}
93+
94+
/**
95+
* Test load billing address by reorder for delegating customer
96+
*
97+
* @magentoDataFixture Magento/Customer/_files/attribute_user_defined_address.php
98+
* @magentoDataFixture Magento/Sales/_files/order.php
99+
*
100+
* @return void
101+
*/
102+
public function testLoadBillingAddressAfterReorderWithDelegatingCustomer(): void
103+
{
104+
$orderId = $this->getOrderWithDelegatingCustomer()->getId();
105+
$this->getRequest()->setMethod(Http::METHOD_GET);
106+
$this->getRequest()->setParam('order_id', $orderId);
107+
$this->dispatch('backend/sales/order_create/loadBlock/block/billing_address');
108+
$html = $this->getResponse()->getBody();
109+
$this->assertEquals(
110+
0,
111+
Xpath::getElementsCountForXpath(
112+
'//*[@id="order-billing_address_save_in_address_book" and contains(@checked, "checked")]',
113+
$html
114+
),
115+
'Billing address checked "Save in address book"'
116+
);
117+
}
118+
119+
/**
120+
* Get Order with delegating customer
121+
*
122+
* @return OrderInterface
123+
*/
124+
private function getOrderWithDelegatingCustomer(): OrderInterface
125+
{
126+
$orderAutoincrementId = '100000001';
127+
/** @var Order $orderModel */
128+
$orderModel = $this->orderFactory->create();
129+
$orderModel->loadByIncrementId($orderAutoincrementId);
130+
//Saving new customer with prepared data from order.
131+
/** @var CustomerInterface $customer */
132+
$customer = $this->customerFactory->create();
133+
$customer->setWebsiteId(1)
134+
->setEmail('customer_order_delegate@example.com')
135+
->setGroupId(1)
136+
->setStoreId(1)
137+
->setPrefix('Mr.')
138+
->setFirstname('John')
139+
->setMiddlename('A')
140+
->setLastname('Smith')
141+
->setSuffix('Esq.')
142+
->setTaxvat('12')
143+
->setGender(0);
144+
$createdCustomer = $this->accountManagement->createAccount(
145+
$customer,
146+
'12345abcD'
147+
);
148+
$this->customerIds[] = $createdCustomer->getId();
149+
$orderModel->setCustomerId($createdCustomer->getId());
150+
151+
return $this->orderRepository->save($orderModel);
152+
}
153+
}

0 commit comments

Comments
 (0)