Skip to content

Commit ddebed6

Browse files
authored
Merge pull request #3537 from magento-performance/MC-5683
[performance] MC-5683: Implement handling of large number of addresses on admin order creation page
2 parents 619f2db + 933d656 commit ddebed6

File tree

7 files changed

+220
-12
lines changed

7 files changed

+220
-12
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
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\ViewModel\Customer;
9+
10+
use Magento\Framework\View\Element\Block\ArgumentInterface;
11+
12+
/**
13+
* Customer address formatter
14+
*/
15+
class AddressFormatter implements ArgumentInterface
16+
{
17+
/**
18+
* Customer form factory
19+
*
20+
* @var \Magento\Customer\Model\Metadata\FormFactory
21+
*/
22+
private $customerFormFactory;
23+
24+
/**
25+
* Address format helper
26+
*
27+
* @var \Magento\Customer\Helper\Address
28+
*/
29+
private $addressFormatHelper;
30+
31+
/**
32+
* Directory helper
33+
*
34+
* @var \Magento\Directory\Helper\Data
35+
*/
36+
private $directoryHelper;
37+
38+
/**
39+
* Session quote
40+
*
41+
* @var \Magento\Backend\Model\Session\Quote
42+
*/
43+
private $session;
44+
45+
/**
46+
* Json encoder
47+
*
48+
* @var \Magento\Framework\Serialize\Serializer\Json
49+
*/
50+
private $jsonEncoder;
51+
52+
/**
53+
* Customer address
54+
*
55+
* @param \Magento\Customer\Model\Metadata\FormFactory $customerFormFactory
56+
* @param \Magento\Customer\Helper\Address $addressFormatHelper
57+
* @param \Magento\Directory\Helper\Data $directoryHelper
58+
* @param \Magento\Backend\Model\Session\Quote $session
59+
* @param \Magento\Framework\Serialize\Serializer\Json $jsonEncoder
60+
*/
61+
public function __construct(
62+
\Magento\Customer\Model\Metadata\FormFactory $customerFormFactory,
63+
\Magento\Customer\Helper\Address $addressFormatHelper,
64+
\Magento\Directory\Helper\Data $directoryHelper,
65+
\Magento\Backend\Model\Session\Quote $session,
66+
\Magento\Framework\Serialize\Serializer\Json $jsonEncoder
67+
) {
68+
$this->customerFormFactory = $customerFormFactory;
69+
$this->addressFormatHelper = $addressFormatHelper;
70+
$this->directoryHelper = $directoryHelper;
71+
$this->session = $session;
72+
$this->jsonEncoder = $jsonEncoder;
73+
}
74+
75+
/**
76+
* Return customer address array as JSON
77+
*
78+
* @param array $addressArray
79+
*
80+
* @return string
81+
*/
82+
public function getAddressesJson(array $addressArray): string
83+
{
84+
$data = $this->getEmptyAddressForm();
85+
foreach ($addressArray as $addressId => $address) {
86+
$addressForm = $this->customerFormFactory->create(
87+
'customer_address',
88+
'adminhtml_customer_address',
89+
$address
90+
);
91+
$data[$addressId] = $addressForm->outputData(
92+
\Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_JSON
93+
);
94+
}
95+
96+
return $this->jsonEncoder->serialize($data);
97+
}
98+
99+
/**
100+
* Represent customer address in 'online' format.
101+
*
102+
* @param array $address
103+
* @return string
104+
*/
105+
public function getAddressAsString(array $address): string
106+
{
107+
$formatTypeRenderer = $this->addressFormatHelper->getFormatTypeRenderer('oneline');
108+
$result = '';
109+
if ($formatTypeRenderer) {
110+
$result = $formatTypeRenderer->renderArray($address);
111+
}
112+
113+
return $result;
114+
}
115+
116+
/**
117+
* Return empty address address form
118+
*
119+
* @return array
120+
*/
121+
private function getEmptyAddressForm(): array
122+
{
123+
$defaultCountryId = $this->directoryHelper->getDefaultCountry($this->session->getStore());
124+
$emptyAddressForm = $this->customerFormFactory->create(
125+
'customer_address',
126+
'adminhtml_customer_address',
127+
[\Magento\Customer\Api\Data\AddressInterface::COUNTRY_ID => $defaultCountryId]
128+
);
129+
130+
return [0 => $emptyAddressForm->outputData(\Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_JSON)];
131+
}
132+
}

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,18 @@
4545
<block class="Magento\Sales\Block\Adminhtml\Order\Create\Sidebar\Pviewed" template="Magento_Sales::order/create/sidebar/items.phtml" name="pviewed"/>
4646
</block>
4747
<block class="Magento\Sales\Block\Adminhtml\Order\Create\Form\Account" template="Magento_Sales::order/create/form/account.phtml" name="form_account"/>
48-
<block class="Magento\Sales\Block\Adminhtml\Order\Create\Shipping\Address" template="Magento_Sales::order/create/form/address.phtml" name="shipping_address"/>
49-
<block class="Magento\Sales\Block\Adminhtml\Order\Create\Billing\Address" template="Magento_Sales::order/create/form/address.phtml" name="billing_address"/>
48+
<block class="Magento\Sales\Block\Adminhtml\Order\Create\Shipping\Address" template="Magento_Sales::order/create/form/address.phtml" name="shipping_address">
49+
<arguments>
50+
<argument name="customerAddressFormatter" xsi:type="object">Magento\Sales\ViewModel\Customer\AddressFormatter</argument>
51+
<argument name="customerAddressCollection" xsi:type="object">Magento\Customer\Model\ResourceModel\Address\Collection</argument>
52+
</arguments>
53+
</block>
54+
<block class="Magento\Sales\Block\Adminhtml\Order\Create\Billing\Address" template="Magento_Sales::order/create/form/address.phtml" name="billing_address">
55+
<arguments>
56+
<argument name="customerAddressFormatter" xsi:type="object">Magento\Sales\ViewModel\Customer\AddressFormatter</argument>
57+
<argument name="customerAddressCollection" xsi:type="object">Magento\Customer\Model\ResourceModel\Address\Collection</argument>
58+
</arguments>
59+
</block>
5060
<block class="Magento\Sales\Block\Adminhtml\Order\Create\Shipping\Method" template="Magento_Sales::order/create/abstract.phtml" name="shipping_method">
5161
<block class="Magento\Sales\Block\Adminhtml\Order\Create\Shipping\Method\Form" template="Magento_Sales::order/create/shipping/method/form.phtml" name="order_create_shipping_form" as="form"/>
5262
</block>

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@
88
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
99
<body>
1010
<referenceContainer name="content">
11-
<block class="Magento\Sales\Block\Adminhtml\Order\Create\Billing\Address" template="Magento_Sales::order/create/form/address.phtml" name="billing_address"/>
11+
<block class="Magento\Sales\Block\Adminhtml\Order\Create\Billing\Address" template="Magento_Sales::order/create/form/address.phtml" name="billing_address">
12+
<arguments>
13+
<argument name="customerAddressFormatter" xsi:type="object">Magento\Sales\ViewModel\Customer\AddressFormatter</argument>
14+
<argument name="customerAddressCollection" xsi:type="object">Magento\Customer\Model\ResourceModel\Address\Collection</argument>
15+
</arguments>
16+
</block>
1217
</referenceContainer>
1318
</body>
1419
</page>

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,18 @@
2020
<block class="Magento\Sales\Block\Adminhtml\Order\Create\Sidebar\Pviewed" template="Magento_Sales::order/create/sidebar/items.phtml" name="pviewed"/>
2121
</block>
2222
<block class="Magento\Sales\Block\Adminhtml\Order\Create\Form\Account" template="Magento_Sales::order/create/form/account.phtml" name="form_account"/>
23-
<block class="Magento\Sales\Block\Adminhtml\Order\Create\Shipping\Address" template="Magento_Sales::order/create/form/address.phtml" name="shipping_address"/>
24-
<block class="Magento\Sales\Block\Adminhtml\Order\Create\Billing\Address" template="Magento_Sales::order/create/form/address.phtml" name="billing_address"/>
23+
<block class="Magento\Sales\Block\Adminhtml\Order\Create\Shipping\Address" template="Magento_Sales::order/create/form/address.phtml" name="shipping_address">
24+
<arguments>
25+
<argument name="customerAddressFormatter" xsi:type="object">Magento\Sales\ViewModel\Customer\AddressFormatter</argument>
26+
<argument name="customerAddressCollection" xsi:type="object">Magento\Customer\Model\ResourceModel\Address\Collection</argument>
27+
</arguments>
28+
</block>
29+
<block class="Magento\Sales\Block\Adminhtml\Order\Create\Billing\Address" template="Magento_Sales::order/create/form/address.phtml" name="billing_address">
30+
<arguments>
31+
<argument name="customerAddressFormatter" xsi:type="object">Magento\Sales\ViewModel\Customer\AddressFormatter</argument>
32+
<argument name="customerAddressCollection" xsi:type="object">Magento\Customer\Model\ResourceModel\Address\Collection</argument>
33+
</arguments>
34+
</block>
2535
<block class="Magento\Sales\Block\Adminhtml\Order\Create\Shipping\Method" template="Magento_Sales::order/create/abstract.phtml" name="shipping_method">
2636
<block class="Magento\Sales\Block\Adminhtml\Order\Create\Shipping\Method\Form" template="Magento_Sales::order/create/shipping/method/form.phtml" name="order.create.shipping.method.form" as="form"/>
2737
</block>

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@
88
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
99
<body>
1010
<referenceContainer name="content">
11-
<block class="Magento\Sales\Block\Adminhtml\Order\Create\Shipping\Address" template="Magento_Sales::order/create/form/address.phtml" name="shipping_address"/>
11+
<block class="Magento\Sales\Block\Adminhtml\Order\Create\Shipping\Address" template="Magento_Sales::order/create/form/address.phtml" name="shipping_address">
12+
<arguments>
13+
<argument name="customerAddressFormatter" xsi:type="object">Magento\Sales\ViewModel\Customer\AddressFormatter</argument>
14+
<argument name="customerAddressCollection" xsi:type="object">Magento\Customer\Model\ResourceModel\Address\Collection</argument>
15+
</arguments>
16+
</block>
1217
</referenceContainer>
1318
</body>
1419
</page>

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

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,21 @@
66

77
// @codingStandardsIgnoreFile
88

9+
/**
10+
* @var \Magento\Customer\Model\ResourceModel\Address\Collection $addressCollection
11+
*/
12+
$addressCollection = $block->getData('customerAddressCollection');
13+
14+
$addressArray = [];
15+
if ($block->getCustomerId()) {
16+
$addressArray = $addressCollection->setCustomerFilter([$block->getCustomerId()])->toArray();
17+
}
18+
19+
/**
20+
* @var \Magento\Sales\ViewModel\Customer\AddressFormatter $customerAddressFormatter
21+
*/
22+
$customerAddressFormatter = $block->getData('customerAddressFormatter');
23+
924
/**
1025
* @var \Magento\Sales\Block\Adminhtml\Order\Create\Billing\Address|\Magento\Sales\Block\Adminhtml\Order\Create\Shipping\Address $block
1126
*/
@@ -17,7 +32,7 @@ if ($block->getIsShipping()):
1732
require(["Magento_Sales/order/create/form"], function(){
1833

1934
order.shippingAddressContainer = '<?= /* @escapeNotVerified */ $_fieldsContainerId ?>';
20-
order.setAddresses(<?= /* @escapeNotVerified */ $block->getAddressCollectionJson() ?>);
35+
order.setAddresses(<?= /* @escapeNotVerified */ $customerAddressFormatter->getAddressesJson($addressArray) ?>);
2136

2237
});
2338
</script>
@@ -59,13 +74,11 @@ endif; ?>
5974
onchange="order.selectAddress(this, '<?= /* @escapeNotVerified */ $_fieldsContainerId ?>')"
6075
class="admin__control-select">
6176
<option value=""><?= /* @escapeNotVerified */ __('Add New Address') ?></option>
62-
<?php foreach ($block->getAddressCollection() as $_address): ?>
63-
<?php //if($block->getAddressAsString($_address)!=$block->getAddressAsString($block->getAddress())): ?>
77+
<?php foreach ($addressArray as $addressId => $address): ?>
6478
<option
65-
value="<?= /* @escapeNotVerified */ $_address->getId() ?>"<?php if ($_address->getId() == $block->getAddressId()): ?> selected="selected"<?php endif; ?>>
66-
<?= /* @escapeNotVerified */ $block->getAddressAsString($_address) ?>
79+
value="<?= /* @escapeNotVerified */ $addressId ?>"<?php if ($addressId == $block->getAddressId()): ?> selected="selected"<?php endif; ?>>
80+
<?= /* @escapeNotVerified */ $block->escapeHtml($customerAddressFormatter->getAddressAsString($address)) ?>
6781
</option>
68-
<?php //endif; ?>
6982
<?php endforeach; ?>
7083
</select>
7184
</div>

setup/performance-toolkit/benchmark.jmx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25118,6 +25118,39 @@ catch (java.lang.Exception e) {
2511825118
</ResponseAssertion>
2511925119
<hashTree/>
2512025120
</hashTree>
25121+
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Filled Order Page" enabled="true">
25122+
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true">
25123+
<collectionProp name="Arguments.arguments"/>
25124+
</elementProp>
25125+
<stringProp name="HTTPSampler.domain"/>
25126+
<stringProp name="HTTPSampler.port"/>
25127+
<stringProp name="HTTPSampler.connect_timeout">60000</stringProp>
25128+
<stringProp name="HTTPSampler.response_timeout">200000</stringProp>
25129+
<stringProp name="HTTPSampler.protocol">${request_protocol}</stringProp>
25130+
<stringProp name="HTTPSampler.contentEncoding"/>
25131+
<stringProp name="HTTPSampler.path">${base_path}${admin_path}/sales/order_create/index/</stringProp>
25132+
<stringProp name="HTTPSampler.method">GET</stringProp>
25133+
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
25134+
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
25135+
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
25136+
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
25137+
<boolProp name="HTTPSampler.monitor">false</boolProp>
25138+
<stringProp name="HTTPSampler.embedded_url_re"/>
25139+
<stringProp name="TestPlan.comments">Detected the start of a redirect chain</stringProp>
25140+
</HTTPSamplerProxy>
25141+
<hashTree>
25142+
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Assert Filled Order Page" enabled="true">
25143+
<collectionProp name="Asserion.test_strings">
25144+
<stringProp name="-37823069">Select from existing customer addresses</stringProp>
25145+
<stringProp name="-13185722">Submit Order</stringProp>
25146+
<stringProp name="-209419315">Items Ordered</stringProp>
25147+
</collectionProp>
25148+
<stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
25149+
<boolProp name="Assertion.assume_success">false</boolProp>
25150+
<intProp name="Assertion.test_type">2</intProp>
25151+
</ResponseAssertion>
25152+
<hashTree/>
25153+
</hashTree>
2512125154
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Save Order" enabled="true">
2512225155
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" enabled="true">
2512325156
<collectionProp name="Arguments.arguments">

0 commit comments

Comments
 (0)